diff --git a/.woodpecker/build-package.yaml b/.woodpecker/build-package.yaml deleted file mode 100644 index d06a267cd..000000000 --- a/.woodpecker/build-package.yaml +++ /dev/null @@ -1,36 +0,0 @@ -when: - - event: push - branch: ${CI_REPO_DEFAULT_BRANCH} - - event: manual - branch: ${CI_REPO_DEFAULT_BRANCH} - -depends_on: - - test - - test-e2e - -labels: - platform: linux/amd64 - memory: 'high' - -steps: - build: - image: docker.io/node:20-alpine - commands: - - apk add --no-cache zip git - - yarn --frozen-lockfile - - yarn build - - if [ "${CI_PIPELINE_EVENT}" = "push" ] || [ "${CI_PIPELINE_EVENT}" = "manual" ]; then zip -9qr ${CI_REPO_DEFAULT_BRANCH}.zip dist/; fi - - upload-artifacts: - image: docker.io/woodpeckercommunity/plugin-gitea-package:0.5.0 - settings: - user: - from_secret: pleroma-ci-user - password: - from_secret: pleroma-ci-password - update: true - owner: 'pleroma' - package_name: 'pleroma-fe-builds' - package_version: ${CI_REPO_DEFAULT_BRANCH} - file_source: ./${CI_REPO_DEFAULT_BRANCH}.zip - file_name: latest.zip diff --git a/.woodpecker/build.yaml b/.woodpecker/build.yaml index d6bd36f3e..af0bb98e3 100644 --- a/.woodpecker/build.yaml +++ b/.woodpecker/build.yaml @@ -6,12 +6,38 @@ when: - event: manual branch: ${CI_REPO_DEFAULT_BRANCH} +depends_on: + - test + - test-e2e + labels: platform: linux/amd64 + memory: 'high' steps: build: image: docker.io/node:20-alpine commands: + - apk add --no-cache zip git - yarn --frozen-lockfile - yarn build + - if [ "${CI_PIPELINE_EVENT}" = "push" ] || [ "${CI_PIPELINE_EVENT}" = "manual" ]; then zip -9qr ${CI_REPO_DEFAULT_BRANCH}.zip dist/; fi + + upload-artifacts: + image: docker.io/woodpeckercommunity/plugin-gitea-package:0.5.0 + when: + - event: push + branch: ${CI_REPO_DEFAULT_BRANCH} + - event: manual + branch: ${CI_REPO_DEFAULT_BRANCH} + settings: + user: + from_secret: pleroma-ci-user + password: + from_secret: pleroma-ci-password + update: true + owner: 'pleroma' + package_name: 'pleroma-fe-builds' + package_version: ${CI_REPO_DEFAULT_BRANCH} + file_source: ./${CI_REPO_DEFAULT_BRANCH}.zip + file_name: latest.zip diff --git a/.woodpecker/code-analisys.yaml b/.woodpecker/code-analisys.yaml deleted file mode 100644 index 11ee853ee..000000000 --- a/.woodpecker/code-analisys.yaml +++ /dev/null @@ -1,45 +0,0 @@ -when: - - event: push - branch: ${CI_REPO_DEFAULT_BRANCH} - - event: manual - branch: ${CI_REPO_DEFAULT_BRANCH} - -labels: - platform: linux/amd64 - memory: 'high' - -depends_on: - - build - - test - - test-e2e - -clone: - - name: git - image: woodpeckerci/plugin-git - settings: - depth: 0 - partial: false - -variables: - script_file_entrypoint: &script_file_entrypoint - - /bin/sh - - -c - - 'printf "%s" "$CI_SCRIPT" | base64 -d > /tmp/ci-script.sh && /bin/sh -xe /tmp/ci-script.sh' - -steps: - generate-coverage: - image: mcr.microsoft.com/playwright:v1.61.0-jammy - environment: - FF_NETWORK_PER_BUILD: "true" - PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD: "1" - entrypoint: *script_file_entrypoint - commands: - - yarn --frozen-lockfile - - yarn unit-ci-coverage - - code-analysis: - image: sonarsource/sonar-scanner-cli:11 - environment: - SONAR_TOKEN: - from_secret: sonarqube-token - entrypoint: sonar-scanner diff --git a/.woodpecker/test-e2e.yaml b/.woodpecker/test-e2e.yaml index 8f7e407f8..2a7d1511d 100644 --- a/.woodpecker/test-e2e.yaml +++ b/.woodpecker/test-e2e.yaml @@ -10,10 +10,6 @@ labels: platform: linux/amd64 memory: 'high' -depends_on: - - build - - test - variables: artifacts_uploader_settings: &artifacts_uploader_settings user: diff --git a/.woodpecker/test.yaml b/.woodpecker/test.yaml index c3f2c3793..9c3c24a53 100644 --- a/.woodpecker/test.yaml +++ b/.woodpecker/test.yaml @@ -10,9 +10,6 @@ labels: platform: linux/amd64 memory: 'high' -depends_on: - - build - variables: artifacts_uploader_settings: &artifacts_uploader_settings user: @@ -48,6 +45,20 @@ steps: exit 1 fi + code-analysis: + image: sonarsource/sonar-scanner-cli:11 + when: + - event: push + branch: ${CI_REPO_DEFAULT_BRANCH} + - event: manual + branch: ${CI_REPO_DEFAULT_BRANCH} + environment: + SONAR_TOKEN: + from_secret: sonarqube-token + entrypoint: *script_file_entrypoint + commands: + - sonar-scanner + upload-artifacts: image: docker.io/woodpeckercommunity/plugin-gitea-package:0.5.0 when: diff --git a/README.md b/README.md index a1dabba35..16d32dcd2 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,12 @@ -# Pleroma-FE +# Pleroma-FE > Highly-customizable frontend designed for Pleroma. ![screenshot](./image-1.png) -[![Pipeline Status](https://ci.pleroma.com/api/badges/2/status.svg)](https://ci.pleroma.com/repos/2) [![Coverage](https://sonarqube.pleroma.dev/api/project_badges/measure?project=Pleroma-FE&metric=coverage&token=sqb_f8a5ec836caede0e2c6c62a9bfe66e62a89e2b01)](https://sonarqube.pleroma.dev/dashboard?id=Pleroma-FE) [![Maintainability Rating](https://sonarqube.pleroma.dev/api/project_badges/measure?project=Pleroma-FE&metric=software_quality_maintainability_rating&token=sqb_f8a5ec836caede0e2c6c62a9bfe66e62a89e2b01)](https://sonarqube.pleroma.dev/dashboard?id=Pleroma-FE) [![Reliability Rating](https://sonarqube.pleroma.dev/api/project_badges/measure?project=Pleroma-FE&metric=software_quality_reliability_rating&token=sqb_f8a5ec836caede0e2c6c62a9bfe66e62a89e2b01)](https://sonarqube.pleroma.dev/dashboard?id=Pleroma-FE) [![Security Rating](https://sonarqube.pleroma.dev/api/project_badges/measure?project=Pleroma-FE&metric=software_quality_security_rating&token=sqb_f8a5ec836caede0e2c6c62a9bfe66e62a89e2b01)](https://sonarqube.pleroma.dev/dashboard?id=Pleroma-FE) Translation status - # For Translators -To translate Pleroma-FE, use our weblate server: https://translate.pleroma.social/. If you need to add your language it should be added as a json file in [src/i18n/](https://git.pleroma.social/pleroma/pleroma-fe/src/src/i18n/) folder and added in a list within [src/i18n/languages.js](https://git.pleroma.social/pleroma/pleroma-fe/src/src/i18n/languages.js). +To translate Pleroma-FE, use our weblate server: https://translate.pleroma.social/. If you need to add your language it should be added as a json file in [src/i18n/](https://git.pleroma.social/pleroma/pleroma-fe/src/src/i18n/) folder and added in a list within [src/i18n/languages.js](https://git.pleroma.social/pleroma/pleroma-fe/src/src/i18n/languages.js). Pleroma-FE will set your language by your browser locale, but you can change language in settings. @@ -34,14 +32,9 @@ yarn unit # For Contributors: -You can make local build proxy requests to specific instance with an environment variable `VITE_PROXY_TARGET`, generally it is a good idea to also set port for that specific proxy, if you intend on testing multiple instances, i.e.: - -```bash -yarn && PORT=8080 VITE_PROXY_TARGET=https://coolinstance.tld yarn dev -``` - You can create file `/config/local.json` (see [example](https://git.pleroma.social/pleroma/pleroma-fe/src/config/local.example.json)) to enable some convenience dev options: +* `target`: makes local dev server redirect to some existing instance's BE instead of local BE, useful for testing things in near-production environment and searching for real-life use-cases. * `staticConfigPreference`: makes FE's `/static/config.json` take preference of BE-served `/api/pleroma/frontend_configurations`. Only works in dev mode. FE Build process also leaves current commit hash in global variable `___pleromafe_commit_hash` so that you can easily see which pleroma-fe commit instance is running, also helps pinpointing which commit was used when FE was bundled into BE. diff --git a/build/commit_hash.js b/build/commit_hash.js index 2b13afb93..8225817ee 100644 --- a/build/commit_hash.js +++ b/build/commit_hash.js @@ -7,9 +7,7 @@ export const getCommitHash = () => { } else { try { return childProcess - .execSync( - 'PATH=/usr/bin:/bin:/usr/local/bin:/sbin:/usr/sbin git rev-parse --short HEAD', - ) + .execSync('git rev-parse --short HEAD') .toString() .trim() } catch (e) { diff --git a/changelog.d/avatar_upload.fix b/changelog.d/avatar_upload.fix deleted file mode 100644 index b5dd9ee56..000000000 --- a/changelog.d/avatar_upload.fix +++ /dev/null @@ -1 +0,0 @@ -fix image cropper error preventing avatar upload diff --git a/changelog.d/third_column.fix b/changelog.d/third_column.fix deleted file mode 100644 index 191e914d5..000000000 --- a/changelog.d/third_column.fix +++ /dev/null @@ -1 +0,0 @@ -Fixed layout selector (third column/reverse) not working immideately upon change diff --git a/package.json b/package.json index 50138e6a2..f8bacaf15 100644 --- a/package.json +++ b/package.json @@ -8,8 +8,7 @@ "dev": "node build/update-emoji.js && vite dev", "build": "node build/update-emoji.js && vite build", "unit": "node build/update-emoji.js && vitest --run --coverage", - "unit-ci": "node build/update-emoji.js && vitest --run --browser.headless", - "unit-ci-coverage": "node build/update-emoji.js && vitest --run --coverage --browser.headless", + "unit-ci": "node build/update-emoji.js && vitest --run --coverage --browser.headless", "unit:watch": "node build/update-emoji.js && vitest --coverage", "e2e:pw": "playwright test --config test/e2e-playwright/playwright.config.mjs", "e2e": "sh ./tools/e2e/run.sh", diff --git a/src/App.js b/src/App.js index d7a63bd8a..4ce6f1abc 100644 --- a/src/App.js +++ b/src/App.js @@ -74,8 +74,6 @@ export default { }, data: () => ({ mobileActivePanel: 'timeline', - updateMobileState: null, - updateScrollState: null, }), provide() { return { @@ -213,32 +211,31 @@ export default { hideShoutbox() { return this.isChats || useMergedConfigStore().mergedConfig.hideShoutbox }, - thirdColumnMode() { - return this.mergedConfig.thirdColumnMode - }, - reverseSetting() { - return this.mergedConfig.sidebarRight - }, reverseLayout() { + const { thirdColumnMode, sidebarRight: reverseSetting } = + useMergedConfigStore().mergedConfig if (this.layoutType !== 'wide') { - return this.reverseSetting + return reverseSetting } else { - return this.thirdColumnMode === 'notifications' - ? this.reverseSetting - : !this.reverseSetting + return thirdColumnMode === 'notifications' + ? reverseSetting + : !reverseSetting } }, noSticky() { - return this.mergedConfig.disableStickyHeaders + return useMergedConfigStore().mergedConfig.disableStickyHeaders }, showScrollbars() { - return this.mergedConfig.showScrollbars + return useMergedConfigStore().mergedConfig.showScrollbars }, scrollParent() { return window /* this.$refs.appContentRef */ }, showInstanceSpecificPanel() { - return this.instanceSpecificPanelPresent && !this.mergedConfig.hideISP + return ( + this.instanceSpecificPanelPresent && + !useMergedConfigStore().mergedConfig.hideISP + ) }, ...mapState(useMergedConfigStore, ['mergedConfig']), ...mapState(useInterfaceStore, [ diff --git a/src/components/image_cropper/image_cropper.js b/src/components/image_cropper/image_cropper.js index 599c95caf..b85ef6626 100644 --- a/src/components/image_cropper/image_cropper.js +++ b/src/components/image_cropper/image_cropper.js @@ -70,9 +70,6 @@ const ImageCropper = { ) }, onCropperSelectionChange(event) { - if (!this.$refs.cropperCanvas) { - return // Cropper sends even before component is fully initialized - } const cropperCanvas = this.$refs.cropperCanvas const cropperCanvasRect = cropperCanvas.getBoundingClientRect() const selection = event.detail diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index feb59857e..393aef639 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -134,11 +134,12 @@ const Notifications = { return this.minimalMode || layoutType === 'mobile' }, teleportTarget() { + const { layoutType } = useInterfaceStore() const map = { wide: '#notifs-column', mobile: '#mobile-notifications', } - return map[this.layoutType] || '#notifs-sidebar' + return map[layoutType] || '#notifs-sidebar' }, popoversZLayer() { const { layoutType } = useInterfaceStore() @@ -161,7 +162,6 @@ const Notifications = { }, ...mapState(useAnnouncementsStore, ['unreadAnnouncementCount']), ...mapState(useChatsStore, ['unreadChatsCount']), - ...mapState(useInterfaceStore, ['layoutType']), }, mounted() { this.scrollerRef = this.$refs.root.closest('.column.-scrollable') diff --git a/src/components/poll/poll_form.js b/src/components/poll/poll_form.js index a9c915127..5d0334a63 100644 --- a/src/components/poll/poll_form.js +++ b/src/components/poll/poll_form.js @@ -25,10 +25,6 @@ export default { }, emits: ['update:modelValue'], computed: { - // Model value - options() { - return pollFallback(this.modelValue, 'options') - }, pollType: { get() { return pollFallback(this.modelValue, 'pollType') @@ -40,6 +36,14 @@ export default { }) }, }, + options: { + get() { + return pollFallback(this.modelValue, 'options') + }, + set(newVal) { + this.$emit('update:modelValue', { ...this.modelValue, options: newVal }) + }, + }, expiryAmount: { get() { return pollFallback(this.modelValue, 'expiryAmount') @@ -62,8 +66,6 @@ export default { }) }, }, - - // Configuration pollLimits() { return useInstanceStore().limits.pollLimits }, @@ -114,34 +116,19 @@ export default { }, addOption() { if (this.options.length < this.maxOptions) { - this.$emit('update:modelValue', { - ...this.modelValue, - options: [...this.options, ''], - }) - + this.options = [...this.options, ''] return true } return false }, deleteOption(index) { if (this.options.length > 2) { - const options = [...this.options] - options.splice(index, 1) - - this.$emit('update:modelValue', { - ...this.modelValue, - options, - }) + this.options.splice(index, 1) + this.options = this.options } }, updateOption(index, value) { - const options = [...this.options] - options[index] = value - - this.$emit('update:modelValue', { - ...this.modelValue, - options, - }) + this.options = this.options }, convertExpiryToUnit(unit, amount) { // Note: we want seconds and not milliseconds diff --git a/src/components/poll/poll_form.vue b/src/components/poll/poll_form.vue index b5db1314a..cb8a6f91f 100644 --- a/src/components/poll/poll_form.vue +++ b/src/components/poll/poll_form.vue @@ -11,15 +11,14 @@