diff options
| author | Shpuld Shpuldson <shpuld@shpposter.club> | 2020-01-26 15:59:59 +0200 |
|---|---|---|
| committer | Shpuld Shpuldson <shpuld@shpposter.club> | 2020-01-26 15:59:59 +0200 |
| commit | c4beac5f894642e64f2818e43697b472b7a70847 (patch) | |
| tree | b5e64b7f4f19b8b15549b0b29e876e8eea724c16 /src | |
| parent | 7cfe1b05e8d16fcbb6eab3b42f19e464d57ea35b (diff) | |
| parent | b0b0fc403a57dca6837bc99a87c66609156af2b9 (diff) | |
Merge branch 'develop' into feat/emoji-reactions
Diffstat (limited to 'src')
24 files changed, 332 insertions, 78 deletions
diff --git a/src/boot/after_store.js b/src/boot/after_store.js index 228a0497..0bb1b2b4 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -185,12 +185,9 @@ const getAppSecret = async ({ store }) => { }) } -const resolveStaffAccounts = async ({ store, accounts }) => { - const backendInteractor = store.state.api.backendInteractor - let nicknames = accounts.map(uri => uri.split('/').pop()) - .map(id => backendInteractor.fetchUser({ id })) - nicknames = await Promise.all(nicknames) - +const resolveStaffAccounts = ({ store, accounts }) => { + const nicknames = accounts.map(uri => uri.split('/').pop()) + nicknames.map(nickname => store.dispatch('fetchUser', nickname)) store.dispatch('setInstanceOption', { name: 'staffAccounts', value: nicknames }) } @@ -236,7 +233,7 @@ const getNodeInfo = async ({ store }) => { }) const accounts = metadata.staffAccounts - await resolveStaffAccounts({ store, accounts }) + resolveStaffAccounts({ store, accounts }) } else { throw (res) } diff --git a/src/components/domain_mute_card/domain_mute_card.js b/src/components/domain_mute_card/domain_mute_card.js new file mode 100644 index 00000000..c8e838ba --- /dev/null +++ b/src/components/domain_mute_card/domain_mute_card.js @@ -0,0 +1,15 @@ +import ProgressButton from '../progress_button/progress_button.vue' + +const DomainMuteCard = { + props: ['domain'], + components: { + ProgressButton + }, + methods: { + unmuteDomain () { + return this.$store.dispatch('unmuteDomain', this.domain) + } + } +} + +export default DomainMuteCard diff --git a/src/components/domain_mute_card/domain_mute_card.vue b/src/components/domain_mute_card/domain_mute_card.vue new file mode 100644 index 00000000..567d81c5 --- /dev/null +++ b/src/components/domain_mute_card/domain_mute_card.vue @@ -0,0 +1,38 @@ +<template> + <div class="domain-mute-card"> + <div class="domain-mute-card-domain"> + {{ domain }} + </div> + <ProgressButton + :click="unmuteDomain" + class="btn btn-default" + > + {{ $t('domain_mute_card.unmute') }} + <template slot="progress"> + {{ $t('domain_mute_card.unmute_progress') }} + </template> + </ProgressButton> + </div> +</template> + +<script src="./domain_mute_card.js"></script> + +<style lang="scss"> +.domain-mute-card { + flex: 1 0; + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.6em 1em 0.6em 0; + + &-domain { + margin-right: 1em; + overflow: hidden; + text-overflow: ellipsis; + } + + button { + width: 10em; + } +} +</style> diff --git a/src/components/nav_panel/nav_panel.js b/src/components/nav_panel/nav_panel.js index d9268585..8f7edb7f 100644 --- a/src/components/nav_panel/nav_panel.js +++ b/src/components/nav_panel/nav_panel.js @@ -3,7 +3,7 @@ import { mapState } from 'vuex' const NavPanel = { created () { if (this.currentUser && this.currentUser.locked) { - this.$store.dispatch('startFetchingFollowRequest') + this.$store.dispatch('startFetchingFollowRequests') } }, computed: mapState({ diff --git a/src/components/nav_panel/nav_panel.vue b/src/components/nav_panel/nav_panel.vue index 034259d9..0f3296eb 100644 --- a/src/components/nav_panel/nav_panel.vue +++ b/src/components/nav_panel/nav_panel.vue @@ -33,7 +33,7 @@ <i class="button-icon icon-users" /> {{ $t("nav.public_tl") }} </router-link> </li> - <li v-if="federating && !privateMode"> + <li v-if="federating && (currentUser || !privateMode)"> <router-link :to="{ name: 'public-external-timeline' }"> <i class="button-icon icon-globe" /> {{ $t("nav.twkn") }} </router-link> diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js index a89c0cdc..26ffbab6 100644 --- a/src/components/notifications/notifications.js +++ b/src/components/notifications/notifications.js @@ -2,10 +2,12 @@ import Notification from '../notification/notification.vue' import notificationsFetcher from '../../services/notifications_fetcher/notifications_fetcher.service.js' import { notificationsFromStore, - visibleNotificationsFromStore, + filteredNotificationsFromStore, unseenNotificationsFromStore } from '../../services/notification_utils/notification_utils.js' +const DEFAULT_SEEN_TO_DISPLAY_COUNT = 30 + const Notifications = { props: { // Disables display of panel header @@ -18,7 +20,11 @@ const Notifications = { }, data () { return { - bottomedOut: false + bottomedOut: false, + // How many seen notifications to display in the list. The more there are, + // the heavier the page becomes. This count is increased when loading + // older notifications, and cut back to default whenever hitting "Read!". + seenToDisplayCount: DEFAULT_SEEN_TO_DISPLAY_COUNT } }, computed: { @@ -34,14 +40,17 @@ const Notifications = { unseenNotifications () { return unseenNotificationsFromStore(this.$store) }, - visibleNotifications () { - return visibleNotificationsFromStore(this.$store, this.filterMode) + filteredNotifications () { + return filteredNotificationsFromStore(this.$store, this.filterMode) }, unseenCount () { return this.unseenNotifications.length }, loading () { return this.$store.state.statuses.notifications.loading + }, + notificationsToDisplay () { + return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount) } }, components: { @@ -64,12 +73,21 @@ const Notifications = { methods: { markAsSeen () { this.$store.dispatch('markNotificationsAsSeen') + this.seenToDisplayCount = DEFAULT_SEEN_TO_DISPLAY_COUNT }, fetchOlderNotifications () { if (this.loading) { return } + const seenCount = this.filteredNotifications.length - this.unseenCount + if (this.seenToDisplayCount < seenCount) { + this.seenToDisplayCount = Math.min(this.seenToDisplayCount + 20, seenCount) + return + } else if (this.seenToDisplayCount > seenCount) { + this.seenToDisplayCount = seenCount + } + const store = this.$store const credentials = store.state.users.currentUser.credentials store.commit('setNotificationsLoading', { value: true }) @@ -82,6 +100,7 @@ const Notifications = { if (notifs.length === 0) { this.bottomedOut = true } + this.seenToDisplayCount += notifs.length }) } } diff --git a/src/components/notifications/notifications.vue b/src/components/notifications/notifications.vue index c42c35e6..d477a41b 100644 --- a/src/components/notifications/notifications.vue +++ b/src/components/notifications/notifications.vue @@ -32,7 +32,7 @@ </div> <div class="panel-body"> <div - v-for="notification in visibleNotifications" + v-for="notification in notificationsToDisplay" :key="notification.id" class="notification" :class="{"unseen": !minimalMode && !notification.seen}" diff --git a/src/components/registration/registration.js b/src/components/registration/registration.js index 57f3caf0..ace8cc7c 100644 --- a/src/components/registration/registration.js +++ b/src/components/registration/registration.js @@ -63,7 +63,8 @@ const registration = { await this.signUp(this.user) this.$router.push({ name: 'friends' }) } catch (error) { - console.warn('Registration failed: ' + error) + console.warn('Registration failed: ', error) + this.setCaptcha() } } }, diff --git a/src/components/registration/registration.vue b/src/components/registration/registration.vue index 222b67a8..fdbda007 100644 --- a/src/components/registration/registration.vue +++ b/src/components/registration/registration.vue @@ -170,7 +170,7 @@ <label class="form--label" for="captcha-label" - >{{ $t('captcha') }}</label> + >{{ $t('registration.captcha') }}</label> <template v-if="['kocaptcha', 'native'].includes(captcha.type)"> <img diff --git a/src/components/side_drawer/side_drawer.js b/src/components/side_drawer/side_drawer.js index 2534eb8f..2181ecc7 100644 --- a/src/components/side_drawer/side_drawer.js +++ b/src/components/side_drawer/side_drawer.js @@ -12,7 +12,7 @@ const SideDrawer = { this.closeGesture = GestureService.swipeGesture(GestureService.DIRECTION_LEFT, this.toggleDrawer) if (this.currentUser && this.currentUser.locked) { - this.$store.dispatch('startFetchingFollowRequest') + this.$store.dispatch('startFetchingFollowRequests') } }, components: { UserCard }, diff --git a/src/components/side_drawer/side_drawer.vue b/src/components/side_drawer/side_drawer.vue index 3fba9058..28637afc 100644 --- a/src/components/side_drawer/side_drawer.vue +++ b/src/components/side_drawer/side_drawer.vue @@ -88,7 +88,7 @@ </router-link> </li> <li - v-if="federating && !privateMode" + v-if="federating && (currentUser || !privateMode)" @click="toggleDrawer" > <router-link to="/main/all"> diff --git a/src/components/staff_panel/staff_panel.js b/src/components/staff_panel/staff_panel.js index 93e950ad..4f98fff6 100644 --- a/src/components/staff_panel/staff_panel.js +++ b/src/components/staff_panel/staff_panel.js @@ -1,3 +1,4 @@ +import map from 'lodash/map' import BasicUserCard from '../basic_user_card/basic_user_card.vue' const StaffPanel = { @@ -6,7 +7,7 @@ const StaffPanel = { }, computed: { staffAccounts () { - return this.$store.state.instance.staffAccounts + return map(this.$store.state.instance.staffAccounts, nickname => this.$store.getters.findUser(nickname)).filter(_ => _) } } } diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index d5d671e4..1709b48f 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -9,6 +9,7 @@ import ScopeSelector from '../scope_selector/scope_selector.vue' import fileSizeFormatService from '../../services/file_size_format/file_size_format.js' import BlockCard from '../block_card/block_card.vue' import MuteCard from '../mute_card/mute_card.vue' +import DomainMuteCard from '../domain_mute_card/domain_mute_card.vue' import SelectableList from '../selectable_list/selectable_list.vue' import ProgressButton from '../progress_button/progress_button.vue' import EmojiInput from '../emoji_input/emoji_input.vue' @@ -32,6 +33,12 @@ const MuteList = withSubscription({ childPropName: 'items' })(SelectableList) +const DomainMuteList = withSubscription({ + fetch: (props, $store) => $store.dispatch('fetchDomainMutes'), + select: (props, $store) => get($store.state.users.currentUser, 'domainMutes', []), + childPropName: 'items' +})(SelectableList) + const UserSettings = { data () { return { @@ -67,7 +74,8 @@ const UserSettings = { changedPassword: false, changePasswordError: false, activeTab: 'profile', - notificationSettings: this.$store.state.users.currentUser.notification_settings + notificationSettings: this.$store.state.users.currentUser.notification_settings, + newDomainToMute: '' } }, created () { @@ -80,10 +88,12 @@ const UserSettings = { ImageCropper, BlockList, MuteList, + DomainMuteList, EmojiInput, Autosuggest, BlockCard, MuteCard, + DomainMuteCard, ProgressButton, Importer, Exporter, @@ -365,6 +375,13 @@ const UserSettings = { unmuteUsers (ids) { return this.$store.dispatch('unmuteUsers', ids) }, + unmuteDomains (domains) { + return this.$store.dispatch('unmuteDomains', domains) + }, + muteDomain () { + return this.$store.dispatch('muteDomain', this.newDomainToMute) + .then(() => { this.newDomainToMute = '' }) + }, identity (value) { return value } diff --git a/src/components/user_settings/user_settings.vue b/src/components/user_settings/user_settings.vue index 3f1982a6..2222c293 100644 --- a/src/components/user_settings/user_settings.vue +++ b/src/components/user_settings/user_settings.vue @@ -509,59 +509,114 @@ </div> <div :label="$t('settings.mutes_tab')"> - <div class="profile-edit-usersearch-wrapper"> - <Autosuggest - :filter="filterUnMutedUsers" - :query="queryUserIds" - :placeholder="$t('settings.search_user_to_mute')" - > - <MuteCard - slot-scope="row" - :user-id="row.item" - /> - </Autosuggest> - </div> - <MuteList - :refresh="true" - :get-key="identity" - > - <template - slot="header" - slot-scope="{selected}" - > - <div class="profile-edit-bulk-actions"> - <ProgressButton - v-if="selected.length > 0" - class="btn btn-default" - :click="() => muteUsers(selected)" + <tab-switcher> + <div label="Users"> + <div class="profile-edit-usersearch-wrapper"> + <Autosuggest + :filter="filterUnMutedUsers" + :query="queryUserIds" + :placeholder="$t('settings.search_user_to_mute')" + > + <MuteCard + slot-scope="row" + :user-id="row.item" + /> + </Autosuggest> + </div> + <MuteList + :refresh="true" + :get-key="identity" + > + <template + slot="header" + slot-scope="{selected}" + > + <div class="profile-edit-bulk-actions"> + <ProgressButton + v-if="selected.length > 0" + class="btn btn-default" + :click="() => muteUsers(selected)" + > + {{ $t('user_card.mute') }} + <template slot="progress"> + {{ $t('user_card.mute_progress') }} + </template> + </ProgressButton> + <ProgressButton + v-if="selected.length > 0" + class="btn btn-default" + :click="() => unmuteUsers(selected)" + > + {{ $t('user_card.unmute') }} + <template slot="progress"> + {{ $t('user_card.unmute_progress') }} + </template> + </ProgressButton> + </div> + </template> + <template + slot="item" + slot-scope="{item}" + > + <MuteCard :user-id="item" /> + </template> + <template slot="empty"> + {{ $t('settings.no_mutes') }} + </template> + </MuteList> + </div> + + <div :label="$t('settings.domain_mutes')"> + <div class="profile-edit-domain-mute-form"> + <input + v-model="newDomainToMute" + :placeholder="$t('settings.type_domains_to_mute')" + type="text" + @keyup.enter="muteDomain" > - {{ $t('user_card.mute') }} - <template slot="progress"> - {{ $t('user_card.mute_progress') }} - </template> - </ProgressButton> <ProgressButton - v-if="selected.length > 0" class="btn btn-default" - :click="() => unmuteUsers(selected)" + :click="muteDomain" > - {{ $t('user_card.unmute') }} + {{ $t('domain_mute_card.mute') }} <template slot="progress"> - {{ $t('user_card.unmute_progress') }} + {{ $t('domain_mute_card.mute_progress') }} </template> </ProgressButton> </div> - </template> - <template - slot="item" - slot-scope="{item}" - > - <MuteCard :user-id="item" /> - </template> - <template slot="empty"> - {{ $t('settings.no_mutes') }} - </template> - </MuteList> + <DomainMuteList + :refresh="true" + :get-key="identity" + > + <template + slot="header" + slot-scope="{selected}" + > + <div class="profile-edit-bulk-actions"> + <ProgressButton + v-if="selected.length > 0" + class="btn btn-default" + :click="() => unmuteDomains(selected)" + > + {{ $t('domain_mute_card.unmute') }} + <template slot="progress"> + {{ $t('domain_mute_card.unmute_progress') }} + </template> + </ProgressButton> + </div> + </template> + <template + slot="item" + slot-scope="{item}" + > + <DomainMuteCard :domain="item" /> + </template> + <template slot="empty"> + {{ $t('settings.no_mutes') }} + </template> + </DomainMuteList> + </div> + </tab-switcher> </div> </tab-switcher> </div> @@ -639,6 +694,18 @@ } } + &-domain-mute-form { + padding: 1em; + display: flex; + flex-direction: column; + + button { + align-self: flex-end; + margin-top: 1em; + width: 10em; + } + } + .setting-subitem { margin-left: 1.75em; } diff --git a/src/i18n/en.json b/src/i18n/en.json index c840fe6d..db2ce54d 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -21,6 +21,12 @@ "chat": { "title": "Chat" }, + "domain_mute_card": { + "mute": "Mute", + "mute_progress": "Muting...", + "unmute": "Unmute", + "unmute_progress": "Unmuting..." + }, "exporter": { "export": "Export", "processing": "Processing, you'll soon be asked to download your file" @@ -264,6 +270,7 @@ "delete_account_error": "There was an issue deleting your account. If this persists please contact your instance administrator.", "delete_account_instructions": "Type your password in the input below to confirm account deletion.", "discoverable": "Allow discovery of this account in search results and other services", + "domain_mutes": "Domains", "avatar_size_instruction": "The recommended minimum size for avatar images is 150x150 pixels.", "pad_emoji": "Pad emoji with spaces when adding from picker", "export_theme": "Save preset", @@ -361,6 +368,7 @@ "post_status_content_type": "Post status content type", "stop_gifs": "Play-on-hover GIFs", "streaming": "Enable automatic streaming of new posts when scrolled to the top", + "user_mutes": "Users", "useStreamingApi": "Receive posts and notifications real-time", "useStreamingApiWarning": "(Not recommended, experimental, known to skip posts)", "text": "Text", @@ -369,6 +377,7 @@ "theme_help_v2_1": "You can also override certain component's colors and opacity by toggling the checkbox, use \"Clear all\" button to clear all overrides.", "theme_help_v2_2": "Icons underneath some entries are background/text contrast indicators, hover over for detailed info. Please keep in mind that when using transparency contrast indicators show the worst possible case.", "tooltipRadius": "Tooltips/alerts", + "type_domains_to_mute": "Type in domains to mute", "upload_a_photo": "Upload a photo", "user_settings": "User Settings", "values": { diff --git a/src/lib/event_target_polyfill.js b/src/lib/event_target_polyfill.js new file mode 100644 index 00000000..2042c770 --- /dev/null +++ b/src/lib/event_target_polyfill.js @@ -0,0 +1,9 @@ +import EventTargetPolyfill from '@ungap/event-target' + +try { + /* eslint-disable no-new */ + new EventTarget() + /* eslint-enable no-new */ +} catch (e) { + window.EventTarget = EventTargetPolyfill +} diff --git a/src/main.js b/src/main.js index a9db1cff..baf73ac8 100644 --- a/src/main.js +++ b/src/main.js @@ -2,6 +2,9 @@ import Vue from 'vue' import VueRouter from 'vue-router' import Vuex from 'vuex' +import 'custom-event-polyfill' +import './lib/event_target_polyfill.js' + import interfaceModule from './modules/interface.js' import instanceModule from './modules/instance.js' import statusesModule from './modules/statuses.js' diff --git a/src/modules/api.js b/src/modules/api.js index 9c296275..748570e5 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -146,6 +146,7 @@ const api = { startFetchingFollowRequests (store) { if (store.state.fetchers['followRequests']) return const fetcher = store.state.backendInteractor.startFetchingFollowRequests({ store }) + store.commit('addFetcher', { fetcherName: 'followRequests', fetcher }) }, stopFetchingFollowRequests (store) { diff --git a/src/modules/users.js b/src/modules/users.js index 84fa0255..ce3e595d 100644 --- a/src/modules/users.js +++ b/src/modules/users.js @@ -72,6 +72,16 @@ const showReblogs = (store, userId) => { .then((relationship) => store.commit('updateUserRelationship', [relationship])) } +const muteDomain = (store, domain) => { + return store.rootState.api.backendInteractor.muteDomain({ domain }) + .then(() => store.commit('addDomainMute', domain)) +} + +const unmuteDomain = (store, domain) => { + return store.rootState.api.backendInteractor.unmuteDomain({ domain }) + .then(() => store.commit('removeDomainMute', domain)) +} + export const mutations = { setMuted (state, { user: { id }, muted }) { const user = state.usersObject[id] @@ -177,6 +187,20 @@ export const mutations = { state.currentUser.muteIds.push(muteId) } }, + saveDomainMutes (state, domainMutes) { + state.currentUser.domainMutes = domainMutes + }, + addDomainMute (state, domain) { + if (state.currentUser.domainMutes.indexOf(domain) === -1) { + state.currentUser.domainMutes.push(domain) + } + }, + removeDomainMute (state, domain) { + const index = state.currentUser.domainMutes.indexOf(domain) + if (index !== -1) { + state.currentUser.domainMutes.splice(index, 1) + } + }, setPinnedToUser (state, status) { const user = state.usersObject[status.user.id] const index = user.pinnedStatusIds.indexOf(status.id) @@ -297,6 +321,25 @@ const users = { unmuteUsers (store, ids = []) { return Promise.all(ids.map(id => unmuteUser(store, id))) }, + fetchDomainMutes (store) { + return store.rootState.api.backendInteractor.fetchDomainMutes() + .then((domainMutes) => { + store.commit('saveDomainMutes', domainMutes) + return domainMutes + }) + }, + muteDomain (store, domain) { + return muteDomain(store, domain) + }, + unmuteDomain (store, domain) { + return unmuteDomain(store, domain) + }, + muteDomains (store, domains = []) { + return Promise.all(domains.map(domain => muteDomain(store, domain))) + }, + unmuteDomains (store, domain = []) { + return Promise.all(domain.map(domain => unmuteDomain(store, domain))) + }, fetchFriends ({ rootState, commit }, id) { const user = rootState.users.usersObject[id] const maxId = last(user.friendIds) @@ -401,7 +444,9 @@ const users = { let rootState = store.rootState try { - let data = await rootState.api.backendInteractor.register({ ...userInfo }) + let data = await rootState.api.backendInteractor.register( + { params: { ...userInfo } } + ) store.commit('signUpSuccess') store.commit('setToken', data.access_token) store.dispatch('loginUser', data.access_token) @@ -458,6 +503,7 @@ const users = { user.credentials = accessToken user.blockIds = [] user.muteIds = [] + user.domainMutes = [] commit('setCurrentUser', user) commit('addNewUsers', [user]) diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 783c2696..aa31f123 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -72,6 +72,7 @@ const MASTODON_MUTE_CONVERSATION = id => `/api/v1/statuses/${id}/mute` const MASTODON_UNMUTE_CONVERSATION = id => `/api/v1/statuses/${id}/unmute` const MASTODON_SEARCH_2 = `/api/v2/search` const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search' +const MASTODON_DOMAIN_BLOCKS_URL = '/api/v1/domain_blocks' const MASTODON_STREAMING = '/api/v1/streaming' const PLEROMA_EMOJI_REACTIONS_URL = id => `/api/v1/pleroma/statuses/${id}/emoji_reactions_by` const PLEROMA_EMOJI_REACT_URL = id => `/api/v1/pleroma/statuses/${id}/react_with_emoji` @@ -973,6 +974,28 @@ const search2 = ({ credentials, q, resolve, limit, offset, following }) => { }) } +const fetchDomainMutes = ({ credentials }) => { + return promisedRequest({ url: MASTODON_DOMAIN_BLOCKS_URL, credentials }) +} + +const muteDomain = ({ domain, credentials }) => { + return promisedRequest({ + url: MASTODON_DOMAIN_BLOCKS_URL, + method: 'POST', + payload: { domain }, + credentials + }) +} + +const unmuteDomain = ({ domain, credentials }) => { + return promisedRequest({ + url: MASTODON_DOMAIN_BLOCKS_URL, + method: 'DELETE', + payload: { domain }, + credentials + }) +} + export const getMastodonSocketURI = ({ credentials, stream, args = {} }) => { return Object.entries({ ...(credentials @@ -1138,7 +1161,10 @@ const apiService = { reportUser, updateNotificationSettings, search2, - searchUsers + searchUsers, + fetchDomainMutes, + muteDomain, + unmuteDomain } export default apiService diff --git a/src/services/backend_interactor_service/backend_interactor_service.js b/src/services/backend_interactor_service/backend_interactor_service.js index b7372ed0..e1c32860 100644 --- a/src/services/backend_interactor_service/backend_interactor_service.js +++ b/src/services/backend_interactor_service/backend_interactor_service.js @@ -16,7 +16,7 @@ const backendInteractorService = credentials => ({ return notificationsFetcher.fetchAndUpdate({ store, credentials }) }, - startFetchingFollowRequest ({ store }) { + startFetchingFollowRequests ({ store }) { return followRequestFetcher.startFetching({ store, credentials }) }, diff --git a/src/services/errors/errors.js b/src/services/errors/errors.js index 590552da..d4cf9132 100644 --- a/src/services/errors/errors.js +++ b/src/services/errors/errors.js @@ -32,12 +32,18 @@ export class RegistrationError extends Error { } if (typeof error === 'object') { + const errorContents = JSON.parse(error.error) + // keys will have the property that has the error, for example 'ap_id', + // 'email' or 'captcha', the value will be an array of its error + // like "ap_id": ["has been taken"] or "captcha": ["Invalid CAPTCHA"] + // replace ap_id with username - if (error.ap_id) { - error.username = error.ap_id - delete error.ap_id + if (errorContents.ap_id) { + errorContents.username = errorContents.ap_id + delete errorContents.ap_id } - this.message = humanizeErrors(error) + + this.message = humanizeErrors(errorContents) } else { this.message = error } diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index b08514da..860620fc 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -26,7 +26,7 @@ const sortById = (a, b) => { } } -export const visibleNotificationsFromStore = (store, types) => { +export const filteredNotificationsFromStore = (store, types) => { // map is just to clone the array since sort mutates it and it causes some issues let sortedNotifications = notificationsFromStore(store).map(_ => _).sort(sortById) sortedNotifications = sortBy(sortedNotifications, 'seen') @@ -36,4 +36,4 @@ export const visibleNotificationsFromStore = (store, types) => { } export const unseenNotificationsFromStore = store => - filter(visibleNotificationsFromStore(store), ({ seen }) => !seen) + filter(filteredNotificationsFromStore(store), ({ seen }) => !seen) diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js index 47008026..64499a1b 100644 --- a/src/services/notifications_fetcher/notifications_fetcher.service.js +++ b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -2,7 +2,6 @@ import apiService from '../api/api.service.js' const update = ({ store, notifications, older }) => { store.dispatch('setNotificationsError', { value: false }) - store.dispatch('addNewNotifications', { notifications, older }) } @@ -30,9 +29,9 @@ const fetchAndUpdate = ({ store, credentials, older = false }) => { // load unread notifications repeatedly to provide consistency between browser tabs const notifications = timelineData.data - const unread = notifications.filter(n => !n.seen).map(n => n.id) - if (unread.length) { - args['since'] = Math.min(...unread) + const readNotifsIds = notifications.filter(n => n.seen).map(n => n.id) + if (readNotifsIds.length) { + args['since'] = Math.max(...readNotifsIds) fetchNotifications({ store, args, older }) } |
