From 700b9ad4336aafc76515c28d28070c3ffef30232 Mon Sep 17 00:00:00 2001 From: Zhiyuan Zheng Date: Fri, 5 Feb 2021 13:45:02 +0100 Subject: [PATCH] Support max_toot_chars See this commit of how to supply this value in API response. `instance_serializer.rb` https://github.com/pullopen/mastodon/commit/2bf275ba3b81e4c28d817511407680b0b7abc7fe --- src/@types/mastodon.d.ts | 3 +++ src/components/Instance.tsx | 2 +- src/components/Instance/Auth.tsx | 7 ++++--- src/screens/Compose.tsx | 18 +++++++++++------- src/store.ts | 23 +++++++++++++++++++---- src/utils/slices/instancesSlice.ts | 8 ++++++++ 6 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/@types/mastodon.d.ts b/src/@types/mastodon.d.ts index e74b4191..57ce762c 100644 --- a/src/@types/mastodon.d.ts +++ b/src/@types/mastodon.d.ts @@ -290,6 +290,9 @@ declare namespace Mastodon { // Others thumbnail?: string contact_account?: Account + + // Custom + max_toot_chars?: number } type Mention = { diff --git a/src/components/Instance.tsx b/src/components/Instance.tsx index a1362352..4dbf386a 100644 --- a/src/components/Instance.tsx +++ b/src/components/Instance.tsx @@ -149,7 +149,7 @@ const ComponentInstance: React.FC = ({ { + ({ instanceDomain, instance, appData, goBack }: Props) => { const redirectUri = AuthSession.makeRedirectUri({ native: 'tooot://instance-auth', useProxy: false @@ -65,7 +65,8 @@ const InstanceAuth = React.memo( localAddInstance({ url: instanceDomain, token: accessToken, - uri: instanceUri, + uri: instance.uri, + max_toot_chars: instance.max_toot_chars, appData }) ) diff --git a/src/screens/Compose.tsx b/src/screens/Compose.tsx index 74a625d8..0b0b6c0f 100644 --- a/src/screens/Compose.tsx +++ b/src/screens/Compose.tsx @@ -7,7 +7,10 @@ import formatText from '@screens/Compose/formatText' import ComposeRoot from '@screens/Compose/Root' import { QueryKeyTimeline } from '@utils/queryHooks/timeline' import { updateStoreReview } from '@utils/slices/contextsSlice' -import { getLocalAccount } from '@utils/slices/instancesSlice' +import { + getLocalAccount, + getLocalMaxTootChar +} from '@utils/slices/instancesSlice' import { StyleConstants } from '@utils/styles/constants' import { useTheme } from '@utils/styles/ThemeManager' import React, { useCallback, useEffect, useReducer, useState } from 'react' @@ -23,7 +26,7 @@ import { import { SafeAreaView } from 'react-native-safe-area-context' import { createNativeStackNavigator } from 'react-native-screens/native-stack' import { useQueryClient } from 'react-query' -import { useDispatch } from 'react-redux' +import { useDispatch, useSelector } from 'react-redux' import * as Sentry from 'sentry-expo' import ComposeEditAttachment from './Compose/EditAttachment' import ComposeContext from './Compose/utils/createContext' @@ -110,6 +113,7 @@ const ScreenCompose: React.FC = ({ } }, [params?.type]) + const maxTootChars = useSelector(getLocalMaxTootChar) const totalTextCount = (composeState.spoiler.active ? composeState.spoiler.count : 0) + composeState.text.count @@ -160,14 +164,14 @@ const ScreenCompose: React.FC = ({ style={[ styles.count, { - color: totalTextCount > 500 ? theme.red : theme.secondary + color: totalTextCount > maxTootChars ? theme.red : theme.secondary } ]} > - {totalTextCount} / 500 + {totalTextCount} / {maxTootChars} ), - [totalTextCount] + [totalTextCount, maxTootChars] ) const dispatch = useDispatch() const headerRight = useCallback( @@ -217,14 +221,14 @@ const ScreenCompose: React.FC = ({ loading={composeState.posting} disabled={ composeState.text.raw.length < 1 || - totalTextCount > 500 || + totalTextCount > maxTootChars || (composeState.attachments.uploads.length > 0 && composeState.attachments.uploads.filter(upload => upload.uploading) .length > 0) } /> ), - [totalTextCount, composeState] + [totalTextCount, maxTootChars, composeState] ) return ( diff --git a/src/store.ts b/src/store.ts index 81841408..5a5b2469 100644 --- a/src/store.ts +++ b/src/store.ts @@ -6,9 +6,9 @@ import { getDefaultMiddleware } from '@reduxjs/toolkit' import contextsSlice from '@utils/slices/contextsSlice' -import instancesSlice from '@utils/slices/instancesSlice' +import instancesSlice, { InstancesState } from '@utils/slices/instancesSlice' import settingsSlice from '@utils/slices/settingsSlice' -import { persistReducer, persistStore } from 'redux-persist' +import { createMigrate, persistReducer, persistStore } from 'redux-persist' const secureStorage = createSecureStore() @@ -20,11 +20,26 @@ const contextsPersistConfig = { storage: AsyncStorage } +const instancesMigration = { + 2: (state: InstancesState) => { + return { + ...state, + local: { + ...state.local, + instances: state.local.instances.map(instance => { + instance.max_toot_chars = 500 + return instance + }) + } + } + } +} const instancesPersistConfig = { key: 'instances', prefix, - version: 1, - storage: secureStorage + version: 2, + storage: secureStorage, + migrate: createMigrate(instancesMigration, { debug: true }) } const settingsPersistConfig = { diff --git a/src/utils/slices/instancesSlice.ts b/src/utils/slices/instancesSlice.ts index f53e870f..1457845d 100644 --- a/src/utils/slices/instancesSlice.ts +++ b/src/utils/slices/instancesSlice.ts @@ -13,6 +13,7 @@ export type InstanceLocal = { url: string token: string uri: Mastodon.Instance['uri'] + max_toot_chars: number account: { id: Mastodon.Account['id'] acct: Mastodon.Account['acct'] @@ -54,11 +55,13 @@ export const localAddInstance = createAsyncThunk( url, token, uri, + max_toot_chars = 500, appData }: { url: InstanceLocal['url'] token: InstanceLocal['token'] uri: Mastodon.Instance['uri'] + max_toot_chars?: number appData: InstanceLocal['appData'] }): Promise<{ type: 'add' | 'overwrite'; data: InstanceLocal }> => { const { store } = require('@root/store') @@ -107,6 +110,7 @@ export const localAddInstance = createAsyncThunk( url, token, uri, + max_toot_chars, account: { id, acct, @@ -273,6 +277,10 @@ export const getLocalUri = ({ instances: { local } }: RootState) => local.activeIndex !== null ? local.instances[local.activeIndex].uri : undefined +export const getLocalMaxTootChar = ({ instances: { local } }: RootState) => + local.activeIndex !== null + ? local.instances[local.activeIndex].max_toot_chars + : 500 export const getLocalAccount = ({ instances: { local } }: RootState) => local.activeIndex !== null ? local.instances[local.activeIndex].account