diff --git a/src/@types/mastodon.d.ts b/src/@types/mastodon.d.ts index 54bc1571..8b58589b 100644 --- a/src/@types/mastodon.d.ts +++ b/src/@types/mastodon.d.ts @@ -30,6 +30,7 @@ declare namespace Mastodon { bot: boolean source?: Source suspended?: boolean + role?: Role } type Announcement = { @@ -384,6 +385,8 @@ declare namespace Mastodon { mention: boolean poll: boolean status: boolean + 'admin.sign_up': boolean + 'admin.report': boolean } server_key: string } @@ -409,6 +412,18 @@ declare namespace Mastodon { hashtags?: Tag[] } + type Role = { + // Added since 4.0 + id: string + name: string + color: string + position: number + permissions: string + highlighted: boolean + created_at: string + updated_at: string + } + type Status = { // Base id: string @@ -479,25 +494,4 @@ declare namespace Mastodon { history: { day: string; accounts: string; uses: string }[] following: boolean // Since v4.0 } - - type WebSocketStream = - | 'user' - | 'public' - | 'public:local' - | 'hashtag' - | 'hashtag:local' - | 'list' - | 'direct' - type WebSocket = - | { - stream: WebSocketStream[] - event: 'update' - payload: string // Status - } - | { stream: WebSocketStream[]; event: 'delete'; payload: Status['id'] } - | { - stream: WebSocketStream[] - event: 'notification' - payload: string // Notification - } } diff --git a/src/Screens.tsx b/src/Screens.tsx index f5686550..e7430d1f 100644 --- a/src/Screens.tsx +++ b/src/Screens.tsx @@ -135,10 +135,7 @@ const Screens: React.FC = ({ localCorrupt }) => { instance => paths[0] === `@${instance.account.acct}@${instance.uri}` ) if (instanceIndex !== -1 && instanceActive !== instanceIndex) { - initQuery({ - instance: instances[instanceIndex], - prefetch: { enabled: true } - }) + initQuery({ instance: instances[instanceIndex] }) } } } diff --git a/src/components/AccountButton.tsx b/src/components/AccountButton.tsx index cddce028..21ef8288 100644 --- a/src/components/AccountButton.tsx +++ b/src/components/AccountButton.tsx @@ -12,11 +12,7 @@ interface Props { additionalActions?: () => void } -const AccountButton: React.FC = ({ - instance, - selected = false, - additionalActions -}) => { +const AccountButton: React.FC = ({ instance, selected = false, additionalActions }) => { const navigation = useNavigation() return ( @@ -27,12 +23,10 @@ const AccountButton: React.FC = ({ marginBottom: StyleConstants.Spacing.M, marginRight: StyleConstants.Spacing.M }} - content={`@${instance.account.acct}@${instance.uri}${ - selected ? ' ✓' : '' - }`} + content={`@${instance.account.acct}@${instance.uri}${selected ? ' ✓' : ''}`} onPress={() => { haptics('Light') - initQuery({ instance, prefetch: { enabled: true } }) + initQuery({ instance }) navigation.goBack() if (additionalActions) { additionalActions() diff --git a/src/helpers/features.json b/src/helpers/features.json index 3a466762..994eaa34 100644 --- a/src/helpers/features.json +++ b/src/helpers/features.json @@ -19,6 +19,11 @@ "version": 3.5, "reference": "https://github.com/mastodon/mastodon/releases/tag/v3.5.0" }, + { + "feature": "notification_type_admin_signup", + "version": 3.5, + "reference": "https://github.com/mastodon/mastodon/releases/tag/v3.5.0" + }, { "feature": "notification_types_positive_filter", "version": 3.5, @@ -33,5 +38,10 @@ "feature": "follow_tags", "version": 4.0, "reference": "https://github.com/mastodon/mastodon/releases/tag/v4.0.0" + }, + { + "feature": "notification_type_admin_report", + "version": 4.0, + "reference": "https://github.com/mastodon/mastodon/releases/tag/v3.5.0" } ] \ No newline at end of file diff --git a/src/helpers/permissions.ts b/src/helpers/permissions.ts new file mode 100644 index 00000000..bbb3a1a4 --- /dev/null +++ b/src/helpers/permissions.ts @@ -0,0 +1,2 @@ +export const PERMISSION_MANAGE_REPORTS = 0x0000000000000010 +export const PERMISSION_MANAGE_USERS = 0x0000000000000400 diff --git a/src/i18n/en/screens/tabs.json b/src/i18n/en/screens/tabs.json index e2abcd89..c4da7ba8 100644 --- a/src/i18n/en/screens/tabs.json +++ b/src/i18n/en/screens/tabs.json @@ -214,6 +214,12 @@ "status": { "heading": "Toot from subscribed users" }, + "admin.sign_up": { + "heading": "Admin: sign up" + }, + "admin.report": { + "heading": "Admin: reports" + }, "howitworks": "Learn how routing works" }, "root": { @@ -225,10 +231,8 @@ } }, "push": { - "content": { - "enabled": "Enabled", - "disabled": "Disabled" - } + "content_true": "Enabled", + "content_false": "Disabled" }, "update": { "title": "Update to latest version" diff --git a/src/screens/Tabs/Me/Profile/Root.tsx b/src/screens/Tabs/Me/Profile/Root.tsx index a4e48780..6a1f4ba1 100644 --- a/src/screens/Tabs/Me/Profile/Root.tsx +++ b/src/screens/Tabs/Me/Profile/Root.tsx @@ -21,7 +21,7 @@ const TabMeProfileRoot: React.FC< const { showActionSheetWithOptions } = useActionSheet() - const { data, isLoading } = useProfileQuery({}) + const { data, isLoading } = useProfileQuery() const { mutateAsync } = useProfileMutation() const dispatch = useAppDispatch() diff --git a/src/screens/Tabs/Me/Profile/Root/AvatarHeader.tsx b/src/screens/Tabs/Me/Profile/Root/AvatarHeader.tsx index f6879a2c..363c879b 100644 --- a/src/screens/Tabs/Me/Profile/Root/AvatarHeader.tsx +++ b/src/screens/Tabs/Me/Profile/Root/AvatarHeader.tsx @@ -17,7 +17,7 @@ const ProfileAvatarHeader: React.FC = ({ type, messageRef }) => { const { showActionSheetWithOptions } = useActionSheet() - const query = useProfileQuery({}) + const query = useProfileQuery() const mutation = useProfileMutation() return ( diff --git a/src/screens/Tabs/Me/Push.tsx b/src/screens/Tabs/Me/Push.tsx index 5d498b8b..b32c2943 100644 --- a/src/screens/Tabs/Me/Push.tsx +++ b/src/screens/Tabs/Me/Push.tsx @@ -3,28 +3,48 @@ import Icon from '@components/Icon' import { MenuContainer, MenuRow } from '@components/Menu' import CustomText from '@components/Text' import browserPackage from '@helpers/browserPackage' +import { PERMISSION_MANAGE_REPORTS, PERMISSION_MANAGE_USERS } from '@helpers/permissions' import { useAppDispatch } from '@root/store' import { isDevelopment } from '@utils/checkEnvironment' +import { useProfileQuery } from '@utils/queryHooks/profile' import { getExpoToken } from '@utils/slices/appSlice' import { updateInstancePush } from '@utils/slices/instances/updatePush' import { updateInstancePushAlert } from '@utils/slices/instances/updatePushAlert' import { updateInstancePushDecode } from '@utils/slices/instances/updatePushDecode' -import { - clearPushLoading, - getInstanceAccount, - getInstancePush, - getInstanceUri -} from '@utils/slices/instancesSlice' +import { getInstanceAccount, getInstancePush, getInstanceUri } from '@utils/slices/instancesSlice' import { StyleConstants } from '@utils/styles/constants' import layoutAnimation from '@utils/styles/layoutAnimation' import { useTheme } from '@utils/styles/ThemeManager' import * as Notifications from 'expo-notifications' import * as WebBrowser from 'expo-web-browser' -import React, { useState, useEffect, useMemo } from 'react' +import React, { useState, useEffect } from 'react' import { useTranslation } from 'react-i18next' import { AppState, Linking, ScrollView, View } from 'react-native' import { useSelector } from 'react-redux' +export const PUSH_DEFAULT: [ + 'follow', + 'follow_request', + 'favourite', + 'reblog', + 'mention', + 'poll', + 'status' +] = ['follow', 'follow_request', 'favourite', 'reblog', 'mention', 'poll', 'status'] +export const PUSH_ADMIN: { type: 'admin.sign_up' | 'admin.report'; permission: number }[] = [ + { type: 'admin.sign_up', permission: PERMISSION_MANAGE_USERS }, + { type: 'admin.report', permission: PERMISSION_MANAGE_REPORTS } +] +export const checkPushAdminPermission = ( + permission: number, + permissions?: string | number +): boolean => + permissions + ? !!( + (typeof permissions === 'string' ? parseInt(permissions || '0') : permissions) & permission + ) + : false + const TabMePush: React.FC = () => { const { colors } = useTheme() const { t } = useTranslation('screenTabs') @@ -58,40 +78,21 @@ const TabMePush: React.FC = () => { } }, []) - useEffect(() => { - dispatch(clearPushLoading()) - }, []) - - const isLoading = instancePush?.global.loading || instancePush?.decode.loading - - const alerts = useMemo(() => { - return instancePush?.alerts - ? ( - ['follow', 'follow_request', 'favourite', 'reblog', 'mention', 'poll', 'status'] as [ - 'follow', - 'follow_request', - 'favourite', - 'reblog', - 'mention', - 'poll', - 'status' - ] - ).map(alert => ( + const alerts = () => + instancePush?.alerts + ? PUSH_DEFAULT.map(alert => ( dispatch( updateInstancePushAlert({ changed: alert, alerts: { ...instancePush?.alerts, - [alert]: { - ...instancePush?.alerts[alert], - value: !instancePush?.alerts[alert].value - } + [alert]: instancePush?.alerts[alert] } }) ) @@ -99,7 +100,32 @@ const TabMePush: React.FC = () => { /> )) : null - }, [pushEnabled, instancePush?.global, instancePush?.alerts, isLoading]) + + const profileQuery = useProfileQuery() + const adminAlerts = () => + profileQuery.data?.role?.permissions + ? PUSH_ADMIN.map(({ type, permission }) => + checkPushAdminPermission(permission, profileQuery.data.role?.permissions) ? ( + + dispatch( + updateInstancePushAlert({ + changed: type, + alerts: { + ...instancePush?.alerts, + [type]: instancePush?.alerts[type] + } + }) + ) + } + /> + ) : null + ) + : null return ( @@ -134,22 +160,19 @@ const TabMePush: React.FC = () => { acct: `@${instanceAccount?.acct}@${instanceUri}` })} description={t('me.push.global.description')} - loading={instancePush?.global.loading} - switchDisabled={!pushEnabled || isLoading} - switchValue={pushEnabled === false ? false : instancePush?.global.value} - switchOnValueChange={() => dispatch(updateInstancePush(!instancePush?.global.value))} + switchDisabled={!pushEnabled} + switchValue={pushEnabled === false ? false : instancePush?.global} + switchOnValueChange={() => dispatch(updateInstancePush(!instancePush?.global))} /> - dispatch(updateInstancePushDecode(!instancePush?.decode.value)) - } + loading={instancePush?.decode} + switchDisabled={!pushEnabled || !instancePush?.global} + switchValue={instancePush?.decode} + switchOnValueChange={() => dispatch(updateInstancePushDecode(!instancePush?.decode))} /> { } /> - {alerts} + + ) : ( { flex: 1, minHeight: '100%', justifyContent: 'center', - alignItems: 'center' + alignItems: 'center', + paddingHorizontal: StyleConstants.Spacing.Global.PagePadding }} > - + {t('me.push.notAvailable')} diff --git a/src/screens/Tabs/Me/Root/Collections.tsx b/src/screens/Tabs/Me/Root/Collections.tsx index 900be986..557b3a65 100644 --- a/src/screens/Tabs/Me/Root/Collections.tsx +++ b/src/screens/Tabs/Me/Root/Collections.tsx @@ -50,10 +50,7 @@ const Collections: React.FC = () => { } }, [announcementsQuery.data]) - const instancePush = useSelector( - getInstancePush, - (prev, next) => prev?.global.value === next?.global.value - ) + const instancePush = useSelector(getInstancePush, (prev, next) => prev?.global === next?.global) return ( @@ -102,11 +99,7 @@ const Collections: React.FC = () => { iconFront={instancePush ? 'Bell' : 'BellOff'} iconBack='ChevronRight' title={t('me.stacks.push.name')} - content={ - instancePush.global.value - ? t('me.root.push.content.enabled') - : t('me.root.push.content.disabled') - } + content={t('me.root.push.content', { context: instancePush.global.toString() })} onPress={() => navigation.navigate('Tab-Me-Push')} /> diff --git a/src/screens/Tabs/Me/SettingsLanguage.tsx b/src/screens/Tabs/Me/SettingsLanguage.tsx index 0e9cd820..c76e46d4 100644 --- a/src/screens/Tabs/Me/SettingsLanguage.tsx +++ b/src/screens/Tabs/Me/SettingsLanguage.tsx @@ -2,6 +2,7 @@ import haptics from '@components/haptics' import { MenuContainer, MenuRow } from '@components/Menu' import { LOCALES } from '@root/i18n/locales' import { TabMeStackScreenProps } from '@utils/navigation/navigators' +import { useProfileQuery } from '@utils/queryHooks/profile' import androidDefaults from '@utils/slices/instances/push/androidDefaults' import { getInstances } from '@utils/slices/instancesSlice' import { changeLanguage } from '@utils/slices/settingsSlice' @@ -10,15 +11,18 @@ import React from 'react' import { useTranslation } from 'react-i18next' import { FlatList, Platform } from 'react-native' import { useDispatch, useSelector } from 'react-redux' +import { checkPushAdminPermission, PUSH_ADMIN, PUSH_DEFAULT } from './Push' -const TabMeSettingsLanguage: React.FC< - TabMeStackScreenProps<'Tab-Me-Settings-Language'> -> = ({ navigation }) => { +const TabMeSettingsLanguage: React.FC> = ({ + navigation +}) => { const { i18n, t } = useTranslation('screenTabs') const languages = Object.entries(LOCALES) const instances = useSelector(getInstances) const dispatch = useDispatch() + const profileQuery = useProfileQuery({ options: { enabled: Platform.OS === 'android' } }) + const change = (lang: string) => { haptics('Success') @@ -29,41 +33,29 @@ const TabMeSettingsLanguage: React.FC< if (Platform.OS === 'android') { instances.forEach(instance => { const accountFull = `@${instance.account.acct}@${instance.uri}` - if (instance.push.decode.value === false) { + if (instance.push.decode === false) { Notifications.setNotificationChannelAsync(`${accountFull}_default`, { groupId: accountFull, name: t('me.push.default.heading'), ...androidDefaults }) } else { - Notifications.setNotificationChannelAsync(`${accountFull}_follow`, { - groupId: accountFull, - name: t('me.push.follow.heading'), - ...androidDefaults - }) - Notifications.setNotificationChannelAsync( - `${accountFull}_favourite`, - { + for (const push of PUSH_DEFAULT) { + Notifications.setNotificationChannelAsync(`${accountFull}_${push}`, { groupId: accountFull, - name: t('me.push.favourite.heading'), + name: t(`me.push.${push}.heading`), ...androidDefaults + }) + } + for (const { type, permission } of PUSH_ADMIN) { + if (checkPushAdminPermission(permission, profileQuery.data?.role?.permissions)) { + Notifications.setNotificationChannelAsync(`${accountFull}_${type}`, { + groupId: accountFull, + name: t(`me.push.${type}.heading`), + ...androidDefaults + }) } - ) - Notifications.setNotificationChannelAsync(`${accountFull}_reblog`, { - groupId: accountFull, - name: t('me.push.reblog.heading'), - ...androidDefaults - }) - Notifications.setNotificationChannelAsync(`${accountFull}_mention`, { - groupId: accountFull, - name: t('me.push.mention.heading'), - ...androidDefaults - }) - Notifications.setNotificationChannelAsync(`${accountFull}_poll`, { - groupId: accountFull, - name: t('me.push.poll.heading'), - ...androidDefaults - }) + } } }) } diff --git a/src/startup/netInfo.ts b/src/startup/netInfo.ts index d7b25185..9e38cac7 100644 --- a/src/startup/netInfo.ts +++ b/src/startup/netInfo.ts @@ -1,13 +1,8 @@ import apiInstance from '@api/instance' import NetInfo from '@react-native-community/netinfo' import { store } from '@root/store' -import initQuery from '@utils/initQuery' -import { getPreviousTab } from '@utils/slices/contextsSlice' import removeInstance from '@utils/slices/instances/remove' -import { - getInstance, - updateInstanceAccount -} from '@utils/slices/instancesSlice' +import { getInstance, updateInstanceAccount } from '@utils/slices/instancesSlice' import { onlineManager } from 'react-query' import log from './log' @@ -22,9 +17,7 @@ const netInfo = async (): Promise<{ onlineManager.setEventListener(setOnline => { return NetInfo.addEventListener(state => { - setOnline( - typeof state.isConnected === 'boolean' ? state.isConnected : undefined - ) + setOnline(typeof state.isConnected === 'boolean' ? state.isConnected : undefined) }) }) @@ -60,23 +53,6 @@ const netInfo = async (): Promise<{ }) ) - if (instance.timelinesLookback) { - const previousTab = getPreviousTab(store.getState()) - let loadPage: - | Extract - | undefined = undefined - if (previousTab === 'Tab-Local') { - loadPage = 'Following' - } else if (previousTab === 'Tab-Public') { - loadPage = 'LocalPublic' - } - - // await initQuery({ - // instance, - // prefetch: { enabled: true, page: loadPage } - // }) - } - return Promise.resolve({ connected: true }) } } else { diff --git a/src/store.ts b/src/store.ts index 7e6b5e2d..f9725338 100644 --- a/src/store.ts +++ b/src/store.ts @@ -46,7 +46,7 @@ const instancesPersistConfig = { key: 'instances', prefix, storage: Platform.OS === 'ios' ? secureStorage : AsyncStorage, - version: 10, + version: 11, // @ts-ignore migrate: createMigrate(instancesMigration) } diff --git a/src/utils/initQuery.ts b/src/utils/initQuery.ts index f51dcba0..591e9538 100644 --- a/src/utils/initQuery.ts +++ b/src/utils/initQuery.ts @@ -1,33 +1,11 @@ import queryClient from '@helpers/queryClient' import { store } from '@root/store' import { InstanceLatest } from './migrations/instances/migration' -// import { prefetchTimelineQuery } from './queryHooks/timeline' import { updateInstanceActive } from './slices/instancesSlice' -const initQuery = async ({ - instance, - prefetch -}: { - instance: InstanceLatest - prefetch?: { enabled: boolean; page?: 'Following' | 'LocalPublic' } -}) => { +const initQuery = async ({ instance }: { instance: InstanceLatest }) => { store.dispatch(updateInstanceActive(instance)) await queryClient.resetQueries() - - // if (prefetch?.enabled && instance.timelinesLookback) { - // if ( - // prefetch.page && - // instance.timelinesLookback[prefetch.page]?.ids?.length > 0 - // ) { - // await prefetchTimelineQuery(instance.timelinesLookback[prefetch.page]) - // } - - // for (const page of Object.keys(instance.timelinesLookback)) { - // if (page !== prefetch.page) { - // prefetchTimelineQuery(instance.timelinesLookback[page]) - // } - // } - // } } export default initQuery diff --git a/src/utils/migrations/instances/migration.ts b/src/utils/migrations/instances/migration.ts index ac02bd1c..ee5627c9 100644 --- a/src/utils/migrations/instances/migration.ts +++ b/src/utils/migrations/instances/migration.ts @@ -6,6 +6,7 @@ import { InstanceV7 } from './v7' import { InstanceV8 } from './v8' import { InstanceV9 } from './v9' import { InstanceV10 } from './v10' +import { InstanceV11 } from './v11' const instancesMigration = { 4: (state: InstanceV3): InstanceV4 => { @@ -128,9 +129,34 @@ const instancesMigration = { } }) } + }, + 11: (state: { instances: InstanceV10[] }): { instances: InstanceV11[] } => { + return { + instances: state.instances.map(instance => { + return { + ...instance, + push: { + ...instance.push, + global: instance.push.global.value, + decode: instance.push.decode.value, + alerts: { + follow: instance.push.alerts.follow.value, + follow_request: instance.push.alerts.follow_request.value, + favourite: instance.push.alerts.favourite.value, + reblog: instance.push.alerts.reblog.value, + mention: instance.push.alerts.mention.value, + poll: instance.push.alerts.poll.value, + status: instance.push.alerts.status.value, + 'admin.sign_up': false, + 'admin.report': false + } + } + } + }) + } } } -export { InstanceV10 as InstanceLatest } +export { InstanceV11 as InstanceLatest } export default instancesMigration diff --git a/src/utils/migrations/instances/v11.ts b/src/utils/migrations/instances/v11.ts new file mode 100644 index 00000000..7fe08573 --- /dev/null +++ b/src/utils/migrations/instances/v11.ts @@ -0,0 +1,60 @@ +import { ComposeStateDraft } from '@screens/Compose/utils/types' +import { QueryKeyTimeline } from '@utils/queryHooks/timeline' + +export type InstanceV11 = { + 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: boolean + decode: boolean + alerts: Mastodon.PushSubscription['alerts'] + 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 bb117b7d..dbb45104 100644 --- a/src/utils/push/useConnect.ts +++ b/src/utils/push/useConnect.ts @@ -23,7 +23,7 @@ const pushUseConnect = () => { const expoToken = useSelector(getExpoToken) const instances = useSelector(getInstances, (prev, next) => prev.length === next.length) - const pushEnabled = instances.filter(instance => instance.push.global.value) + const pushEnabled = instances.filter(instance => instance.push.global) const connect = () => { apiTooot({ @@ -60,7 +60,7 @@ const pushUseConnect = () => { dispatch(disableAllPushes()) instances.forEach(instance => { - if (instance.push.global.value) { + if (instance.push.global) { apiGeneral<{}>({ method: 'delete', domain: instance.url, diff --git a/src/utils/push/useReceive.ts b/src/utils/push/useReceive.ts index 08c8009d..76a91b21 100644 --- a/src/utils/push/useReceive.ts +++ b/src/utils/push/useReceive.ts @@ -31,10 +31,7 @@ const pushUseReceive = () => { description: notification.request.content.body!, onPress: () => { if (notificationIndex !== -1) { - initQuery({ - instance: instances[notificationIndex], - prefetch: { enabled: true } - }) + initQuery({ instance: instances[notificationIndex] }) } pushUseNavigate(payloadData.notification_id) } diff --git a/src/utils/push/useRespond.ts b/src/utils/push/useRespond.ts index df4771b6..e63be4d4 100644 --- a/src/utils/push/useRespond.ts +++ b/src/utils/push/useRespond.ts @@ -27,10 +27,7 @@ const pushUseRespond = () => { instance.account.id === payloadData.accountId ) if (notificationIndex !== -1) { - initQuery({ - instance: instances[notificationIndex], - prefetch: { enabled: true } - }) + initQuery({ instance: instances[notificationIndex] }) } pushUseNavigate(payloadData.notification_id) } diff --git a/src/utils/queryHooks/profile.ts b/src/utils/queryHooks/profile.ts index bb00c6d5..2a000dc2 100644 --- a/src/utils/queryHooks/profile.ts +++ b/src/utils/queryHooks/profile.ts @@ -21,12 +21,12 @@ const queryFunction = async () => { return res.body } -const useProfileQuery = ({ - options -}: { - options?: UseQueryOptions -}) => { - return useQuery(queryKey, queryFunction, options) +const useProfileQuery = ( + params: { + options: UseQueryOptions + } | void +) => { + return useQuery(queryKey, queryFunction, params?.options) } type MutationVarsProfileBase = diff --git a/src/utils/slices/instances/add.ts b/src/utils/slices/instances/add.ts index a8f322ac..4b4551af 100644 --- a/src/utils/slices/instances/add.ts +++ b/src/utils/slices/instances/add.ts @@ -90,16 +90,18 @@ const addInstance = createAsyncThunk( update: true }, push: { - global: { loading: false, value: false }, - decode: { loading: false, value: false }, + global: false, + decode: false, alerts: { - follow: { loading: false, value: true }, - follow_request: { loading: false, value: true }, - favourite: { loading: false, value: true }, - reblog: { loading: false, value: true }, - mention: { loading: false, value: true }, - poll: { loading: false, value: true }, - status: { loading: false, value: true } + follow: true, + follow_request: true, + favourite: true, + reblog: true, + mention: true, + poll: true, + status: true, + 'admin.sign_up': false, + 'admin.report': false }, keys: { auth: undefined, public: undefined, private: undefined } }, diff --git a/src/utils/slices/instances/push/register.ts b/src/utils/slices/instances/push/register.ts index 976b0d29..396cefaa 100644 --- a/src/utils/slices/instances/push/register.ts +++ b/src/utils/slices/instances/push/register.ts @@ -6,7 +6,6 @@ import { RootState } from '@root/store' import * as Sentry from '@sentry/react-native' import { InstanceLatest } from '@utils/migrations/instances/migration' import { getInstance } from '@utils/slices/instancesSlice' -import { Theme } from '@utils/styles/themes' import * as Notifications from 'expo-notifications' import * as Random from 'expo-random' import i18next from 'i18next' @@ -97,7 +96,7 @@ const pushRegister = async ( accountId, accountFull, serverKey: res.body.server_key, - auth: instancePush.decode.value === false ? null : auth + auth: instancePush.decode === false ? null : auth }) if (Platform.OS === 'android') { @@ -106,7 +105,7 @@ const pushRegister = async ( ...androidDefaults }).then(group => { if (group) { - if (instancePush.decode.value === false) { + if (instancePush.decode === false) { Notifications.setNotificationChannelAsync(`${group.id}_default`, { groupId: group.id, name: i18n.t('meSettingsPush:content.default.heading'), diff --git a/src/utils/slices/instances/remove.ts b/src/utils/slices/instances/remove.ts index 053971c7..8936fa69 100644 --- a/src/utils/slices/instances/remove.ts +++ b/src/utils/slices/instances/remove.ts @@ -6,7 +6,7 @@ import { updateInstancePush } from './updatePush' const removeInstance = createAsyncThunk( 'instances/remove', async (instance: InstanceLatest, { dispatch }): Promise => { - if (instance.push.global.value) { + if (instance.push.global) { dispatch(updateInstancePush(false)) } diff --git a/src/utils/slices/instances/updatePushDecode.ts b/src/utils/slices/instances/updatePushDecode.ts index ac215263..ab0892e8 100644 --- a/src/utils/slices/instances/updatePushDecode.ts +++ b/src/utils/slices/instances/updatePushDecode.ts @@ -13,7 +13,7 @@ export const updateInstancePushDecode = createAsyncThunk( async ( disable: boolean, { getState } - ): Promise<{ disable: InstanceLatest['push']['decode']['value'] }> => { + ): Promise<{ disable: InstanceLatest['push']['decode'] }> => { const state = getState() as RootState const instance = getInstance(state) if (!instance?.url || !instance.account.id || !instance.push.keys) { @@ -43,14 +43,11 @@ export const updateInstancePushDecode = createAsyncThunk( name: i18n.t('meSettingsPush:content.follow.heading'), ...androidDefaults }) - Notifications.setNotificationChannelAsync( - `${accountFull}_favourite`, - { - groupId: accountFull, - name: i18n.t('meSettingsPush:content.favourite.heading'), - ...androidDefaults - } - ) + Notifications.setNotificationChannelAsync(`${accountFull}_favourite`, { + groupId: accountFull, + name: i18n.t('meSettingsPush:content.favourite.heading'), + ...androidDefaults + }) Notifications.setNotificationChannelAsync(`${accountFull}_reblog`, { groupId: accountFull, name: i18n.t('meSettingsPush:content.reblog.heading'), @@ -74,9 +71,7 @@ export const updateInstancePushDecode = createAsyncThunk( ...androidDefaults }) Notifications.deleteNotificationChannelAsync(`${accountFull}_follow`) - Notifications.deleteNotificationChannelAsync( - `${accountFull}_favourite` - ) + Notifications.deleteNotificationChannelAsync(`${accountFull}_favourite`) Notifications.deleteNotificationChannelAsync(`${accountFull}_reblog`) Notifications.deleteNotificationChannelAsync(`${accountFull}_mention`) Notifications.deleteNotificationChannelAsync(`${accountFull}_poll`) diff --git a/src/utils/slices/instancesSlice.ts b/src/utils/slices/instancesSlice.ts index c331301c..87abf486 100644 --- a/src/utils/slices/instancesSlice.ts +++ b/src/utils/slices/instancesSlice.ts @@ -73,18 +73,11 @@ const instancesSlice = createSlice({ }, clearPushLoading: ({ instances }) => { const activeIndex = findInstanceActive(instances) - instances[activeIndex].push.global.loading = false - instances[activeIndex].push.decode.loading = false - instances[activeIndex].push.alerts.favourite.loading = false - instances[activeIndex].push.alerts.follow.loading = false - instances[activeIndex].push.alerts.mention.loading = false - instances[activeIndex].push.alerts.poll.loading = false - instances[activeIndex].push.alerts.reblog.loading = false }, disableAllPushes: ({ instances }) => { instances = instances.map(instance => { let newInstance = instance - newInstance.push.global.value = false + newInstance.push.global = false return newInstance }) }, @@ -238,48 +231,21 @@ const instancesSlice = createSlice({ // Update Instance Push Global .addCase(updateInstancePush.fulfilled, (state, action) => { const activeIndex = findInstanceActive(state.instances) - state.instances[activeIndex].push.global.loading = false - state.instances[activeIndex].push.global.value = action.meta.arg + state.instances[activeIndex].push.global = action.meta.arg state.instances[activeIndex].push.keys = { auth: action.payload } }) - .addCase(updateInstancePush.rejected, state => { - const activeIndex = findInstanceActive(state.instances) - state.instances[activeIndex].push.global.loading = false - }) - .addCase(updateInstancePush.pending, state => { - const activeIndex = findInstanceActive(state.instances) - state.instances[activeIndex].push.global.loading = true - }) // Update Instance Push Decode .addCase(updateInstancePushDecode.fulfilled, (state, action) => { const activeIndex = findInstanceActive(state.instances) - state.instances[activeIndex].push.decode.loading = false - state.instances[activeIndex].push.decode.value = action.payload.disable - }) - .addCase(updateInstancePushDecode.rejected, state => { - const activeIndex = findInstanceActive(state.instances) - state.instances[activeIndex].push.decode.loading = false - }) - .addCase(updateInstancePushDecode.pending, state => { - const activeIndex = findInstanceActive(state.instances) - state.instances[activeIndex].push.decode.loading = true + state.instances[activeIndex].push.decode = action.payload.disable }) // Update Instance Push Individual Alert .addCase(updateInstancePushAlert.fulfilled, (state, action) => { const activeIndex = findInstanceActive(state.instances) - state.instances[activeIndex].push.alerts[action.meta.arg.changed].loading = false state.instances[activeIndex].push.alerts = action.payload }) - .addCase(updateInstancePushAlert.rejected, (state, action) => { - const activeIndex = findInstanceActive(state.instances) - state.instances[activeIndex].push.alerts[action.meta.arg.changed].loading = false - }) - .addCase(updateInstancePushAlert.pending, (state, action) => { - const activeIndex = findInstanceActive(state.instances) - state.instances[activeIndex].push.alerts[action.meta.arg.changed].loading = true - }) // Check if frequently used emojis still exist .addCase(checkEmojis.fulfilled, (state, action) => { @@ -412,7 +378,6 @@ export const { updateInstanceNotificationsFilter, updateInstanceDraft, removeInstanceDraft, - clearPushLoading, disableAllPushes, updateInstanceTimelineLookback, updateInstanceMePage,