From 4398e520ed6c777b40957e6178acde268c4b0daf Mon Sep 17 00:00:00 2001 From: Zhiyuan Zheng Date: Sat, 28 May 2022 19:24:08 +0200 Subject: [PATCH] Refine notifications https://github.com/tooot-app/app/issues/306 https://github.com/tooot-app/app/issues/305 This one uses the positive filtering that is added since v3.5, that a such a filter won't be shown as there is no way to check if a user is an admin or not and showing a useless option for majority users won't be a good experience. --- src/@types/mastodon.d.ts | 1 + src/components/Instance/Auth.tsx | 5 +- src/components/Timeline/Shared/Actioned.tsx | 30 ++++--- src/helpers/features.json | 15 ++++ src/i18n/en/components/timeline.json | 3 +- src/i18n/en/screens/actions.json | 4 +- src/screens/Actions/NotificationsFilter.tsx | 56 +++++++++---- src/screens/Tabs/Me/Switch.tsx | 9 +-- src/startup/sentry.ts | 3 +- src/store.ts | 2 +- src/utils/initQuery.ts | 5 +- src/utils/migrations/instances/migration.ts | 17 ++++ src/utils/migrations/instances/v10.ts | 81 +++++++++++++++++++ src/utils/push/useConnect.ts | 5 +- src/utils/push/useReceive.ts | 4 +- src/utils/push/useRespond.ts | 4 +- src/utils/queryHooks/timeline.ts | 25 ++++-- src/utils/slices/instances/add.ts | 14 ++-- src/utils/slices/instances/push/register.ts | 5 +- src/utils/slices/instances/remove.ts | 4 +- src/utils/slices/instances/updatePush.ts | 4 +- src/utils/slices/instances/updatePushAlert.ts | 8 +- .../slices/instances/updatePushDecode.ts | 5 +- src/utils/slices/instancesSlice.ts | 31 ++++--- 24 files changed, 254 insertions(+), 86 deletions(-) create mode 100644 src/utils/migrations/instances/v10.ts diff --git a/src/@types/mastodon.d.ts b/src/@types/mastodon.d.ts index 2e1663f7..1a62f519 100644 --- a/src/@types/mastodon.d.ts +++ b/src/@types/mastodon.d.ts @@ -341,6 +341,7 @@ declare namespace Mastodon { | 'favourite' | 'poll' | 'status' + | 'update' created_at: string account: Account diff --git a/src/components/Instance/Auth.tsx b/src/components/Instance/Auth.tsx index 2418bb49..16af0428 100644 --- a/src/components/Instance/Auth.tsx +++ b/src/components/Instance/Auth.tsx @@ -1,8 +1,9 @@ import { useNavigation } from '@react-navigation/native' import { useAppDispatch } from '@root/store' +import { InstanceLatest } from '@utils/migrations/instances/migration' import { TabMeStackNavigationProp } from '@utils/navigation/navigators' import addInstance from '@utils/slices/instances/add' -import { checkInstanceFeature, Instance } from '@utils/slices/instancesSlice' +import { checkInstanceFeature } from '@utils/slices/instancesSlice' import * as AuthSession from 'expo-auth-session' import React, { useEffect } from 'react' import { useQueryClient } from 'react-query' @@ -12,7 +13,7 @@ export interface Props { instanceDomain: string // Domain can be different than uri instance: Mastodon.Instance - appData: Instance['appData'] + appData: InstanceLatest['appData'] goBack?: boolean } diff --git a/src/components/Timeline/Shared/Actioned.tsx b/src/components/Timeline/Shared/Actioned.tsx index 9b600d2f..0ff986e3 100644 --- a/src/components/Timeline/Shared/Actioned.tsx +++ b/src/components/Timeline/Shared/Actioned.tsx @@ -34,7 +34,7 @@ const TimelineActioned = React.memo( navigation.push('Tab-Shared-Account', { account }) }, []) - const children = useMemo(() => { + const children = () => { switch (action) { case 'pinned': return ( @@ -48,7 +48,6 @@ const TimelineActioned = React.memo( {content(t('shared.actioned.pinned'))} ) - break case 'favourite': return ( <> @@ -63,7 +62,6 @@ const TimelineActioned = React.memo( ) - break case 'follow': return ( <> @@ -78,7 +76,6 @@ const TimelineActioned = React.memo( ) - break case 'follow_request': return ( <> @@ -93,7 +90,6 @@ const TimelineActioned = React.memo( ) - break case 'poll': return ( <> @@ -106,7 +102,6 @@ const TimelineActioned = React.memo( {content(t('shared.actioned.poll'))} ) - break case 'reblog': return ( <> @@ -125,7 +120,6 @@ const TimelineActioned = React.memo( ) - break case 'status': return ( <> @@ -140,9 +134,22 @@ const TimelineActioned = React.memo( ) - break + case 'update': + return ( + <> + + {content(t('shared.actioned.update'))} + + ) + default: + return <> } - }, []) + } return ( + > + {children()} + ) }, () => true diff --git a/src/helpers/features.json b/src/helpers/features.json index 73437eec..84241975 100644 --- a/src/helpers/features.json +++ b/src/helpers/features.json @@ -8,5 +8,20 @@ "feature": "deprecate_auth_follow", "version": 3.5, "reference": "https://github.com/mastodon/mastodon/releases/tag/v3.5.0" + }, + { + "feature": "notification_type_status", + "version": 3.3, + "reference": "https://docs.joinmastodon.org/entities/notification/#required-attributes" + }, + { + "feature": "notification_type_update", + "version": 3.5, + "reference": "https://github.com/mastodon/mastodon/releases/tag/v3.5.0" + }, + { + "feature": "notification_types_positive_filter", + "version": 3.5, + "reference": "https://github.com/mastodon/mastodon/releases/tag/v3.5.0" } ] \ No newline at end of file diff --git a/src/i18n/en/components/timeline.json b/src/i18n/en/components/timeline.json index a06addd8..caeb15ed 100644 --- a/src/i18n/en/components/timeline.json +++ b/src/i18n/en/components/timeline.json @@ -29,7 +29,8 @@ "reblog": { "default": "{{name}} boosted", "notification": "{{name}} boosted your toot" - } + }, + "update": "Reblog has been edited" }, "actions": { "reply": { diff --git a/src/i18n/en/screens/actions.json b/src/i18n/en/screens/actions.json index 14a46aaf..f5f2a7c5 100644 --- a/src/i18n/en/screens/actions.json +++ b/src/i18n/en/screens/actions.json @@ -8,11 +8,13 @@ "heading": "Show notification types", "content": { "follow": "$t(screenTabs:me.push.follow.heading)", + "follow_request": "Follow request", "favourite": "$t(screenTabs:me.push.favourite.heading)", "reblog": "$t(screenTabs:me.push.reblog.heading)", "mention": "$t(screenTabs:me.push.mention.heading)", "poll": "$t(screenTabs:me.push.poll.heading)", - "follow_request": "Follow request" + "status": "Toot from subscribed users", + "update": "Reblog has been edited" } } } diff --git a/src/screens/Actions/NotificationsFilter.tsx b/src/screens/Actions/NotificationsFilter.tsx index 5bf31102..43f96741 100644 --- a/src/screens/Actions/NotificationsFilter.tsx +++ b/src/screens/Actions/NotificationsFilter.tsx @@ -4,6 +4,7 @@ import MenuHeader from '@components/Menu/Header' import MenuRow from '@components/Menu/Row' import { useNavigation } from '@react-navigation/native' import { + checkInstanceFeature, getInstanceNotificationsFilter, updateInstanceNotificationsFilter } from '@utils/slices/instancesSlice' @@ -33,42 +34,63 @@ const ActionsNotificationsFilter: React.FC = () => { return null } + const hasTypeStatus = useSelector( + checkInstanceFeature('notification_type_status') + ) + const hasTypeUpdate = useSelector( + checkInstanceFeature('notification_type_update') + ) const options = useMemo(() => { return ( instanceNotificationsFilter && ( [ 'follow', + 'follow_request', 'favourite', 'reblog', 'mention', 'poll', - 'follow_request' + 'status', + 'update' ] as [ 'follow', + 'follow_request', 'favourite', 'reblog', 'mention', 'poll', - 'follow_request' + 'status', + 'update' ] - ).map(type => ( - - dispatch( - updateInstanceNotificationsFilter({ - ...instanceNotificationsFilter, - [type]: !instanceNotificationsFilter[type] - }) - ) + ) + .filter(type => { + switch (type) { + case 'status': + return hasTypeStatus + case 'update': + return hasTypeUpdate + default: + return true } - /> - )) + }) + .map(type => ( + + dispatch( + updateInstanceNotificationsFilter({ + ...instanceNotificationsFilter, + [type]: !instanceNotificationsFilter[type] + }) + ) + } + /> + )) ) - }, [instanceNotificationsFilter]) + }, [instanceNotificationsFilter, hasTypeStatus, hasTypeUpdate]) return ( <> diff --git a/src/screens/Tabs/Me/Switch.tsx b/src/screens/Tabs/Me/Switch.tsx index 8df269a6..b345ff98 100644 --- a/src/screens/Tabs/Me/Switch.tsx +++ b/src/screens/Tabs/Me/Switch.tsx @@ -5,11 +5,8 @@ import ComponentInstance from '@components/Instance' import CustomText from '@components/Text' import { useNavigation } from '@react-navigation/native' import initQuery from '@utils/initQuery' -import { - getInstanceActive, - getInstances, - Instance -} from '@utils/slices/instancesSlice' +import { InstanceLatest } from '@utils/migrations/instances/migration' +import { getInstanceActive, getInstances } from '@utils/slices/instancesSlice' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import React, { useEffect, useRef } from 'react' @@ -19,7 +16,7 @@ import { ScrollView } from 'react-native-gesture-handler' import { useSelector } from 'react-redux' interface Props { - instance: Instance + instance: InstanceLatest selected?: boolean } diff --git a/src/startup/sentry.ts b/src/startup/sentry.ts index 7d398c66..52e543e8 100644 --- a/src/startup/sentry.ts +++ b/src/startup/sentry.ts @@ -1,4 +1,3 @@ -import { isRelease } from '@utils/checkEnvironment' import * as Sentry from 'sentry-expo' import log from './log' @@ -7,7 +6,7 @@ const sentry = () => { Sentry.init({ dsn: 'https://53348b60ff844d52886e90251b3a5f41@o917354.ingest.sentry.io/6410576', enableInExpoDevelopment: false, - debug: !isRelease, + // debug: !isRelease, autoSessionTracking: true }) } diff --git a/src/store.ts b/src/store.ts index 8e6e9e04..81a06675 100644 --- a/src/store.ts +++ b/src/store.ts @@ -39,7 +39,7 @@ const instancesPersistConfig = { key: 'instances', prefix, storage: Platform.OS === 'ios' ? secureStorage : AsyncStorage, - version: 9, + version: 10, // @ts-ignore migrate: createMigrate(instancesMigration) } diff --git a/src/utils/initQuery.ts b/src/utils/initQuery.ts index 22ea7bfb..f51dcba0 100644 --- a/src/utils/initQuery.ts +++ b/src/utils/initQuery.ts @@ -1,13 +1,14 @@ import queryClient from '@helpers/queryClient' import { store } from '@root/store' +import { InstanceLatest } from './migrations/instances/migration' // import { prefetchTimelineQuery } from './queryHooks/timeline' -import { Instance, updateInstanceActive } from './slices/instancesSlice' +import { updateInstanceActive } from './slices/instancesSlice' const initQuery = async ({ instance, prefetch }: { - instance: Instance + instance: InstanceLatest prefetch?: { enabled: boolean; page?: 'Following' | 'LocalPublic' } }) => { store.dispatch(updateInstanceActive(instance)) diff --git a/src/utils/migrations/instances/migration.ts b/src/utils/migrations/instances/migration.ts index f7079c88..eadcf4d4 100644 --- a/src/utils/migrations/instances/migration.ts +++ b/src/utils/migrations/instances/migration.ts @@ -5,6 +5,7 @@ import { InstanceV6 } from './v6' import { InstanceV7 } from './v7' import { InstanceV8 } from './v8' import { InstanceV9 } from './v9' +import { InstanceV10 } from './v10' const instancesMigration = { 4: (state: InstanceV3): InstanceV4 => { @@ -99,7 +100,23 @@ const instancesMigration = { } }) } + }, + 10: (state: { instances: InstanceV9[] }): { instances: InstanceV10[] } => { + return { + instances: state.instances.map(instance => { + return { + ...instance, + notifications_filter: { + ...instance.notifications_filter, + status: true, + update: true + } + } + }) + } } } +export { InstanceV10 as InstanceLatest } + export default instancesMigration diff --git a/src/utils/migrations/instances/v10.ts b/src/utils/migrations/instances/v10.ts new file mode 100644 index 00000000..6257a75f --- /dev/null +++ b/src/utils/migrations/instances/v10.ts @@ -0,0 +1,81 @@ +import { ComposeStateDraft } from '@screens/Compose/utils/types' +import { QueryKeyTimeline } from '@utils/queryHooks/timeline' + +export type InstanceV10 = { + active: boolean + appData: { + clientId: string + clientSecret: string + } + url: string + token: string + uri: Mastodon.Instance['uri'] + urls: Mastodon.Instance['urls'] + account: { + id: Mastodon.Account['id'] + acct: Mastodon.Account['acct'] + avatarStatic: Mastodon.Account['avatar_static'] + preferences: Mastodon.Preferences + } + version: string + configuration?: Mastodon.Instance['configuration'] + filters: Mastodon.Filter[] + notifications_filter: { + follow: boolean + follow_request: boolean + favourite: boolean + reblog: boolean + mention: boolean + poll: boolean + status: boolean + update: boolean + } + push: { + global: { loading: boolean; value: boolean } + decode: { loading: boolean; value: boolean } + alerts: { + follow: { + loading: boolean + value: Mastodon.PushSubscription['alerts']['follow'] + } + favourite: { + loading: boolean + value: Mastodon.PushSubscription['alerts']['favourite'] + } + reblog: { + loading: boolean + value: Mastodon.PushSubscription['alerts']['reblog'] + } + mention: { + loading: boolean + value: Mastodon.PushSubscription['alerts']['mention'] + } + poll: { + loading: boolean + value: Mastodon.PushSubscription['alerts']['poll'] + } + } + keys: { + auth?: string + public?: string // legacy + private?: string // legacy + } + } + timelinesLookback?: { + [key: string]: { + queryKey: QueryKeyTimeline + ids: Mastodon.Status['id'][] + } + } + mePage: { + lists: { shown: boolean } + announcements: { shown: boolean; unread: number } + } + drafts: ComposeStateDraft[] + frequentEmojis: { + emoji: Pick + score: number + count: number + lastUsed: number + }[] +} diff --git a/src/utils/push/useConnect.ts b/src/utils/push/useConnect.ts index 84174ea4..6096f4a9 100644 --- a/src/utils/push/useConnect.ts +++ b/src/utils/push/useConnect.ts @@ -4,7 +4,8 @@ import { displayMessage } from '@components/Message' import navigationRef from '@helpers/navigationRef' import { useAppDispatch } from '@root/store' import { isDevelopment } from '@utils/checkEnvironment' -import { disableAllPushes, Instance } from '@utils/slices/instancesSlice' +import { InstanceLatest } from '@utils/migrations/instances/migration' +import { disableAllPushes } from '@utils/slices/instancesSlice' import { useTheme } from '@utils/styles/ThemeManager' import * as Notifications from 'expo-notifications' import { useEffect } from 'react' @@ -12,7 +13,7 @@ import { TFunction } from 'react-i18next' export interface Params { t: TFunction<'screens'> - instances: Instance[] + instances: InstanceLatest[] } const pushUseConnect = ({ t, instances }: Params) => { diff --git a/src/utils/push/useReceive.ts b/src/utils/push/useReceive.ts index b5997966..692b9231 100644 --- a/src/utils/push/useReceive.ts +++ b/src/utils/push/useReceive.ts @@ -1,14 +1,14 @@ import { displayMessage } from '@components/Message' import queryClient from '@helpers/queryClient' import initQuery from '@utils/initQuery' +import { InstanceLatest } from '@utils/migrations/instances/migration' import { QueryKeyTimeline } from '@utils/queryHooks/timeline' -import { Instance } from '@utils/slices/instancesSlice' import * as Notifications from 'expo-notifications' import { useEffect } from 'react' import pushUseNavigate from './useNavigate' export interface Params { - instances: Instance[] + instances: InstanceLatest[] } const pushUseReceive = ({ instances }: Params) => { diff --git a/src/utils/push/useRespond.ts b/src/utils/push/useRespond.ts index 8121029a..325ee4b2 100644 --- a/src/utils/push/useRespond.ts +++ b/src/utils/push/useRespond.ts @@ -1,13 +1,13 @@ import queryClient from '@helpers/queryClient' import initQuery from '@utils/initQuery' +import { InstanceLatest } from '@utils/migrations/instances/migration' import { QueryKeyTimeline } from '@utils/queryHooks/timeline' -import { Instance } from '@utils/slices/instancesSlice' import * as Notifications from 'expo-notifications' import { useEffect } from 'react' import pushUseNavigate from './useNavigate' export interface Params { - instances: Instance[] + instances: InstanceLatest[] } const pushUseRespond = ({ instances }: Params) => { diff --git a/src/utils/queryHooks/timeline.ts b/src/utils/queryHooks/timeline.ts index b2956faa..1c4b28bb 100644 --- a/src/utils/queryHooks/timeline.ts +++ b/src/utils/queryHooks/timeline.ts @@ -2,7 +2,10 @@ import apiInstance, { InstanceResponse } from '@api/instance' import haptics from '@components/haptics' import queryClient from '@helpers/queryClient' import { store } from '@root/store' -import { getInstanceNotificationsFilter } from '@utils/slices/instancesSlice' +import { + checkInstanceFeature, + getInstanceNotificationsFilter +} from '@utils/slices/instancesSlice' import { AxiosError } from 'axios' import { uniqBy } from 'lodash' import { @@ -62,16 +65,26 @@ const queryFunction = async ({ case 'Notifications': const rootStore = store.getState() const notificationsFilter = getInstanceNotificationsFilter(rootStore) + const usePositiveFilter = checkInstanceFeature( + 'notification_types_positive_filter' + )(rootStore) return apiInstance({ method: 'get', url: 'notifications', params: { ...params, - ...(notificationsFilter && { - exclude_types: Object.keys(notificationsFilter) - // @ts-ignore - .filter(filter => notificationsFilter[filter] === false) - }) + ...(notificationsFilter && + (usePositiveFilter + ? { + types: Object.keys(notificationsFilter) + // @ts-ignore + .filter(filter => notificationsFilter[filter] === true) + } + : { + exclude_types: Object.keys(notificationsFilter) + // @ts-ignore + .filter(filter => notificationsFilter[filter] === false) + })) } }) diff --git a/src/utils/slices/instances/add.ts b/src/utils/slices/instances/add.ts index 5b5b95e0..1f19bd34 100644 --- a/src/utils/slices/instances/add.ts +++ b/src/utils/slices/instances/add.ts @@ -1,7 +1,7 @@ import apiGeneral from '@api/general' import { createAsyncThunk } from '@reduxjs/toolkit' import { RootState } from '@root/store' -import { Instance } from '../instancesSlice' +import { InstanceLatest } from '@utils/migrations/instances/migration' const addInstance = createAsyncThunk( 'instances/add', @@ -11,11 +11,11 @@ const addInstance = createAsyncThunk( instance, appData }: { - domain: Instance['url'] - token: Instance['token'] + domain: InstanceLatest['url'] + token: InstanceLatest['token'] instance: Mastodon.Instance - appData: Instance['appData'] - }): Promise<{ type: 'add' | 'overwrite'; data: Instance }> => { + appData: InstanceLatest['appData'] + }): Promise<{ type: 'add' | 'overwrite'; data: InstanceLatest }> => { const { store } = require('@root/store') const instances = (store.getState() as RootState).instances.instances @@ -81,11 +81,13 @@ const addInstance = createAsyncThunk( filters, notifications_filter: { follow: true, + follow_request: true, favourite: true, reblog: true, mention: true, poll: true, - follow_request: true + status: true, + update: true }, push: { global: { loading: false, value: false }, diff --git a/src/utils/slices/instances/push/register.ts b/src/utils/slices/instances/push/register.ts index 0db6ef44..ff43c968 100644 --- a/src/utils/slices/instances/push/register.ts +++ b/src/utils/slices/instances/push/register.ts @@ -2,7 +2,8 @@ import apiInstance from '@api/instance' import apiTooot, { TOOOT_API_DOMAIN } from '@api/tooot' import i18n from '@root/i18n/i18n' import { RootState } from '@root/store' -import { getInstance, Instance } from '@utils/slices/instancesSlice' +import { InstanceLatest } from '@utils/migrations/instances/migration' +import { getInstance } from '@utils/slices/instancesSlice' import * as Notifications from 'expo-notifications' import * as Random from 'expo-random' import { Platform } from 'react-native' @@ -34,7 +35,7 @@ const subscribe = async ({ const pushRegister = async ( state: RootState, expoToken: string -): Promise => { +): Promise => { const instance = getInstance(state) const instanceUrl = instance?.url const instanceUri = instance?.uri diff --git a/src/utils/slices/instances/remove.ts b/src/utils/slices/instances/remove.ts index 1794b1c9..053971c7 100644 --- a/src/utils/slices/instances/remove.ts +++ b/src/utils/slices/instances/remove.ts @@ -1,11 +1,11 @@ import { createAsyncThunk } from '@reduxjs/toolkit' +import { InstanceLatest } from '@utils/migrations/instances/migration' import * as AuthSession from 'expo-auth-session' -import { Instance } from '../instancesSlice' import { updateInstancePush } from './updatePush' const removeInstance = createAsyncThunk( 'instances/remove', - async (instance: Instance, { dispatch }): Promise => { + async (instance: InstanceLatest, { dispatch }): Promise => { if (instance.push.global.value) { dispatch(updateInstancePush(false)) } diff --git a/src/utils/slices/instances/updatePush.ts b/src/utils/slices/instances/updatePush.ts index a477a100..9d11c546 100644 --- a/src/utils/slices/instances/updatePush.ts +++ b/src/utils/slices/instances/updatePush.ts @@ -1,8 +1,8 @@ import { createAsyncThunk } from '@reduxjs/toolkit' import { RootState } from '@root/store' import { isDevelopment } from '@utils/checkEnvironment' +import { InstanceLatest } from '@utils/migrations/instances/migration' import * as Notifications from 'expo-notifications' -import { Instance } from '../instancesSlice' import pushRegister from './push/register' import pushUnregister from './push/unregister' @@ -11,7 +11,7 @@ export const updateInstancePush = createAsyncThunk( async ( disable: boolean, { getState } - ): Promise => { + ): Promise => { const state = getState() as RootState const expoToken = isDevelopment ? 'DEVELOPMENT_TOKEN_1' diff --git a/src/utils/slices/instances/updatePushAlert.ts b/src/utils/slices/instances/updatePushAlert.ts index 7d583448..1bbe3b49 100644 --- a/src/utils/slices/instances/updatePushAlert.ts +++ b/src/utils/slices/instances/updatePushAlert.ts @@ -1,15 +1,15 @@ import apiInstance from '@api/instance' import { createAsyncThunk } from '@reduxjs/toolkit' -import { Instance } from '../instancesSlice' +import { InstanceLatest } from '@utils/migrations/instances/migration' export const updateInstancePushAlert = createAsyncThunk( 'instances/updatePushAlert', async ({ alerts }: { - changed: keyof Instance['push']['alerts'] - alerts: Instance['push']['alerts'] - }): Promise => { + changed: keyof InstanceLatest['push']['alerts'] + alerts: InstanceLatest['push']['alerts'] + }): Promise => { const formData = new FormData() Object.keys(alerts).map(alert => // @ts-ignore diff --git a/src/utils/slices/instances/updatePushDecode.ts b/src/utils/slices/instances/updatePushDecode.ts index a0c5b898..3525d170 100644 --- a/src/utils/slices/instances/updatePushDecode.ts +++ b/src/utils/slices/instances/updatePushDecode.ts @@ -3,9 +3,10 @@ import { createAsyncThunk } from '@reduxjs/toolkit' import i18n from '@root/i18n/i18n' import { RootState } from '@root/store' import { isDevelopment } from '@utils/checkEnvironment' +import { InstanceLatest } from '@utils/migrations/instances/migration' import * as Notifications from 'expo-notifications' import { Platform } from 'react-native' -import { getInstance, Instance } from '../instancesSlice' +import { getInstance } from '../instancesSlice' import androidDefaults from './push/androidDefaults' export const updateInstancePushDecode = createAsyncThunk( @@ -13,7 +14,7 @@ export const updateInstancePushDecode = createAsyncThunk( async ( disable: boolean, { getState } - ): Promise<{ disable: Instance['push']['decode']['value'] }> => { + ): Promise<{ disable: InstanceLatest['push']['decode']['value'] }> => { const state = getState() as RootState const instance = getInstance(state) if (!instance?.url || !instance.account.id || !instance.push.keys) { diff --git a/src/utils/slices/instancesSlice.ts b/src/utils/slices/instancesSlice.ts index 85210dff..fd9d845e 100644 --- a/src/utils/slices/instancesSlice.ts +++ b/src/utils/slices/instancesSlice.ts @@ -3,7 +3,7 @@ import features from '@helpers/features' import { createSlice, PayloadAction } from '@reduxjs/toolkit' import { RootState } from '@root/store' import { ComposeStateDraft } from '@screens/Compose/utils/types' -import { InstanceV9 } from '@utils/migrations/instances/v9' +import { InstanceLatest } from '@utils/migrations/instances/migration' import addInstance from './instances/add' import { checkEmojis } from './instances/checkEmojis' import removeInstance from './instances/remove' @@ -14,24 +14,25 @@ import { updateInstancePush } from './instances/updatePush' import { updateInstancePushAlert } from './instances/updatePushAlert' import { updateInstancePushDecode } from './instances/updatePushDecode' -export type Instance = InstanceV9 - export type InstancesState = { - instances: Instance[] + instances: InstanceLatest[] } export const instancesInitialState: InstancesState = { instances: [] } -const findInstanceActive = (instances: Instance[]) => +const findInstanceActive = (instances: InstanceLatest[]) => instances.findIndex(instance => instance.active) const instancesSlice = createSlice({ name: 'instances', initialState: instancesInitialState, reducers: { - updateInstanceActive: ({ instances }, action: PayloadAction) => { + updateInstanceActive: ( + { instances }, + action: PayloadAction + ) => { instances = instances.map(instance => { instance.active = instance.url === action.payload.url && @@ -42,7 +43,9 @@ const instancesSlice = createSlice({ }, updateInstanceAccount: ( { instances }, - action: PayloadAction> + action: PayloadAction< + Pick + > ) => { const activeIndex = findInstanceActive(instances) instances[activeIndex].account = { @@ -52,7 +55,7 @@ const instancesSlice = createSlice({ }, updateInstanceNotificationsFilter: ( { instances }, - action: PayloadAction + action: PayloadAction ) => { const activeIndex = findInstanceActive(instances) instances[activeIndex].notifications_filter = action.payload @@ -99,7 +102,7 @@ const instancesSlice = createSlice({ }, updateInstanceTimelineLookback: ( { instances }, - action: PayloadAction + action: PayloadAction ) => { const activeIndex = findInstanceActive(instances) instances[activeIndex] && @@ -110,7 +113,7 @@ const instancesSlice = createSlice({ }, updateInstanceMePage: ( { instances }, - action: PayloadAction> + action: PayloadAction> ) => { const activeIndex = findInstanceActive(instances) instances[activeIndex].mePage = { @@ -120,10 +123,12 @@ const instancesSlice = createSlice({ }, countInstanceEmoji: ( { instances }, - action: PayloadAction + action: PayloadAction ) => { const HALF_LIFE = 60 * 60 * 24 * 7 // 1 week - const calculateScore = (emoji: Instance['frequentEmojis'][0]): number => { + const calculateScore = ( + emoji: InstanceLatest['frequentEmojis'][0] + ): number => { var seconds = (new Date().getTime() - emoji.lastUsed) / 1000 var score = emoji.count + 1 var order = Math.log(Math.max(score, 1)) / Math.LN10 @@ -136,7 +141,7 @@ const instancesSlice = createSlice({ e.emoji.shortcode === action.payload.shortcode && e.emoji.url === action.payload.url ) - let newEmojisSort: Instance['frequentEmojis'] + let newEmojisSort: InstanceLatest['frequentEmojis'] if (foundEmojiIndex > -1) { newEmojisSort = instances[activeIndex].frequentEmojis .map((e, i) =>