From 64fa662644dd385dd746f2b309eef6287f5eae04 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 13 Jan 2021 21:31:57 +0200 Subject: added notices for ws events --- src/modules/api.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/modules') diff --git a/src/modules/api.js b/src/modules/api.js index 08485a30..01c65e49 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -91,12 +91,29 @@ const api = { } ) state.mastoUserSocket.addEventListener('open', () => { + // Do not show notification when we just opened up the page + if (state.mastoUserSocketStatus !== null) { + dispatch('pushGlobalNotice', { + level: 'success', + messageKey: 'timeline.socket_reconnected', + timeout: 5000 + }) + } commit('setMastoUserSocketStatus', WSConnectionStatus.JOINED) }) state.mastoUserSocket.addEventListener('error', ({ detail: error }) => { console.error('Error in MastoAPI websocket:', error) commit('setMastoUserSocketStatus', WSConnectionStatus.ERROR) dispatch('clearOpenedChats') + /* Since data in WS event for error is useless it's better to show + * generic warning instead of in "close" which actually has some + * useful data + */ + dispatch('pushGlobalNotice', { + level: 'error', + messageKey: 'timeline.socket_closed', + timeout: 5000 + }) }) state.mastoUserSocket.addEventListener('close', ({ detail: closeEvent }) => { const ignoreCodes = new Set([ @@ -112,6 +129,12 @@ const api = { dispatch('startFetchingNotifications') dispatch('startFetchingChats') dispatch('restartMastoUserSocket') + dispatch('pushGlobalNotice', { + level: 'error', + messageKey: 'timeline.socket_broke', + messageArgs: [code], + timeout: 5000 + }) } commit('setMastoUserSocketStatus', WSConnectionStatus.CLOSED) dispatch('clearOpenedChats') -- cgit v1.2.3-70-g09d2 From 48bef143d86b02d7feeeac3e1faa0e5e00e09ea6 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 13 Jan 2021 21:33:20 +0200 Subject: fix not being able to re-enable sockets until page refresh --- CHANGELOG.md | 1 + src/modules/api.js | 11 ++++++++++- src/services/api/api.service.js | 1 + 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'src/modules') diff --git a/CHANGELOG.md b/CHANGELOG.md index 6160c5f4..0b9c7f68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Handle punycode in screen names - Fixed local dev mode having non-functional websockets in some cases - Show notices for websocket events (errors, abnormal closures, reconnections) +- Fix not being able to re-enable websocket until page refresh ## [2.2.2] - 2020-12-22 ### Added diff --git a/src/modules/api.js b/src/modules/api.js index 01c65e49..2be0f236 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -40,7 +40,16 @@ const api = { // Global MastoAPI socket control, in future should disable ALL sockets/(re)start relevant sockets enableMastoSockets (store) { const { state, dispatch } = store - if (state.mastoUserSocket) return + // Do not initialize unless nonexistent or closed + if ( + state.mastoUserSocket && + ![ + WebSocket.CLOSED, + WebSocket.CLOSING + ].includes(state.mastoUserSocket.getState()) + ) { + return + } return dispatch('startMastoUserSocket') }, disableMastoSockets (store) { diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index f4483149..d3d5c68d 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -1152,6 +1152,7 @@ export const ProcessedWS = ({ // 1000 = Normal Closure eventTarget.close = () => { socket.close(1000, 'Shutting down socket') } + eventTarget.getState = () => socket.readyState return eventTarget } -- cgit v1.2.3-70-g09d2 From 9a8bc245a6f76f1a41da9d05408dadc36625ffe9 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Wed, 13 Jan 2021 22:17:10 +0200 Subject: fixed few-posts TLs when streaming is enabled --- CHANGELOG.md | 1 + src/components/notifications/notifications.js | 5 ----- src/modules/api.js | 13 +++++++++++++ src/modules/users.js | 2 ++ .../backend_interactor_service.js | 12 ++++++++++-- .../notifications_fetcher/notifications_fetcher.service.js | 6 ++++-- src/services/timeline_fetcher/timeline_fetcher.service.js | 9 +++++++-- 7 files changed, 37 insertions(+), 11 deletions(-) (limited to 'src/modules') diff --git a/CHANGELOG.md b/CHANGELOG.md index 0b9c7f68..4d0ca7d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fixed local dev mode having non-functional websockets in some cases - Show notices for websocket events (errors, abnormal closures, reconnections) - Fix not being able to re-enable websocket until page refresh +- Fix annoying issue where timeline might have few posts when streaming is enabled ## [2.2.2] - 2020-12-22 ### Added diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 49258563..d6bd6375 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -35,11 +35,6 @@ const Notifications = { seenToDisplayCount: DEFAULT_SEEN_TO_DISPLAY_COUNT } }, - created () { - const store = this.$store - const credentials = store.state.users.currentUser.credentials - notificationsFetcher.fetchAndUpdate({ store, credentials }) - }, computed: { mainClass () { return this.minimalMode ? '' : 'panel panel-default' diff --git a/src/modules/api.js b/src/modules/api.js index 2be0f236..b482637d 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -188,6 +188,13 @@ const api = { if (!fetcher) return store.commit('removeFetcher', { fetcherName: timeline, fetcher }) }, + fetchTimeline (store, timeline, { ...rest }) { + store.state.backendInteractor.fetchTimeline({ + store, + timeline, + ...rest + }) + }, // Notifications startFetchingNotifications (store) { @@ -200,6 +207,12 @@ const api = { if (!fetcher) return store.commit('removeFetcher', { fetcherName: 'notifications', fetcher }) }, + fetchNotifications (store, { ...rest }) { + store.state.backendInteractor.fetchNotifications({ + store, + ...rest + }) + }, // Follow requests startFetchingFollowRequests (store) { diff --git a/src/modules/users.js b/src/modules/users.js index 655db4c7..ac52be1f 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -547,6 +547,8 @@ const users = { } if (store.getters.mergedConfig.useStreamingApi) { + store.dispatch('fetchTimeline', 'friends', { since: null }) + store.dispatch('fetchNotifications', { since: null }) store.dispatch('enableMastoSockets').catch((error) => { console.error('Failed initializing MastoAPI Streaming socket', error) startPolling() diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index 45e6bd0e..4a40f5b5 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -1,17 +1,25 @@ import apiService, { getMastodonSocketURI, ProcessedWS } from '../api/api.service.js' -import timelineFetcherService from '../timeline_fetcher/timeline_fetcher.service.js' +import timelineFetcher from '../timeline_fetcher/timeline_fetcher.service.js' import notificationsFetcher from '../notifications_fetcher/notifications_fetcher.service.js' import followRequestFetcher from '../../services/follow_request_fetcher/follow_request_fetcher.service' const backendInteractorService = credentials => ({ startFetchingTimeline ({ timeline, store, userId = false, tag }) { - return timelineFetcherService.startFetching({ timeline, store, credentials, userId, tag }) + return timelineFetcher.startFetching({ timeline, store, credentials, userId, tag }) + }, + + fetchTimeline (args) { + return timelineFetcher.fetchAndUpdate({ ...args, credentials }) }, startFetchingNotifications ({ store }) { return notificationsFetcher.startFetching({ store, credentials }) }, + fetchNotifications (args) { + return notificationsFetcher.fetchAndUpdate({ ...args, credentials }) + }, + startFetchingFollowRequests ({ store }) { return followRequestFetcher.startFetching({ store, credentials }) }, diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js index beeb167c..f83f871e 100644 --- a/src/services/notifications_fetcher/notifications_fetcher.service.js +++ b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -5,7 +5,7 @@ const update = ({ store, notifications, older }) => { store.dispatch('addNewNotifications', { notifications, older }) } -const fetchAndUpdate = ({ store, credentials, older = false }) => { +const fetchAndUpdate = ({ store, credentials, older = false, since }) => { const args = { credentials } const { getters } = store const rootState = store.rootState || store.state @@ -22,8 +22,10 @@ const fetchAndUpdate = ({ store, credentials, older = false }) => { return fetchNotifications({ store, args, older }) } else { // fetch new notifications - if (timelineData.maxId !== Number.POSITIVE_INFINITY) { + if (since === undefined && timelineData.maxId !== Number.POSITIVE_INFINITY) { args['since'] = timelineData.maxId + } else if (since !== null) { + args['since'] = since } const result = fetchNotifications({ store, args, older }) diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js index 921df3ed..46bba41a 100644 --- a/src/services/timeline_fetcher/timeline_fetcher.service.js +++ b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -23,7 +23,8 @@ const fetchAndUpdate = ({ showImmediately = false, userId = false, tag = false, - until + until, + since }) => { const args = { timeline, credentials } const rootState = store.rootState || store.state @@ -35,7 +36,11 @@ const fetchAndUpdate = ({ if (older) { args['until'] = until || timelineData.minId } else { - args['since'] = timelineData.maxId + if (since === undefined) { + args['since'] = timelineData.maxId + } else if (since !== null) { + args['since'] = since + } } args['userId'] = userId -- cgit v1.2.3-70-g09d2 From 3f23aecd10e570f78b4142687a9a3fa349c13018 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Tue, 23 Feb 2021 10:00:23 +0200 Subject: add sensitive by default option --- src/components/post_status_form/post_status_form.js | 4 ++-- src/components/settings_modal/tabs/general_tab.vue | 7 ++++++- src/i18n/en.json | 1 + src/modules/config.js | 3 ++- src/modules/instance.js | 1 + 5 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src/modules') diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 4148381c..e540654b 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -115,7 +115,7 @@ const PostStatusForm = { ? this.copyMessageScope : this.$store.state.users.currentUser.default_scope - const { postContentType: contentType } = this.$store.getters.mergedConfig + const { postContentType: contentType, sensitiveByDefault } = this.$store.getters.mergedConfig return { dropFiles: [], @@ -126,7 +126,7 @@ const PostStatusForm = { newStatus: { spoilerText: this.subject || '', status: statusText, - nsfw: false, + nsfw: !!sensitiveByDefault, files: [], poll: {}, mediaDescriptions: {}, diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue index f93f4ea0..9228c78e 100644 --- a/src/components/settings_modal/tabs/general_tab.vue +++ b/src/components/settings_modal/tabs/general_tab.vue @@ -144,7 +144,12 @@
  • - {{ $t('settings.minimal_scopes_mode') }} {{ minimalScopesModeDefaultValue }} + {{ $t('settings.minimal_scopes_mode') }} + +
  • +
  • + + {{ $t('settings.sensitive_by_default') }}
  • diff --git a/src/i18n/en.json b/src/i18n/en.json index 0e069785..e6acda9c 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -429,6 +429,7 @@ "subject_line_mastodon": "Like mastodon: copy as is", "subject_line_noop": "Do not copy", "post_status_content_type": "Post status content type", + "sensitive_by_default": "Mark posts as sensitive by default", "stop_gifs": "Play-on-hover GIFs", "streaming": "Enable automatic streaming of new posts when scrolled to the top", "user_mutes": "Users", diff --git a/src/modules/config.js b/src/modules/config.js index f992519e..b08903d1 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -67,7 +67,8 @@ export const defaultState = { greentext: undefined, // instance default hidePostStats: undefined, // instance default hideUserStats: undefined, // instance default - virtualScrolling: undefined // instance default + virtualScrolling: undefined, // instance default + sensitiveByDefault: undefined } // caching the instance default properties diff --git a/src/modules/instance.js b/src/modules/instance.js index 411b1caa..96de73ca 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -43,6 +43,7 @@ const defaultState = { subjectLineBehavior: 'email', theme: 'pleroma-dark', virtualScrolling: true, + sensitiveByDefault: false, // Nasty stuff customEmoji: [], -- cgit v1.2.3-70-g09d2 From ecb211606cddeeec809c8a6bc39f9c96a0af95f5 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Tue, 23 Feb 2021 10:06:45 +0200 Subject: change config comment to be consistent --- src/modules/config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/config.js b/src/modules/config.js index b08903d1..eca58c12 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -68,7 +68,7 @@ export const defaultState = { hidePostStats: undefined, // instance default hideUserStats: undefined, // instance default virtualScrolling: undefined, // instance default - sensitiveByDefault: undefined + sensitiveByDefault: undefined // instance default } // caching the instance default properties -- cgit v1.2.3-70-g09d2 From cd2f5ced31a3598eb8a1fcdeef47d70dabf8bb00 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Fri, 26 Feb 2021 14:27:25 +0200 Subject: add basic validation for statusless status notifications --- CHANGELOG.md | 1 + src/modules/statuses.js | 29 ++++++++++++++++------ .../notification_utils/notification_utils.js | 7 ++++++ 3 files changed, 30 insertions(+), 7 deletions(-) (limited to 'src/modules') diff --git a/CHANGELOG.md b/CHANGELOG.md index 2685fd32..929292f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fixed missing highlighted border in expanded conversations again - Fixed some UI jumpiness when opening images particularly in chat view - Fixed chat unread badge looking weird +- Fixed notifications crashing on an invalid notificaiton ### Changed - Display 'people voted' instead of 'votes' for multi-choice polls diff --git a/src/modules/statuses.js b/src/modules/statuses.js index 33c68c57..ac5d25c4 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -13,7 +13,11 @@ import { omitBy } from 'lodash' import { set } from 'vue' -import { isStatusNotification, maybeShowNotification } from '../services/notification_utils/notification_utils.js' +import { + isStatusNotification, + isValidNotification, + maybeShowNotification +} from '../services/notification_utils/notification_utils.js' import apiService from '../services/api/api.service.js' const emptyTl = (userId = 0) => ({ @@ -310,8 +314,24 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us } } +const updateNotificationsMinMaxId = (state, notification) => { + state.notifications.maxId = notification.id > state.notifications.maxId + ? notification.id + : state.notifications.maxId + state.notifications.minId = notification.id < state.notifications.minId + ? notification.id + : state.notifications.minId +} + const addNewNotifications = (state, { dispatch, notifications, older, visibleNotificationTypes, rootGetters, newNotificationSideEffects }) => { each(notifications, (notification) => { + // If invalid notification, update ids but don't add it to store + if (!isValidNotification(notification)) { + console.error('Invalid notification:', notification) + updateNotificationsMinMaxId(state, notification) + return + } + if (isStatusNotification(notification.type)) { notification.action = addStatusToGlobalStorage(state, notification.action).item notification.status = notification.status && addStatusToGlobalStorage(state, notification.status).item @@ -323,12 +343,7 @@ const addNewNotifications = (state, { dispatch, notifications, older, visibleNot // Only add a new notification if we don't have one for the same action if (!state.notifications.idStore.hasOwnProperty(notification.id)) { - state.notifications.maxId = notification.id > state.notifications.maxId - ? notification.id - : state.notifications.maxId - state.notifications.minId = notification.id < state.notifications.minId - ? notification.id - : state.notifications.minId + updateNotificationsMinMaxId(state, notification) state.notifications.data.push(notification) state.notifications.idStore[notification.id] = notification diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index d912d19f..6fef1022 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -22,6 +22,13 @@ const statusNotifications = ['like', 'mention', 'repeat', 'pleroma:emoji_reactio export const isStatusNotification = (type) => includes(statusNotifications, type) +export const isValidNotification = (notification) => { + if (isStatusNotification(notification.type) && !notification.status) { + return false + } + return true +} + const sortById = (a, b) => { const seqA = Number(a.id) const seqB = Number(b.id) -- cgit v1.2.3-70-g09d2 From f6af4c43f656d1990da00bc773c15ebbbc57e71d Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Mon, 1 Mar 2021 16:21:35 +0200 Subject: add quick filters for notifications2 --- .../notifications/notification_filters.vue | 121 +++++++++++++++++++++ src/components/notifications/notifications.js | 8 +- src/components/notifications/notifications.vue | 1 + src/components/timeline/timeline_quick_settings.js | 4 +- .../timeline/timeline_quick_settings.vue | 8 +- src/modules/config.js | 2 +- 6 files changed, 130 insertions(+), 14 deletions(-) create mode 100644 src/components/notifications/notification_filters.vue (limited to 'src/modules') diff --git a/src/components/notifications/notification_filters.vue b/src/components/notifications/notification_filters.vue new file mode 100644 index 00000000..95b2513b --- /dev/null +++ b/src/components/notifications/notification_filters.vue @@ -0,0 +1,121 @@ + + + + + diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 49258563..a9bf2931 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -1,5 +1,6 @@ import { mapGetters } from 'vuex' import Notification from '../notification/notification.vue' +import NotificationFilters from './notification_filters.vue' import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js' import { notificationsFromStore, @@ -17,6 +18,10 @@ library.add( const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30 const Notifications = { + components: { + Notification, + NotificationFilters + }, props: { // Disables display of panel header noHeading: Boolean, @@ -70,9 +75,6 @@ const Notifications = { }, ...mapGetters(['unreadChatCount']) }, - components: { - Notification - }, watch: { unseenCountTitle (count) { if (count > 0) { diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue index 725d1ad4..12097b85 100644 --- a/src/components/notifications/notifications.vue +++ b/src/components/notifications/notifications.vue @@ -22,6 +22,7 @@ > {{ $t('notifications.read') }} +
    -
    +
    { + id += 1 + return { + text: 'test' + id, + author: { + username: 'test', + avatar: '', + id + } + } + } + + const loop = () => { + store.commit('addMessage', createmsg()) + setTimeout(loop, 3000) + } + loop() + channel.on('new_msg', (msg) => { store.commit('addMessage', msg) }) diff --git a/yarn.lock b/yarn.lock index 6d0095db..80c09312 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8923,10 +8923,6 @@ void-elements@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec" -vue-chat-scroll@^1.2.1: - version "1.3.5" - resolved "https://registry.yarnpkg.com/vue-chat-scroll/-/vue-chat-scroll-1.3.5.tgz#a5ee5bae5058f614818a96eac5ee3be4394a2f68" - vue-eslint-parser@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-5.0.0.tgz#00f4e4da94ec974b821a26ff0ed0f7a78402b8a1" -- cgit v1.2.3-70-g09d2 From becacf064303f0fceca8def3f1c49248b9d3e5f8 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Wed, 3 Mar 2021 16:47:59 +0200 Subject: remove shoutbox test hacks --- src/App.vue | 2 +- src/modules/chat.js | 18 ------------------ 2 files changed, 1 insertion(+), 19 deletions(-) (limited to 'src/modules') diff --git a/src/App.vue b/src/App.vue index e09ce4c8..1a166778 100644 --- a/src/App.vue +++ b/src/App.vue @@ -50,7 +50,7 @@
    diff --git a/src/modules/chat.js b/src/modules/chat.js index 264ba00b..ffeb272b 100644 --- a/src/modules/chat.js +++ b/src/modules/chat.js @@ -18,24 +18,6 @@ const chat = { actions: { initializeChat (store, socket) { const channel = socket.channel('chat:public') - let id = 0 - const createmsg = () => { - id += 1 - return { - text: 'test' + id, - author: { - username: 'test', - avatar: '', - id - } - } - } - - const loop = () => { - store.commit('addMessage', createmsg()) - setTimeout(loop, 3000) - } - loop() channel.on('new_msg', (msg) => { store.commit('addMessage', msg) -- cgit v1.2.3-70-g09d2 From dda95543e82ff21ca03c96f3366735a9ec43c0e6 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 8 Mar 2021 19:53:30 +0200 Subject: implemented import/export for themes --- src/components/settings_modal/settings_modal.js | 80 ++++++++++++++++++++++++ src/components/settings_modal/settings_modal.vue | 70 ++++++++++++++++++++- src/i18n/en.json | 5 ++ src/modules/config.js | 5 ++ 4 files changed, 158 insertions(+), 2 deletions(-) (limited to 'src/modules') diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js index f0d49c91..7f6ccccb 100644 --- a/src/components/settings_modal/settings_modal.js +++ b/src/components/settings_modal/settings_modal.js @@ -2,10 +2,52 @@ import Modal from 'src/components/modal/modal.vue' import PanelLoading from 'src/components/panel_loading/panel_loading.vue' import AsyncComponentError from 'src/components/async_component_error/async_component_error.vue' import getResettableAsyncComponent from 'src/services/resettable_async_component.js' +import Popover from '../popover/popover.vue' +import { library } from '@fortawesome/fontawesome-svg-core' +import { cloneDeep } from 'lodash' +import { + newImporter, + newExporter +} from 'src/services/export_import/export_import.js' +import { + faTimes, + faFileUpload, + faFileDownload, + faChevronDown +} from '@fortawesome/free-solid-svg-icons' +import { + faWindowMinimize +} from '@fortawesome/free-regular-svg-icons' + +library.add( + faTimes, + faWindowMinimize, + faFileUpload, + faFileDownload, + faChevronDown +) const SettingsModal = { + data () { + return { + dataImporter: newImporter({ + validator: this.importValidator, + onImport: this.onImport, + onImportFailure: this.onImportFailure + }), + dataThemeExporter: newExporter({ + filename: 'pleromafe_settings.full', + getExportedObject: () => this.generateExport(true) + }), + dataExporter: newExporter({ + filename: 'pleromafe_settings', + getExportedObject: () => this.generateExport() + }) + } + }, components: { Modal, + Popover, SettingsModalContent: getResettableAsyncComponent( () => import('./settings_modal_content.vue'), { @@ -21,6 +63,44 @@ const SettingsModal = { }, peekModal () { this.$store.dispatch('togglePeekSettingsModal') + }, + importValidator (data) { + return data._pleroma_settings_version[0] === 1 + }, + onImportFailure () { + this.$store.dispatch('pushGlobalNotice', { messageKey: 'settings.invalid_settings_imported', level: 'error' }) + }, + onImport (data) { + this.$store.dispatch('loadSettings', data) + }, + restore () { + console.log(this.dataImporter) + this.dataImporter.importData() + }, + backup () { + this.dataExporter.exportData() + }, + backupWithTheme () { + this.dataThemeExporter.exportData() + }, + generateExport (theme = false) { + const { config } = this.$store.state + let sample = config + if (!theme) { + const ignoreList = new Set([ + 'customTheme', + 'customThemeSource', + 'colors' + ]) + sample = Object.fromEntries( + Object + .entries(sample) + .filter(([key]) => !ignoreList.has(key)) + ) + } + const clone = cloneDeep(sample) + clone._pleroma_settings_version = [1, 0] + return clone } }, computed: { diff --git a/src/components/settings_modal/settings_modal.vue b/src/components/settings_modal/settings_modal.vue index 552ca41f..a142bcd1 100644 --- a/src/components/settings_modal/settings_modal.vue +++ b/src/components/settings_modal/settings_modal.vue @@ -32,19 +32,85 @@
    +
    diff --git a/src/i18n/en.json b/src/i18n/en.json index 2aefebc9..049d3d11 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -357,6 +357,7 @@ "interface": "Interface", "interfaceLanguage": "Interface language", "invalid_theme_imported": "The selected file is not a supported Pleroma theme. No changes to your theme were made.", + "invalid_settings_imported": "The selected file is not a supported Pleroma settings backup. No changes were made.", "limited_availability": "Unavailable in your browser", "links": "Links", "lock_account_description": "Restrict your account to approved followers only", @@ -364,6 +365,10 @@ "loop_video_silent_only": "Loop only videos without sound (i.e. Mastodon's \"gifs\")", "mutes_tab": "Mutes", "play_videos_in_modal": "Play videos in a popup frame", + "backup_restore": "Settings backup", + "backup_settings": "Backup settings to file", + "backup_settings_theme": "Backup settings and theme to file", + "restore_settings": "Restore settings from file", "profile_fields": { "label": "Profile metadata", "add_field": "Add Field", diff --git a/src/modules/config.js b/src/modules/config.js index eca58c12..ec3b4c43 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -110,6 +110,11 @@ const config = { } }, actions: { + loadSettings ({ dispatch }, data) { + Object.keys(this.state.config).forEach( + name => dispatch('setOption', { name, value: data[name] }) + ) + }, setHighlight ({ commit, dispatch }, { user, color, type }) { commit('setHighlight', { user, color, type }) }, -- cgit v1.2.3-70-g09d2 From fada49768dcd12faae4f7a188bdd36ea60f8b0a8 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 8 Mar 2021 21:14:03 +0200 Subject: extra protection to not write what we don't know --- src/modules/config.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/modules') diff --git a/src/modules/config.js b/src/modules/config.js index ec3b4c43..352adf20 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -111,7 +111,16 @@ const config = { }, actions: { loadSettings ({ dispatch }, data) { - Object.keys(this.state.config).forEach( + const knownKeys = new Set(Object.keys(this.state.config)) + const presentKeys = new Set(Object.keys(data)) + const intersection = new Set() + for (let elem of presentKeys) { + if (knownKeys.has(elem)) { + intersection.add(elem) + } + } + + Object.keys(intersection).forEach( name => dispatch('setOption', { name, value: data[name] }) ) }, -- cgit v1.2.3-70-g09d2 From 3d95ea6acbd47cabee519b2450647512ac2d5b46 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 8 Mar 2021 21:56:20 +0200 Subject: cleanup + fix --- src/components/settings_modal/settings_modal.js | 1 - src/modules/config.js | 4 ++-- src/services/export_import/export_import.js | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) (limited to 'src/modules') diff --git a/src/components/settings_modal/settings_modal.js b/src/components/settings_modal/settings_modal.js index 7010e4aa..04043483 100644 --- a/src/components/settings_modal/settings_modal.js +++ b/src/components/settings_modal/settings_modal.js @@ -116,7 +116,6 @@ const SettingsModal = { if (data) { this.$store.dispatch('loadSettings', data) } }, restore () { - console.log(this.dataImporter) this.dataImporter.importData() }, backup () { diff --git a/src/modules/config.js b/src/modules/config.js index 352adf20..b0fc98f5 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -111,7 +111,7 @@ const config = { }, actions: { loadSettings ({ dispatch }, data) { - const knownKeys = new Set(Object.keys(this.state.config)) + const knownKeys = new Set(Object.keys(defaultState)) const presentKeys = new Set(Object.keys(data)) const intersection = new Set() for (let elem of presentKeys) { @@ -120,7 +120,7 @@ const config = { } } - Object.keys(intersection).forEach( + intersection.forEach( name => dispatch('setOption', { name, value: data[name] }) ) }, diff --git a/src/services/export_import/export_import.js b/src/services/export_import/export_import.js index 0bf9eadc..ac67cf9c 100644 --- a/src/services/export_import/export_import.js +++ b/src/services/export_import/export_import.js @@ -26,7 +26,6 @@ export const newImporter = ({ const filePicker = document.createElement('input') filePicker.setAttribute('type', 'file') filePicker.setAttribute('accept', '.json') - console.log(1) filePicker.addEventListener('change', event => { if (event.target.files[0]) { @@ -45,7 +44,6 @@ export const newImporter = ({ onImportFailure({ error }) } } - console.log(2) reader.readAsText(event.target.files[0]) } }) -- cgit v1.2.3-70-g09d2 From 90afcd3420a911856bde794f2b4dc1380a1a0751 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Mon, 8 Mar 2021 22:24:39 +0200 Subject: WIP some work on making errors less spammy --- src/i18n/en.json | 3 +- src/modules/api.js | 44 +++++++++++++--------- .../notifications_fetcher.service.js | 14 ++++--- .../timeline_fetcher/timeline_fetcher.service.js | 14 ++++--- 4 files changed, 43 insertions(+), 32 deletions(-) (limited to 'src/modules') diff --git a/src/i18n/en.json b/src/i18n/en.json index 217ac7c8..635bfd56 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -664,8 +664,7 @@ "no_more_statuses": "No more statuses", "no_statuses": "No statuses", "socket_reconnected": "Realtime connection established", - "socket_broke": "Realtime connection lost: CloseEvent code {0}", - "socket_closed": "No realtime connection, updates can arrive with a delaye until connection is re-established" + "socket_broke": "Realtime connection lost: CloseEvent code {0}" }, "status": { "favorites": "Favorites", diff --git a/src/modules/api.js b/src/modules/api.js index b482637d..e392d5b0 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -5,6 +5,8 @@ import { Socket } from 'phoenix' const api = { state: { + connectionBroken: false, + retryMultiplier: 1, backendInteractor: backendInteractorService(), fetchers: {}, socket: null, @@ -34,12 +36,18 @@ const api = { }, setMastoUserSocketStatus (state, value) { state.mastoUserSocketStatus = value + }, + recoverConnection (state) { + state.connectionBroken = false + }, + breakConnection (state) { + state.connectionBroken = true } }, actions: { // Global MastoAPI socket control, in future should disable ALL sockets/(re)start relevant sockets enableMastoSockets (store) { - const { state, dispatch } = store + const { state, dispatch, commit } = store // Do not initialize unless nonexistent or closed if ( state.mastoUserSocket && @@ -50,11 +58,13 @@ const api = { ) { return } + commit('recoverConnection') return dispatch('startMastoUserSocket') }, disableMastoSockets (store) { - const { state, dispatch } = store + const { state, dispatch, commit } = store if (!state.mastoUserSocket) return + commit('recoverConnection') return dispatch('stopMastoUserSocket') }, @@ -102,6 +112,7 @@ const api = { state.mastoUserSocket.addEventListener('open', () => { // Do not show notification when we just opened up the page if (state.mastoUserSocketStatus !== null) { + commit('recoverConnection') dispatch('pushGlobalNotice', { level: 'success', messageKey: 'timeline.socket_reconnected', @@ -114,15 +125,6 @@ const api = { console.error('Error in MastoAPI websocket:', error) commit('setMastoUserSocketStatus', WSConnectionStatus.ERROR) dispatch('clearOpenedChats') - /* Since data in WS event for error is useless it's better to show - * generic warning instead of in "close" which actually has some - * useful data - */ - dispatch('pushGlobalNotice', { - level: 'error', - messageKey: 'timeline.socket_closed', - timeout: 5000 - }) }) state.mastoUserSocket.addEventListener('close', ({ detail: closeEvent }) => { const ignoreCodes = new Set([ @@ -137,13 +139,19 @@ const api = { dispatch('startFetchingTimeline', { timeline: 'friends' }) dispatch('startFetchingNotifications') dispatch('startFetchingChats') - dispatch('restartMastoUserSocket') - dispatch('pushGlobalNotice', { - level: 'error', - messageKey: 'timeline.socket_broke', - messageArgs: [code], - timeout: 5000 - }) + setTimeout(() => { + console.log('TEST') + dispatch('restartMastoUserSocket') + }, 1000) + if (!state.connectionBroken) { + dispatch('pushGlobalNotice', { + level: 'error', + messageKey: 'timeline.socket_broke', + messageArgs: [code], + timeout: 5000 + }) + } + commit('breakConnection') } commit('setMastoUserSocketStatus', WSConnectionStatus.CLOSED) dispatch('clearOpenedChats') diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js index f83f871e..fc5e76ba 100644 --- a/src/services/notifications_fetcher/notifications_fetcher.service.js +++ b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -57,12 +57,14 @@ const fetchNotifications = ({ store, args, older }) => { return notifications }) .catch((error) => { - store.dispatch('pushGlobalNotice', { - level: 'error', - messageKey: 'notifications.error', - messageArgs: [error.message], - timeout: 5000 - }) + if (!store.rootState.api.connectionBroken) { + store.dispatch('pushGlobalNotice', { + level: 'error', + messageKey: 'notifications.error', + messageArgs: [error.message], + timeout: 5000 + }) + } }) } diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js index 46bba41a..eb4a3e0d 100644 --- a/src/services/timeline_fetcher/timeline_fetcher.service.js +++ b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -66,12 +66,14 @@ const fetchAndUpdate = ({ return { statuses, pagination } }) .catch((error) => { - store.dispatch('pushGlobalNotice', { - level: 'error', - messageKey: 'timeline.error', - messageArgs: [error.message], - timeout: 5000 - }) + if (!store.rootState.api.connectionBroken) { + store.dispatch('pushGlobalNotice', { + level: 'error', + messageKey: 'timeline.error', + messageArgs: [error.message], + timeout: 5000 + }) + } }) } -- cgit v1.2.3-70-g09d2 From a8967d85bd7ae1541f1d4e41e95fc8fa111f2360 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Tue, 9 Mar 2021 02:38:10 +0200 Subject: streamlined WS flow, reduced spam amount related to WS reconnections --- src/modules/api.js | 69 ++++++++++++---------- src/modules/users.js | 3 +- src/services/api/api.service.js | 5 +- .../notifications_fetcher.service.js | 14 ++--- .../timeline_fetcher/timeline_fetcher.service.js | 14 ++--- 5 files changed, 56 insertions(+), 49 deletions(-) (limited to 'src/modules') diff --git a/src/modules/api.js b/src/modules/api.js index e392d5b0..8654b90a 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -3,9 +3,10 @@ import { WSConnectionStatus } from '../services/api/api.service.js' import { maybeShowChatNotification } from '../services/chat_utils/chat_utils.js' import { Socket } from 'phoenix' +const retryTimeout = (multiplier) => 1000 * multiplier + const api = { state: { - connectionBroken: false, retryMultiplier: 1, backendInteractor: backendInteractorService(), fetchers: {}, @@ -37,16 +38,20 @@ const api = { setMastoUserSocketStatus (state, value) { state.mastoUserSocketStatus = value }, - recoverConnection (state) { - state.connectionBroken = false + incrementRetryMultiplier (state) { + state.retryMultiplier = Math.max(++state.retryMultiplier, 3) }, - breakConnection (state) { - state.connectionBroken = true + resetRetryMultiplier (state) { + state.retryMultiplier = 1 } }, actions: { - // Global MastoAPI socket control, in future should disable ALL sockets/(re)start relevant sockets - enableMastoSockets (store) { + /** + * Global MastoAPI socket control, in future should disable ALL sockets/(re)start relevant sockets + * + * @param {Boolean} [initial] - whether this enabling happened at boot time or not + */ + enableMastoSockets (store, initial) { const { state, dispatch, commit } = store // Do not initialize unless nonexistent or closed if ( @@ -58,13 +63,17 @@ const api = { ) { return } - commit('recoverConnection') + if (initial) { + commit('setMastoUserSocketStatus', WSConnectionStatus.STARTING_INITIAL) + } else { + commit('setMastoUserSocketStatus', WSConnectionStatus.STARTING) + } return dispatch('startMastoUserSocket') }, disableMastoSockets (store) { const { state, dispatch, commit } = store if (!state.mastoUserSocket) return - commit('recoverConnection') + commit('setMastoUserSocketStatus', WSConnectionStatus.DISABLED) return dispatch('stopMastoUserSocket') }, @@ -111,19 +120,28 @@ const api = { ) state.mastoUserSocket.addEventListener('open', () => { // Do not show notification when we just opened up the page - if (state.mastoUserSocketStatus !== null) { - commit('recoverConnection') + if (state.mastoUserSocketStatus !== WSConnectionStatus.STARTING_INITIAL) { dispatch('pushGlobalNotice', { level: 'success', messageKey: 'timeline.socket_reconnected', timeout: 5000 }) } + // Stop polling if we were errored or disabled + if (new Set([ + WSConnectionStatus.ERROR, + WSConnectionStatus.DISABLED + ]).has(state.mastoUserSocketStatus)) { + dispatch('stopFetchingTimeline', { timeline: 'friends' }) + dispatch('stopFetchingNotifications') + dispatch('stopFetchingChats') + } + commit('resetRetryMultiplier') commit('setMastoUserSocketStatus', WSConnectionStatus.JOINED) }) state.mastoUserSocket.addEventListener('error', ({ detail: error }) => { console.error('Error in MastoAPI websocket:', error) - commit('setMastoUserSocketStatus', WSConnectionStatus.ERROR) + // TODO is this needed? dispatch('clearOpenedChats') }) state.mastoUserSocket.addEventListener('close', ({ detail: closeEvent }) => { @@ -134,16 +152,17 @@ const api = { const { code } = closeEvent if (ignoreCodes.has(code)) { console.debug(`Not restarting socket becasue of closure code ${code} is in ignore list`) + commit('setMastoUserSocketStatus', WSConnectionStatus.CLOSED) } else { console.warn(`MastoAPI websocket disconnected, restarting. CloseEvent code: ${code}`) - dispatch('startFetchingTimeline', { timeline: 'friends' }) - dispatch('startFetchingNotifications') - dispatch('startFetchingChats') setTimeout(() => { - console.log('TEST') - dispatch('restartMastoUserSocket') - }, 1000) - if (!state.connectionBroken) { + dispatch('startMastoUserSocket') + }, retryTimeout(state.retryMultiplier)) + commit('incrementRetryMultiplier') + if (state.mastoUserSocketStatus !== WSConnectionStatus.ERROR) { + dispatch('startFetchingTimeline', { timeline: 'friends' }) + dispatch('startFetchingNotifications') + dispatch('startFetchingChats') dispatch('pushGlobalNotice', { level: 'error', messageKey: 'timeline.socket_broke', @@ -151,9 +170,8 @@ const api = { timeout: 5000 }) } - commit('breakConnection') + commit('setMastoUserSocketStatus', WSConnectionStatus.ERROR) } - commit('setMastoUserSocketStatus', WSConnectionStatus.CLOSED) dispatch('clearOpenedChats') }) resolve() @@ -162,15 +180,6 @@ const api = { } }) }, - restartMastoUserSocket ({ dispatch }) { - // This basically starts MastoAPI user socket and stops conventional - // fetchers when connection reestablished - return dispatch('startMastoUserSocket').then(() => { - dispatch('stopFetchingTimeline', { timeline: 'friends' }) - dispatch('stopFetchingNotifications') - dispatch('stopFetchingChats') - }) - }, stopMastoUserSocket ({ state, dispatch }) { dispatch('startFetchingTimeline', { timeline: 'friends' }) dispatch('startFetchingNotifications') diff --git a/src/modules/users.js b/src/modules/users.js index ac52be1f..8a764a16 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -549,9 +549,8 @@ const users = { if (store.getters.mergedConfig.useStreamingApi) { store.dispatch('fetchTimeline', 'friends', { since: null }) store.dispatch('fetchNotifications', { since: null }) - store.dispatch('enableMastoSockets').catch((error) => { + store.dispatch('enableMastoSockets', true).catch((error) => { console.error('Failed initializing MastoAPI Streaming socket', error) - startPolling() }).then(() => { store.dispatch('fetchChats', { latest: true }) setTimeout(() => store.dispatch('setNotificationsSilence', false), 10000) diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index d3d5c68d..436b8b0a 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -1184,7 +1184,10 @@ export const handleMastoWS = (wsEvent) => { export const WSConnectionStatus = Object.freeze({ 'JOINED': 1, 'CLOSED': 2, - 'ERROR': 3 + 'ERROR': 3, + 'DISABLED': 4, + 'STARTING': 5, + 'STARTING_INITIAL': 6 }) const chats = ({ credentials }) => { diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js index fc5e76ba..f83f871e 100644 --- a/src/services/notifications_fetcher/notifications_fetcher.service.js +++ b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -57,14 +57,12 @@ const fetchNotifications = ({ store, args, older }) => { return notifications }) .catch((error) => { - if (!store.rootState.api.connectionBroken) { - store.dispatch('pushGlobalNotice', { - level: 'error', - messageKey: 'notifications.error', - messageArgs: [error.message], - timeout: 5000 - }) - } + store.dispatch('pushGlobalNotice', { + level: 'error', + messageKey: 'notifications.error', + messageArgs: [error.message], + timeout: 5000 + }) }) } diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js index eb4a3e0d..46bba41a 100644 --- a/src/services/timeline_fetcher/timeline_fetcher.service.js +++ b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -66,14 +66,12 @@ const fetchAndUpdate = ({ return { statuses, pagination } }) .catch((error) => { - if (!store.rootState.api.connectionBroken) { - store.dispatch('pushGlobalNotice', { - level: 'error', - messageKey: 'timeline.error', - messageArgs: [error.message], - timeout: 5000 - }) - } + store.dispatch('pushGlobalNotice', { + level: 'error', + messageKey: 'timeline.error', + messageArgs: [error.message], + timeout: 5000 + }) }) } -- cgit v1.2.3-70-g09d2 From 7341b8a5516621985a76456e1eefc58cd23ff2e2 Mon Sep 17 00:00:00 2001 From: eris Date: Wed, 26 May 2021 22:22:55 +0000 Subject: Implement right sidebar option as user option --- CHANGELOG.md | 1 + src/App.js | 2 +- src/components/settings_modal/tabs/general_tab.vue | 5 +++++ src/i18n/en.json | 1 + src/modules/config.js | 1 + 5 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/modules') diff --git a/CHANGELOG.md b/CHANGELOG.md index cef6d401..905d9f65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Added a quick settings to timeline header for easier access - Added option to mark posts as sensitive by default - Added quick filters for notifications +- Implemented user option to change sidebar position to the right side ## [2.3.0] - 2021-03-01 diff --git a/src/App.js b/src/App.js index 1ca029b6..231c6ae1 100644 --- a/src/App.js +++ b/src/App.js @@ -77,7 +77,7 @@ export default { privateMode () { return this.$store.state.instance.private }, sidebarAlign () { return { - 'order': this.$store.state.instance.sidebarRight ? 99 : 0 + 'order': this.$store.getters.mergedConfig.sidebarRight ? 99 : 0 } }, ...mapGetters(['mergedConfig']) diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue index 9228c78e..7bae4a32 100644 --- a/src/components/settings_modal/tabs/general_tab.vue +++ b/src/components/settings_modal/tabs/general_tab.vue @@ -11,6 +11,11 @@ {{ $t('settings.hide_isp') }}
  • +
  • + + {{ $t('settings.right_sidebar') }} + +
  • {{ $t('settings.hide_wallpaper') }} diff --git a/src/i18n/en.json b/src/i18n/en.json index d6138482..1b38e29a 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -345,6 +345,7 @@ "hide_all_muted_posts": "Hide muted posts", "max_thumbnails": "Maximum amount of thumbnails per post", "hide_isp": "Hide instance-specific panel", + "right_sidebar": "Show sidebar on the right side", "hide_wallpaper": "Hide instance wallpaper", "preload_images": "Preload images", "use_one_click_nsfw": "Open NSFW attachments with just one click", diff --git a/src/modules/config.js b/src/modules/config.js index 629588a8..0f596750 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -54,6 +54,7 @@ export const defaultState = { interfaceLanguage: browserLocale, hideScopeNotice: false, useStreamingApi: false, + sidebarRight: undefined, // instance default scopeCopy: undefined, // instance default subjectLineBehavior: undefined, // instance default alwaysShowSubjectInput: undefined, // instance default -- cgit v1.2.3-70-g09d2 From 0604b1d5b7b19db41096876d0d911ea95c3c778f Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Mon, 3 Aug 2020 18:44:35 -0500 Subject: Rename legacy PleromaFE Chat functionality to "Shout" --- src/App.js | 6 +- src/App.vue | 6 +- src/boot/after_store.js | 2 +- src/boot/routes.js | 4 +- src/components/chat_panel/chat_panel.js | 53 -------- src/components/chat_panel/chat_panel.vue | 148 ----------------------- src/components/features_panel/features_panel.js | 2 +- src/components/features_panel/features_panel.vue | 4 +- src/components/shout_panel/shout_panel.js | 53 ++++++++ src/components/shout_panel/shout_panel.vue | 148 +++++++++++++++++++++++ src/components/side_drawer/side_drawer.js | 2 +- src/main.js | 4 +- src/modules/api.js | 4 +- src/modules/chat.js | 34 ------ src/modules/instance.js | 6 +- src/modules/shout.js | 33 +++++ src/modules/users.js | 2 +- static/config.json | 2 +- 18 files changed, 256 insertions(+), 257 deletions(-) delete mode 100644 src/components/chat_panel/chat_panel.js delete mode 100644 src/components/chat_panel/chat_panel.vue create mode 100644 src/components/shout_panel/shout_panel.js create mode 100644 src/components/shout_panel/shout_panel.vue delete mode 100644 src/modules/chat.js create mode 100644 src/modules/shout.js (limited to 'src/modules') diff --git a/src/App.js b/src/App.js index 231c6ae1..fe4c30cb 100644 --- a/src/App.js +++ b/src/App.js @@ -4,7 +4,7 @@ import Notifications from './components/notifications/notifications.vue' import InstanceSpecificPanel from './components/instance_specific_panel/instance_specific_panel.vue' import FeaturesPanel from './components/features_panel/features_panel.vue' import WhoToFollowPanel from './components/who_to_follow_panel/who_to_follow_panel.vue' -import ChatPanel from './components/chat_panel/chat_panel.vue' +import ShoutPanel from './components/shout_panel/shout_panel.vue' import SettingsModal from './components/settings_modal/settings_modal.vue' import MediaModal from './components/media_modal/media_modal.vue' import SideDrawer from './components/side_drawer/side_drawer.vue' @@ -26,7 +26,7 @@ export default { InstanceSpecificPanel, FeaturesPanel, WhoToFollowPanel, - ChatPanel, + ShoutPanel, MediaModal, SideDrawer, MobilePostStatusButton, @@ -65,7 +65,7 @@ export default { } } }, - chat () { return this.$store.state.chat.channel.state === 'joined' }, + shout () { return this.$store.state.shout.channel.state === 'joined' }, suggestionsEnabled () { return this.$store.state.instance.suggestionsEnabled }, showInstanceSpecificPanel () { return this.$store.state.instance.showInstanceSpecificPanel && diff --git a/src/App.vue b/src/App.vue index 1a166778..6c582c03 100644 --- a/src/App.vue +++ b/src/App.vue @@ -49,10 +49,10 @@ - diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 45090e5d..613228e9 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -240,7 +240,7 @@ const getNodeInfo = async ({ store }) => { store.dispatch('setInstanceOption', { name: 'registrationOpen', value: data.openRegistrations }) store.dispatch('setInstanceOption', { name: 'mediaProxyAvailable', value: features.includes('media_proxy') }) store.dispatch('setInstanceOption', { name: 'safeDM', value: features.includes('safe_dm_mentions') }) - store.dispatch('setInstanceOption', { name: 'chatAvailable', value: features.includes('chat') }) + store.dispatch('setInstanceOption', { name: 'shoutAvailable', value: features.includes('shout') }) store.dispatch('setInstanceOption', { name: 'pleromaChatMessagesAvailable', value: features.includes('pleroma_chat_messages') }) store.dispatch('setInstanceOption', { name: 'gopherAvailable', value: features.includes('gopher') }) store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') }) diff --git a/src/boot/routes.js b/src/boot/routes.js index b5d3c631..1bc1f9f7 100644 --- a/src/boot/routes.js +++ b/src/boot/routes.js @@ -16,7 +16,7 @@ import FollowRequests from 'components/follow_requests/follow_requests.vue' import OAuthCallback from 'components/oauth_callback/oauth_callback.vue' import Notifications from 'components/notifications/notifications.vue' import AuthForm from 'components/auth_form/auth_form.js' -import ChatPanel from 'components/chat_panel/chat_panel.vue' +import ShoutPanel from 'components/shout_panel/shout_panel.vue' import WhoToFollow from 'components/who_to_follow/who_to_follow.vue' import About from 'components/about/about.vue' import RemoteUserResolver from 'components/remote_user_resolver/remote_user_resolver.vue' @@ -64,7 +64,7 @@ export default (store) => { { name: 'friend-requests', path: '/friend-requests', component: FollowRequests, beforeEnter: validateAuthenticatedRoute }, { name: 'notifications', path: '/:username/notifications', component: Notifications, beforeEnter: validateAuthenticatedRoute }, { name: 'login', path: '/login', component: AuthForm }, - { name: 'chat-panel', path: '/chat-panel', component: ChatPanel, props: () => ({ floating: false }) }, + { name: 'shout-panel', path: '/shout-panel', component: ShoutPanel, props: () => ({ floating: false }) }, { name: 'oauth-callback', path: '/oauth-callback', component: OAuthCallback, props: (route) => ({ code: route.query.code }) }, { name: 'search', path: '/search', component: Search, props: (route) => ({ query: route.query.query }) }, { name: 'who-to-follow', path: '/who-to-follow', component: WhoToFollow, beforeEnter: validateAuthenticatedRoute }, diff --git a/src/components/chat_panel/chat_panel.js b/src/components/chat_panel/chat_panel.js deleted file mode 100644 index 556694ae..00000000 --- a/src/components/chat_panel/chat_panel.js +++ /dev/null @@ -1,53 +0,0 @@ -import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator' -import { library } from '@fortawesome/fontawesome-svg-core' -import { - faBullhorn, - faTimes -} from '@fortawesome/free-solid-svg-icons' - -library.add( - faBullhorn, - faTimes -) - -const chatPanel = { - props: [ 'floating' ], - data () { - return { - currentMessage: '', - channel: null, - collapsed: true - } - }, - computed: { - messages () { - return this.$store.state.chat.messages - } - }, - methods: { - submit (message) { - this.$store.state.chat.channel.push('new_msg', { text: message }, 10000) - this.currentMessage = '' - }, - togglePanel () { - this.collapsed = !this.collapsed - }, - userProfileLink (user) { - return generateProfileLink(user.id, user.username, this.$store.state.instance.restrictedNicknames) - } - }, - watch: { - messages (newVal) { - const scrollEl = this.$el.querySelector('.chat-window') - if (!scrollEl) return - if (scrollEl.scrollTop + scrollEl.offsetHeight + 20 > scrollEl.scrollHeight) { - this.$nextTick(() => { - if (!scrollEl) return - scrollEl.scrollTop = scrollEl.scrollHeight - scrollEl.offsetHeight - }) - } - } - } -} - -export default chatPanel diff --git a/src/components/chat_panel/chat_panel.vue b/src/components/chat_panel/chat_panel.vue deleted file mode 100644 index 8a829115..00000000 --- a/src/components/chat_panel/chat_panel.vue +++ /dev/null @@ -1,148 +0,0 @@ -