From 6529f9fa34c5e4e4786f76f63068d70c771d868e Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Tue, 30 Jun 2020 15:04:16 +0300 Subject: add strikethrough when parent isn't visible --- src/components/status/status.vue | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'src/components') diff --git a/src/components/status/status.vue b/src/components/status/status.vue index 7ec29b28..c537358b 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -208,7 +208,12 @@ @click.prevent="gotoOriginal(status.in_reply_to_status_id)" > - {{ $t('status.reply_to') }} + + {{ $t('status.reply_to') }} + Date: Tue, 30 Jun 2020 15:15:27 +0300 Subject: add no-statusId support for status popover --- src/components/status/status.vue | 2 +- src/components/status_popover/status_popover.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/components') diff --git a/src/components/status/status.vue b/src/components/status/status.vue index c537358b..8237be6c 100644 --- a/src/components/status/status.vue +++ b/src/components/status/status.vue @@ -197,7 +197,7 @@ > diff --git a/src/components/status_popover/status_popover.js b/src/components/status_popover/status_popover.js index 159132a9..51e7680c 100644 --- a/src/components/status_popover/status_popover.js +++ b/src/components/status_popover/status_popover.js @@ -22,6 +22,10 @@ const StatusPopover = { methods: { enter () { if (!this.status) { + if (!this.statusId) { + this.error = true + return + } this.$store.dispatch('fetchStatus', this.statusId) .then(data => (this.error = false)) .catch(e => (this.error = true)) -- cgit v1.2.3-70-g09d2 From 62d0bc47b333135f31abea90b4f5a3c28e608733 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Wed, 1 Jul 2020 14:15:04 +0300 Subject: remove unnecessary fetchAndUpdate, change notifications fetcher to not double fetch --- src/components/notifications/notifications.js | 5 ----- src/modules/api.js | 3 --- .../backend_interactor_service/backend_interactor_service.js | 4 ---- .../notifications_fetcher/notifications_fetcher.service.js | 7 +++++-- 4 files changed, 5 insertions(+), 14 deletions(-) (limited to 'src/components') diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index 26ffbab6..e999a18e 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -56,11 +56,6 @@ const Notifications = { components: { Notification }, - created () { - const { dispatch } = this.$store - - dispatch('fetchAndUpdateNotifications') - }, watch: { unseenCount (count) { if (count > 0) { diff --git a/src/modules/api.js b/src/modules/api.js index 748570e5..04ef6ab4 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -138,9 +138,6 @@ const api = { if (!fetcher) return store.commit('removeFetcher', { fetcherName: 'notifications', fetcher }) }, - fetchAndUpdateNotifications (store) { - store.state.backendInteractor.fetchAndUpdateNotifications({ store }) - }, // Follow requests startFetchingFollowRequests (store) { diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index e1c32860..45e6bd0e 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -12,10 +12,6 @@ const backendInteractorService = credentials => ({ return notificationsFetcher.startFetching({ store, credentials }) }, - fetchAndUpdateNotifications ({ store }) { - return notificationsFetcher.fetchAndUpdate({ store, 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 64499a1b..581931f5 100644 --- a/src/services/notifications_fetcher/notifications_fetcher.service.js +++ b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -31,8 +31,11 @@ const fetchAndUpdate = ({ store, credentials, older = false }) => { const notifications = timelineData.data const readNotifsIds = notifications.filter(n => n.seen).map(n => n.id) if (readNotifsIds.length) { - args['since'] = Math.max(...readNotifsIds) - fetchNotifications({ store, args, older }) + const possibleMax = Math.max(...readNotifsIds) + if (possibleMax !== timelineData.maxId) { + args['since'] = possibleMax + fetchNotifications({ store, args, older }) + } } return result -- cgit v1.2.3-70-g09d2 From a3e370e9f816e3c98028bf82e8ac020b8e294466 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Wed, 1 Jul 2020 15:19:45 +0300 Subject: add initial fetching back in a more streamlined way --- src/components/notifications/notifications.js | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/components') diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index e999a18e..30187072 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -27,6 +27,11 @@ const Notifications = { seenToDisplayCount: DEFAULT_SEEN_TO_DISPLAY_COUNT } }, + created () { + const store = this.$store + const credentials = store.state.users.currentUser.credentials + notificationsFetcher.fetchAndUpdate({ store: this.$store, credentials }) + }, computed: { mainClass () { return this.minimalMode ? '' : 'panel panel-default' -- cgit v1.2.3-70-g09d2 From 1293bec77e5137acf64d3536c286f8ba3df284f4 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Thu, 2 Jul 2020 10:40:41 +0300 Subject: change storage error one-off into a global notice system --- src/App.js | 10 +-- src/App.scss | 9 --- src/App.vue | 11 +--- .../global_notice_list/global_notice_list.js | 15 +++++ .../global_notice_list/global_notice_list.vue | 77 ++++++++++++++++++++++ src/main.js | 16 +++-- src/modules/interface.js | 33 ++++++++-- src/services/theme_data/pleromafe.js | 36 +++++++++- 8 files changed, 167 insertions(+), 40 deletions(-) create mode 100644 src/components/global_notice_list/global_notice_list.js create mode 100644 src/components/global_notice_list/global_notice_list.vue (limited to 'src/components') diff --git a/src/App.js b/src/App.js index da66fe21..92c4e2f5 100644 --- a/src/App.js +++ b/src/App.js @@ -13,6 +13,7 @@ import MobilePostStatusButton from './components/mobile_post_status_button/mobil import MobileNav from './components/mobile_nav/mobile_nav.vue' import UserReportingModal from './components/user_reporting_modal/user_reporting_modal.vue' import PostStatusModal from './components/post_status_modal/post_status_modal.vue' +import GlobalNoticeList from './components/global_notice_list/global_notice_list.vue' import { windowWidth } from './services/window_utils/window_utils' export default { @@ -32,7 +33,8 @@ export default { MobileNav, SettingsModal, UserReportingModal, - PostStatusModal + PostStatusModal, + GlobalNoticeList }, data: () => ({ mobileActivePanel: 'timeline', @@ -107,9 +109,6 @@ export default { return { 'order': this.$store.state.instance.sidebarRight ? 99 : 0 } - }, - showStorageError () { - return this.$store.state.interface.storageError === 'show' } }, methods: { @@ -132,9 +131,6 @@ export default { if (changed) { this.$store.dispatch('setMobileLayout', mobileLayout) } - }, - hideStorageError () { - this.$store.dispatch('setStorageError', 'hide') } } } diff --git a/src/App.scss b/src/App.scss index db447f1c..f2972eda 100644 --- a/src/App.scss +++ b/src/App.scss @@ -806,15 +806,6 @@ nav { } } -.storage-error-notice { - text-align: center; - i { - cursor: pointer; - color: $fallback--text; - color: var(--alertErrorText, $fallback--text); - } -} - .button-icon { font-size: 1.2em; } diff --git a/src/App.vue b/src/App.vue index 23991eac..03b632ec 100644 --- a/src/App.vue +++ b/src/App.vue @@ -101,16 +101,6 @@
-
- {{ $t("errors.storage_unavailable") }} - -
diff --git a/src/components/global_notice_list/global_notice_list.js b/src/components/global_notice_list/global_notice_list.js new file mode 100644 index 00000000..3af29c23 --- /dev/null +++ b/src/components/global_notice_list/global_notice_list.js @@ -0,0 +1,15 @@ + +const GlobalNoticeList = { + computed: { + notices () { + return this.$store.state.interface.globalNotices + } + }, + methods: { + closeNotice (notice) { + this.$store.dispatch('removeGlobalNotice', notice) + } + } +} + +export default GlobalNoticeList diff --git a/src/components/global_notice_list/global_notice_list.vue b/src/components/global_notice_list/global_notice_list.vue new file mode 100644 index 00000000..0e4285cc --- /dev/null +++ b/src/components/global_notice_list/global_notice_list.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/src/main.js b/src/main.js index a7294ea0..5bddc76e 100644 --- a/src/main.js +++ b/src/main.js @@ -62,14 +62,14 @@ const persistedStateOptions = { }; (async () => { - let persistedState - let storageError = 'none' + let storageError = false + const plugins = [pushNotifications] try { - persistedState = await createPersistedState(persistedStateOptions) + const persistedState = await createPersistedState(persistedStateOptions) + plugins.push(persistedState) } catch (e) { console.error(e) - storageError = 'show' - persistedState = _ => _ + storageError = true } const store = new Vuex.Store({ modules: { @@ -93,11 +93,13 @@ const persistedStateOptions = { polls: pollsModule, postStatus: postStatusModule }, - plugins: [persistedState, pushNotifications], + plugins, strict: false // Socket modifies itself, let's ignore this for now. // strict: process.env.NODE_ENV !== 'production' }) - store.dispatch('setStorageError', storageError) + if (storageError) { + store.dispatch('pushGlobalNotice', { messageKey: 'errors.storage_unavailable', level: 'error' }) + } afterStoreSetup({ store, i18n }) })() diff --git a/src/modules/interface.js b/src/modules/interface.js index 4b5b5b5d..338ef651 100644 --- a/src/modules/interface.js +++ b/src/modules/interface.js @@ -8,14 +8,14 @@ const defaultState = { noticeClearTimeout: null, notificationPermission: null }, - storageError: 'none', browserSupport: { cssFilter: window.CSS && window.CSS.supports && ( window.CSS.supports('filter', 'drop-shadow(0 0)') || window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)') ) }, - mobileLayout: false + mobileLayout: false, + globalNotices: [] } const interfaceMod = { @@ -60,8 +60,11 @@ const interfaceMod = { state.settingsModalLoaded = true } }, - setStorageError (state, value) { - state.storageError = value + pushGlobalNotice (state, notice) { + state.globalNotices.push(notice) + }, + removeGlobalNotice (state, notice) { + state.globalNotices = state.globalNotices.filter(n => n !== notice) } }, actions: { @@ -86,8 +89,26 @@ const interfaceMod = { togglePeekSettingsModal ({ commit }) { commit('togglePeekSettingsModal') }, - setStorageError ({ commit }, value) { - commit('setStorageError', value) + pushGlobalNotice ( + { commit, dispatch }, + { + messageKey, + messageArgs = {}, + level = 'error', + timeout = 0 + }) { + const notice = { + messageKey, + messageArgs, + level + } + if (timeout) { + setTimeout(() => dispatch('removeGlobalNotice', notice), timeout) + } + commit('pushGlobalNotice', notice) + }, + removeGlobalNotice ({ commit }, notice) { + commit('removeGlobalNotice', notice) } } } diff --git a/src/services/theme_data/pleromafe.js b/src/services/theme_data/pleromafe.js index b577cfab..83c878ed 100644 --- a/src/services/theme_data/pleromafe.js +++ b/src/services/theme_data/pleromafe.js @@ -34,7 +34,8 @@ export const DEFAULT_OPACITY = { alert: 0.5, input: 0.5, faint: 0.5, - underlay: 0.15 + underlay: 0.15, + alertPopup: 0.85 } /** SUBJECT TO CHANGE IN THE FUTURE, this is all beta @@ -627,6 +628,39 @@ export const SLOT_INHERITANCE = { textColor: true }, + alertPopupError: { + depends: ['alertError'], + opacity: 'alertPopup' + }, + alertPopupErrorText: { + depends: ['alertErrorText'], + layer: 'popover', + variant: 'alertPopupError', + textColor: true + }, + + alertPopupWarning: { + depends: ['alertWarning'], + opacity: 'alertPopup' + }, + alertPopupWarningText: { + depends: ['alertWarningText'], + layer: 'popover', + variant: 'alertPopupWarning', + textColor: true + }, + + alertPopupNeutral: { + depends: ['alertNeutral'], + opacity: 'alertPopup' + }, + alertPopupNeutralText: { + depends: ['alertNeutralText'], + layer: 'popover', + variant: 'alertPopupNeutral', + textColor: true + }, + badgeNotification: '--cRed', badgeNotificationText: { depends: ['text', 'badgeNotification'], -- cgit v1.2.3-70-g09d2 From de291e2e33f1d9e04b27ed30ba3b012d73178e63 Mon Sep 17 00:00:00 2001 From: Eugenij Date: Fri, 3 Jul 2020 19:45:49 +0000 Subject: Add bookmarks Co-authored-by: jared --- CHANGELOG.md | 1 + package.json | 1 + src/boot/routes.js | 2 + .../bookmark_timeline/bookmark_timeline.js | 17 +++++++++ .../bookmark_timeline/bookmark_timeline.vue | 9 +++++ src/components/extra_buttons/extra_buttons.js | 10 +++++ src/components/extra_buttons/extra_buttons.vue | 16 ++++++++ src/components/nav_panel/nav_panel.vue | 5 +++ src/components/side_drawer/side_drawer.vue | 8 ++++ src/components/timeline/timeline.js | 2 +- src/i18n/en.json | 6 ++- src/i18n/ru.json | 7 +++- src/modules/statuses.js | 43 ++++++++++++++++++---- src/services/api/api.service.js | 34 +++++++++++++++-- .../entity_normalizer/entity_normalizer.service.js | 16 ++++++++ .../notifications_fetcher.service.js | 2 +- .../timeline_fetcher/timeline_fetcher.service.js | 17 +++++---- static/fontello.json | 12 ++++++ .../entity_normalizer/entity_normalizer.spec.js | 22 ++++++++++- yarn.lock | 7 ++++ 20 files changed, 213 insertions(+), 24 deletions(-) create mode 100644 src/components/bookmark_timeline/bookmark_timeline.js create mode 100644 src/components/bookmark_timeline/bookmark_timeline.vue mode change 100755 => 100644 static/fontello.json (limited to 'src/components') diff --git a/CHANGELOG.md b/CHANGELOG.md index d978d362..2595af1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -99,6 +99,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Ability to change user's email - About page - Added remote user redirect +- Bookmarks ### Changed - changed the way fading effects for user profile/long statuses works, now uses css-mask instead of gradient background hacks which weren't exactly compatible with semi-transparent themes ### Fixed diff --git a/package.json b/package.json index c0665f6e..96231171 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "cropperjs": "^1.4.3", "diff": "^3.0.1", "escape-html": "^1.0.3", + "parse-link-header": "^1.0.1", "localforage": "^1.5.0", "phoenix": "^1.3.0", "portal-vue": "^2.1.4", diff --git a/src/boot/routes.js b/src/boot/routes.js index d98a3b50..f63d8adf 100644 --- a/src/boot/routes.js +++ b/src/boot/routes.js @@ -2,6 +2,7 @@ import PublicTimeline from 'components/public_timeline/public_timeline.vue' import PublicAndExternalTimeline from 'components/public_and_external_timeline/public_and_external_timeline.vue' import FriendsTimeline from 'components/friends_timeline/friends_timeline.vue' import TagTimeline from 'components/tag_timeline/tag_timeline.vue' +import BookmarkTimeline from 'components/bookmark_timeline/bookmark_timeline.vue' import ConversationPage from 'components/conversation-page/conversation-page.vue' import Interactions from 'components/interactions/interactions.vue' import DMs from 'components/dm_timeline/dm_timeline.vue' @@ -40,6 +41,7 @@ export default (store) => { { name: 'public-timeline', path: '/main/public', component: PublicTimeline }, { name: 'friends', path: '/main/friends', component: FriendsTimeline, beforeEnter: validateAuthenticatedRoute }, { name: 'tag-timeline', path: '/tag/:tag', component: TagTimeline }, + { name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline }, { name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } }, { name: 'remote-user-profile-acct', path: '/remote-users/(@?):username([^/@]+)@:hostname([^/@]+)', diff --git a/src/components/bookmark_timeline/bookmark_timeline.js b/src/components/bookmark_timeline/bookmark_timeline.js new file mode 100644 index 00000000..64b69e5d --- /dev/null +++ b/src/components/bookmark_timeline/bookmark_timeline.js @@ -0,0 +1,17 @@ +import Timeline from '../timeline/timeline.vue' + +const Bookmarks = { + computed: { + timeline () { + return this.$store.state.statuses.timelines.bookmarks + } + }, + components: { + Timeline + }, + destroyed () { + this.$store.commit('clearTimeline', { timeline: 'bookmarks' }) + } +} + +export default Bookmarks diff --git a/src/components/bookmark_timeline/bookmark_timeline.vue b/src/components/bookmark_timeline/bookmark_timeline.vue new file mode 100644 index 00000000..8da6884b --- /dev/null +++ b/src/components/bookmark_timeline/bookmark_timeline.vue @@ -0,0 +1,9 @@ + + + diff --git a/src/components/extra_buttons/extra_buttons.js b/src/components/extra_buttons/extra_buttons.js index e4b19d01..5e0c36bb 100644 --- a/src/components/extra_buttons/extra_buttons.js +++ b/src/components/extra_buttons/extra_buttons.js @@ -34,6 +34,16 @@ const ExtraButtons = { navigator.clipboard.writeText(this.statusLink) .then(() => this.$emit('onSuccess')) .catch(err => this.$emit('onError', err.error.error)) + }, + bookmarkStatus () { + this.$store.dispatch('bookmark', { id: this.status.id }) + .then(() => this.$emit('onSuccess')) + .catch(err => this.$emit('onError', err.error.error)) + }, + unbookmarkStatus () { + this.$store.dispatch('unbookmark', { id: this.status.id }) + .then(() => this.$emit('onSuccess')) + .catch(err => this.$emit('onError', err.error.error)) } }, computed: { diff --git a/src/components/extra_buttons/extra_buttons.vue b/src/components/extra_buttons/extra_buttons.vue index 68db6fd8..7a4e8642 100644 --- a/src/components/extra_buttons/extra_buttons.vue +++ b/src/components/extra_buttons/extra_buttons.vue @@ -40,6 +40,22 @@ > {{ $t("status.unpin") }} + +