diff --git a/changelog.d/remove-opn-dependency.skip b/changelog.d/remove-opn-dependency.skip deleted file mode 100644 index e69de29bb..000000000 diff --git a/package.json b/package.json index cb5378a86..481f65e66 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "lint-fix": "eslint --fix src test/unit/specs test/e2e/specs" }, "dependencies": { - "@babel/runtime": "7.26.10", + "@babel/runtime": "7.26.9", "@chenfengyuan/vue-qrcode": "2.0.0", "@fortawesome/fontawesome-svg-core": "6.7.2", "@fortawesome/free-regular-svg-icons": "6.7.2", @@ -39,14 +39,13 @@ "js-cookie": "3.0.5", "localforage": "1.10.0", "parse-link-header": "2.0.0", - "phoenix": "1.7.20", + "phoenix": "1.7.19", "pinia": "^2.0.33", "punycode.js": "2.3.1", "qrcode": "1.5.4", "querystring-es3": "0.2.1", "url": "0.11.4", "utf8": "3.0.0", - "uuid": "8.3.2", "vue": "3.5.13", "vue-i18n": "10", "vue-router": "4.5.0", @@ -54,9 +53,9 @@ "vuex": "4.1.0" }, "devDependencies": { - "@babel/core": "7.26.10", - "@babel/eslint-parser": "7.26.10", - "@babel/plugin-transform-runtime": "7.26.10", + "@babel/core": "7.26.9", + "@babel/eslint-parser": "7.26.8", + "@babel/plugin-transform-runtime": "7.26.9", "@babel/preset-env": "7.26.9", "@babel/register": "7.25.9", "@ungap/event-target": "0.2.4", @@ -72,7 +71,7 @@ "babel-plugin-lodash": "3.3.4", "chai": "4.5.0", "chalk": "5.4.1", - "chromedriver": "134.0.3", + "chromedriver": "133.0.3", "connect-history-api-fallback": "2.0.0", "cross-spawn": "7.0.6", "custom-event-polyfill": "1.0.7", @@ -90,7 +89,8 @@ "iso-639-1": "3.1.5", "lodash": "4.17.21", "msw": "2.7.3", - "nightwatch": "3.12.0", + "nightwatch": "3.11.1", + "opn": "5.5.0", "ora": "0.4.1", "playwright": "1.49.1", "postcss": "8.5.3", @@ -100,7 +100,7 @@ "selenium-server": "3.141.59", "semver": "7.7.1", "serve-static": "1.16.2", - "shelljs": "0.9.1", + "shelljs": "0.8.5", "sinon": "15.2.0", "sinon-chai": "3.7.0", "stylelint": "14.16.1", diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js index 2085d24e3..10a0892f4 100644 --- a/src/components/mobile_nav/mobile_nav.js +++ b/src/components/mobile_nav/mobile_nav.js @@ -1,19 +1,14 @@ import SideDrawer from '../side_drawer/side_drawer.vue' import Notifications from '../notifications/notifications.vue' import ConfirmModal from '../confirm_modal/confirm_modal.vue' -import GestureService from '../../services/gesture_service/gesture_service' -import NavigationPins from 'src/components/navigation/navigation_pins.vue' - import { unseenNotificationsFromStore, countExtraNotifications } from '../../services/notification_utils/notification_utils' - +import GestureService from '../../services/gesture_service/gesture_service' +import NavigationPins from 'src/components/navigation/navigation_pins.vue' import { mapGetters } from 'vuex' import { mapState } from 'pinia' -import { useAnnouncementsStore } from 'src/stores/announcements' -import { useServerSideStorageStore } from 'src/stores/serverSideStorage' - import { library } from '@fortawesome/fontawesome-svg-core' import { faTimes, @@ -23,6 +18,7 @@ import { faMinus, faCheckDouble } from '@fortawesome/free-solid-svg-icons' +import { useAnnouncementsStore } from 'src/stores/announcements' library.add( faTimes, @@ -75,9 +71,10 @@ const MobileNav = { return this.$route.name === 'chat' }, ...mapState(useAnnouncementsStore, ['unreadAnnouncementCount']), - ...mapState(useServerSideStorageStore, { - pinnedItems: store => new Set(store.prefsStorage.collections.pinnedNavItems).has('chats') - }), + ...mapGetters(['unreadChatCount']), + chatsPinned () { + return new Set(this.$store.state.serverSideStorage.prefsStorage.collections.pinnedNavItems).has('chats') + }, shouldConfirmLogout () { return this.$store.getters.mergedConfig.modalOnLogout }, diff --git a/src/components/nav_panel/nav_panel.js b/src/components/nav_panel/nav_panel.js index 681aaf05b..9d569729f 100644 --- a/src/components/nav_panel/nav_panel.js +++ b/src/components/nav_panel/nav_panel.js @@ -7,9 +7,7 @@ import { filterNavigation } from 'src/components/navigation/filter.js' import NavigationEntry from 'src/components/navigation/navigation_entry.vue' import NavigationPins from 'src/components/navigation/navigation_pins.vue' import Checkbox from 'src/components/checkbox/checkbox.vue' - import { useAnnouncementsStore } from 'src/stores/announcements' -import { useServerSideStorageStore } from 'src/stores/serverSideStorage' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -78,19 +76,19 @@ const NavPanel = { this.editMode = !this.editMode }, toggleCollapse () { - useServerSideStorageStore().setPreference({ path: 'simple.collapseNav', value: !this.collapsed }) - useServerSideStorageStore().pushServerSideStorage() + this.$store.commit('setPreference', { path: 'simple.collapseNav', value: !this.collapsed }) + this.$store.dispatch('pushServerSideStorage') }, isPinned (item) { return this.pinnedItems.has(item) }, togglePin (item) { if (this.isPinned(item)) { - useServerSideStorageStore().removeCollectionPreference({ path: 'collections.pinnedNavItems', value: item }) + this.$store.commit('removeCollectionPreference', { path: 'collections.pinnedNavItems', value: item }) } else { - useServerSideStorageStore().addCollectionPreference({ path: 'collections.pinnedNavItems', value: item }) + this.$store.commit('addCollectionPreference', { path: 'collections.pinnedNavItems', value: item }) } - useServerSideStorageStore().pushServerSideStorage() + this.$store.dispatch('pushServerSideStorage') } }, computed: { @@ -98,16 +96,14 @@ const NavPanel = { unreadAnnouncementCount: 'unreadAnnouncementCount', supportsAnnouncements: store => store.supportsAnnouncements }), - ...mapPiniaState(useServerSideStorageStore, { - collapsed: store => store.prefsStorage.simple.collapseNav, - pinnedItems: store => new Set(store.prefsStorage.collections.pinnedNavItems) - }), ...mapState({ currentUser: state => state.users.currentUser, followRequestCount: state => state.api.followRequests.length, privateMode: state => state.instance.private, federating: state => state.instance.federating, pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable, + pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedNavItems), + collapsed: state => state.serverSideStorage.prefsStorage.simple.collapseNav, bookmarkFolders: state => state.instance.pleromaBookmarkFoldersAvailable }), timelinesItems () { diff --git a/src/components/navigation/navigation_entry.js b/src/components/navigation/navigation_entry.js index 11db1c9e3..dbef18fcd 100644 --- a/src/components/navigation/navigation_entry.js +++ b/src/components/navigation/navigation_entry.js @@ -3,10 +3,8 @@ import { routeTo } from 'src/components/navigation/navigation.js' import OptionalRouterLink from 'src/components/optional_router_link/optional_router_link.vue' import { library } from '@fortawesome/fontawesome-svg-core' import { faThumbtack } from '@fortawesome/free-solid-svg-icons' -import { mapStores, mapState as mapPiniaState } from 'pinia' - +import { mapStores } from 'pinia' import { useAnnouncementsStore } from 'src/stores/announcements' -import { useServerSideStorageStore } from 'src/stores/serverSideStorage' library.add(faThumbtack) @@ -21,11 +19,11 @@ const NavigationEntry = { }, togglePin (value) { if (this.isPinned(value)) { - useServerSideStorageStore().removeCollectionPreference({ path: 'collections.pinnedNavItems', value }) + this.$store.commit('removeCollectionPreference', { path: 'collections.pinnedNavItems', value }) } else { - useServerSideStorageStore().addCollectionPreference({ path: 'collections.pinnedNavItems', value }) + this.$store.commit('addCollectionPreference', { path: 'collections.pinnedNavItems', value }) } - useServerSideStorageStore().pushServerSideStorage() + this.$store.dispatch('pushServerSideStorage') } }, computed: { @@ -37,11 +35,9 @@ const NavigationEntry = { }, ...mapStores(useAnnouncementsStore), ...mapState({ - currentUser: state => state.users.currentUser - }), - ...mapPiniaState(useServerSideStorageStore, { - pinnedItems: store => new Set(store.prefsStorage.collections.pinnedNavItems) - }), + currentUser: state => state.users.currentUser, + pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedNavItems) + }) } } diff --git a/src/components/navigation/navigation_pins.js b/src/components/navigation/navigation_pins.js index 50acbbaf1..f9cdef71b 100644 --- a/src/components/navigation/navigation_pins.js +++ b/src/components/navigation/navigation_pins.js @@ -20,7 +20,6 @@ import { import { useListsStore } from 'src/stores/lists' import { useAnnouncementsStore } from 'src/stores/announcements' import { useBookmarkFoldersStore } from 'src/stores/bookmark_folders' -import { useServerSideStorageStore } from 'src/stores/serverSideStorage' library.add( faUsers, @@ -55,17 +54,15 @@ const NavPanel = { supportsAnnouncements: store => store.supportsAnnouncements }), ...mapPiniaState(useBookmarkFoldersStore, { - bookmarks: getBookmarkFolderEntries, - }), - ...mapPiniaState(useServerSideStorageStore, { - pinnedItems: store => new Set(store.prefsStorage.collections.pinnedNavItems) + bookmarks: getBookmarkFolderEntries }), ...mapState({ currentUser: state => state.users.currentUser, followRequestCount: state => state.api.followRequests.length, privateMode: state => state.instance.private, federating: state => state.instance.federating, - pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable + pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable, + pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedNavItems) }), pinnedList () { if (!this.currentUser) { diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 4fb8e0428..87c88d8f7 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -363,6 +363,12 @@ const PostStatusForm = { } }, safeToSaveDraft () { + console.log('safe', ( + this.newStatus.status || + this.newStatus.spoilerText || + this.newStatus.files?.length || + this.newStatus.hasPoll + ) && this.saveable) return ( this.newStatus.status || this.newStatus.spoilerText || diff --git a/src/components/settings_modal/helpers/setting.js b/src/components/settings_modal/helpers/setting.js index df137157a..2dc9653ea 100644 --- a/src/components/settings_modal/helpers/setting.js +++ b/src/components/settings_modal/helpers/setting.js @@ -78,6 +78,7 @@ export default { }, computed: { draft: { + // TODO allow passing shared draft object? get () { if (this.realSource === 'admin' || this.path == null) { return get(this.$store.state.adminSettings.draft, this.canonPath) diff --git a/src/components/settings_modal/tabs/filtering_tab.js b/src/components/settings_modal/tabs/filtering_tab.js index 89079635a..fbace15df 100644 --- a/src/components/settings_modal/tabs/filtering_tab.js +++ b/src/components/settings_modal/tabs/filtering_tab.js @@ -1,20 +1,15 @@ -import { throttle } from 'lodash' -import { mapState, mapActions } from 'pinia' -import { useServerSideStorageStore } from 'src/stores/serverSideStorage' -import { v4 as uuidv4 } from 'uuid'; - +import { filter, trim, debounce } from 'lodash' import BooleanSetting from '../helpers/boolean_setting.vue' import ChoiceSetting from '../helpers/choice_setting.vue' import UnitSetting from '../helpers/unit_setting.vue' import IntegerSetting from '../helpers/integer_setting.vue' -import Checkbox from 'src/components/checkbox/checkbox.vue' -import Select from 'src/components/select/select.vue' import SharedComputedObject from '../helpers/shared_computed_object.js' const FilteringTab = { data () { return { + muteWordsStringLocal: this.$store.getters.mergedConfig.muteWords.join('\n'), replyVisibilityOptions: ['all', 'following', 'self'].map(mode => ({ key: mode, value: mode, @@ -26,97 +21,26 @@ const FilteringTab = { BooleanSetting, ChoiceSetting, UnitSetting, - IntegerSetting, - Checkbox, - Select + IntegerSetting }, computed: { ...SharedComputedObject(), - ...mapState( - useServerSideStorageStore, - { - muteFilters: store => Object.entries(store.prefsStorage.simple.muteFilters), - muteFiltersObject: store => store.prefsStorage.simple.muteFilters + muteWordsString: { + get () { + return this.muteWordsStringLocal + }, + set (value) { + this.muteWordsStringLocal = value + this.debouncedSetMuteWords(value) } - ) - }, - methods: { - ...mapActions(useServerSideStorageStore, ['unsetPreference']), - pushServerSideStorage: throttle(() => useServerSideStorageStore().pushServerSideStorage(), 500), - setPreference: throttle(x => useServerSideStorageStore().setPreference(x), 500), - getDatetimeLocal (timestamp) { - const date = new Date(timestamp) - const datetime = [ - date.getFullYear(), - '-', - date.getMonth() < 9 ? ('0' + (date.getMonth() + 1)) : (date.getMonth() + 1), - '-', - date.getDate() < 10 ? ('0' + date.getDate()) : date.getDate(), - 'T', - date.getHours() < 10 ? ('0' + date.getHours()) : date.getHours(), - ':', - date.getMinutes() < 10 ? ('0' + date.getMinutes()) : date.getMinutes(), - ].join('') - return datetime }, - checkRegexValid (id) { - const filter = this.muteFiltersObject[id] - if (filter.type !== 'regexp') return true - const { value } = filter - let valid = true - try { - new RegExp(value) - } catch (e) { - valid = false - console.error('Invalid RegExp: ' + value) - } - return valid - }, - createFilter () { - const filter = { - type: 'word', - value: '', - name: 'New Filter', - enabled: true, - expires: null, - hide: false, - order: this.muteFilters.length + 2 - } - const newId = uuidv4() - - this.setPreference({ path: 'simple.muteFilters.' + newId , value: filter }) - this.pushServerSideStorage() - }, - copyFilter (id) { - const filter = { ...this.muteFiltersObject[id] } - const newId = uuidv4() - - this.setPreference({ path: 'simple.muteFilters.' + newId , value: filter }) - this.pushServerSideStorage() - }, - deleteFilter (id) { - this.unsetPreference({ path: 'simple.muteFilters.' + id , value: null }) - this.pushServerSideStorage() - }, - updateFilter(id, field, value) { - const filter = { ...this.muteFiltersObject[id] } - if (field === 'expires-never') { - // filter[field] = value - if (!value) { - const offset = 1000 * 60 * 60 * 24 * 14 // 2 weeks - const date = Date.now() + offset - filter.expires = date - } else { - filter.expires = null - } - } else if (field === 'expires') { - const parsed = Date.parse(value) - filter.expires = parsed.valueOf() - } else { - filter[field] = value - } - this.setPreference({ path: 'simple.muteFilters.' + id , value: filter }) - this.pushServerSideStorage() + debouncedSetMuteWords () { + return debounce((value) => { + this.$store.dispatch('setOption', { + name: 'muteWords', + value: filter(value.split('\n'), (word) => trim(word).length > 0) + }) + }, 1000) } }, // Updating nested properties diff --git a/src/components/settings_modal/tabs/filtering_tab.scss b/src/components/settings_modal/tabs/filtering_tab.scss deleted file mode 100644 index 7d5ffabb6..000000000 --- a/src/components/settings_modal/tabs/filtering_tab.scss +++ /dev/null @@ -1,61 +0,0 @@ -.filtering-tab { - .muteFilterContainer { - border: 1px solid var(--border); - border-radius: var(--roundness); - - height: 33vh; - overflow-y: auto; - } - - .mute-filter { - border: 1px solid var(--border); - border-radius: var(--roundness); - margin: 0.5em; - padding: 0.5em; - - display: grid; - grid-template-columns: fit-content() 1fr fit-content(); - align-items: baseline; - grid-gap: 0.5em; - } - - .filter-name { - grid-column: 1 / span 2; - grid-row: 1; - } - - .alert, .button-default { - display: inline-block; - line-height: 2; - padding: 0 0.5em; - } - - .filter-enabled { - grid-column: 3; - grid-row: 1; - - text-align: right; - } - - .filter-field { - display: grid; - grid-template-columns: subgrid; - grid-template-rows: subgrid; - grid-column: 1 / span 3; - align-items: baseline; - - label { - grid-column: 1; - text-align: right; - } - - .filter-field-value { - grid-column: 2 / span 2; - } - } - - .filter-buttons { - grid-column: 1 / span 3; - justify-self: end; - } -} diff --git a/src/components/settings_modal/tabs/filtering_tab.vue b/src/components/settings_modal/tabs/filtering_tab.vue index 8b1291102..32325d423 100644 --- a/src/components/settings_modal/tabs/filtering_tab.vue +++ b/src/components/settings_modal/tabs/filtering_tab.vue @@ -1,5 +1,5 @@