Fix toot action for #638

This commit is contained in:
xmflsct 2023-01-02 23:18:22 +01:00
parent 6dafbc96af
commit 4c6b8f0959
25 changed files with 298 additions and 71 deletions

View File

@ -19,7 +19,7 @@ target 'tooot' do
:path => config[:reactNativePath],
:hermes_enabled => true,
:fabric_enabled => flags[:fabric_enabled],
:flipper_configuration => FlipperConfiguration.disabled,
:flipper_configuration => FlipperConfiguration.enabled(["Debug"], { 'Flipper' => '0.159.0' }),
# An absolute path to your application root.
:app_path => "#{Pod::Config.instance.installation_root}/.."
)

View File

@ -1,5 +1,6 @@
PODS:
- boost (1.76.0)
- CocoaAsyncSocket (7.6.5)
- DoubleConversion (1.1.6)
- EXApplication (5.0.1):
- ExpoModulesCore
@ -52,6 +53,66 @@ PODS:
- React-Core (= 0.70.6)
- React-jsi (= 0.70.6)
- ReactCommon/turbomodule/core (= 0.70.6)
- Flipper (0.159.0):
- Flipper-Folly (~> 2.6)
- Flipper-Boost-iOSX (1.76.0.1.11)
- Flipper-DoubleConversion (3.2.0.1)
- Flipper-Fmt (7.1.7)
- Flipper-Folly (2.6.10):
- Flipper-Boost-iOSX
- Flipper-DoubleConversion
- Flipper-Fmt (= 7.1.7)
- Flipper-Glog
- libevent (~> 2.1.12)
- OpenSSL-Universal (= 1.1.1100)
- Flipper-Glog (0.5.0.5)
- Flipper-PeerTalk (0.0.4)
- Flipper-RSocket (1.4.3):
- Flipper-Folly (~> 2.6)
- FlipperKit (0.159.0):
- FlipperKit/Core (= 0.159.0)
- FlipperKit/Core (0.159.0):
- Flipper (~> 0.159.0)
- FlipperKit/CppBridge
- FlipperKit/FBCxxFollyDynamicConvert
- FlipperKit/FBDefines
- FlipperKit/FKPortForwarding
- SocketRocket (~> 0.6.0)
- FlipperKit/CppBridge (0.159.0):
- Flipper (~> 0.159.0)
- FlipperKit/FBCxxFollyDynamicConvert (0.159.0):
- Flipper-Folly (~> 2.6)
- FlipperKit/FBDefines (0.159.0)
- FlipperKit/FKPortForwarding (0.159.0):
- CocoaAsyncSocket (~> 7.6)
- Flipper-PeerTalk (~> 0.0.4)
- FlipperKit/FlipperKitHighlightOverlay (0.159.0)
- FlipperKit/FlipperKitLayoutHelpers (0.159.0):
- FlipperKit/Core
- FlipperKit/FlipperKitHighlightOverlay
- FlipperKit/FlipperKitLayoutTextSearchable
- FlipperKit/FlipperKitLayoutIOSDescriptors (0.159.0):
- FlipperKit/Core
- FlipperKit/FlipperKitHighlightOverlay
- FlipperKit/FlipperKitLayoutHelpers
- YogaKit (~> 1.18)
- FlipperKit/FlipperKitLayoutPlugin (0.159.0):
- FlipperKit/Core
- FlipperKit/FlipperKitHighlightOverlay
- FlipperKit/FlipperKitLayoutHelpers
- FlipperKit/FlipperKitLayoutIOSDescriptors
- FlipperKit/FlipperKitLayoutTextSearchable
- YogaKit (~> 1.18)
- FlipperKit/FlipperKitLayoutTextSearchable (0.159.0)
- FlipperKit/FlipperKitNetworkPlugin (0.159.0):
- FlipperKit/Core
- FlipperKit/FlipperKitReactPlugin (0.159.0):
- FlipperKit/Core
- FlipperKit/FlipperKitUserDefaultsPlugin (0.159.0):
- FlipperKit/Core
- FlipperKit/SKIOSNetworkPlugin (0.159.0):
- FlipperKit/Core
- FlipperKit/FlipperKitNetworkPlugin
- fmt (6.2.1)
- glog (0.3.5)
- hermes-engine (0.70.6)
@ -68,6 +129,7 @@ PODS:
- MMKV (1.2.14):
- MMKVCore (~> 1.2.14)
- MMKVCore (1.2.14)
- OpenSSL-Universal (1.1.1100)
- RCT-Folly (2021.07.22.00):
- boost
- DoubleConversion
@ -300,6 +362,8 @@ PODS:
- React-Core
- react-native-cameraroll (5.2.0):
- React-Core
- react-native-flipper (0.176.1):
- React-Core
- react-native-image-picker (4.10.3):
- React-Core
- react-native-ios-context-menu (1.15.1):
@ -446,8 +510,11 @@ PODS:
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.13)
- Sentry/HybridSDK (7.31.3)
- SocketRocket (0.6.0)
- Swime (3.0.6)
- Yoga (1.14.0)
- YogaKit (1.18.1):
- Yoga (~> 1.14)
DEPENDENCIES:
- boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`)
@ -474,9 +541,31 @@ DEPENDENCIES:
- EXVideoThumbnails (from `../node_modules/expo-video-thumbnails/ios`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`)
- Flipper (= 0.159.0)
- Flipper-Boost-iOSX (= 1.76.0.1.11)
- Flipper-DoubleConversion (= 3.2.0.1)
- Flipper-Fmt (= 7.1.7)
- Flipper-Folly (= 2.6.10)
- Flipper-Glog (= 0.5.0.5)
- Flipper-PeerTalk (= 0.0.4)
- Flipper-RSocket (= 1.4.3)
- FlipperKit (= 0.159.0)
- FlipperKit/Core (= 0.159.0)
- FlipperKit/CppBridge (= 0.159.0)
- FlipperKit/FBCxxFollyDynamicConvert (= 0.159.0)
- FlipperKit/FBDefines (= 0.159.0)
- FlipperKit/FKPortForwarding (= 0.159.0)
- FlipperKit/FlipperKitHighlightOverlay (= 0.159.0)
- FlipperKit/FlipperKitLayoutPlugin (= 0.159.0)
- FlipperKit/FlipperKitLayoutTextSearchable (= 0.159.0)
- FlipperKit/FlipperKitNetworkPlugin (= 0.159.0)
- FlipperKit/FlipperKitReactPlugin (= 0.159.0)
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.159.0)
- FlipperKit/SKIOSNetworkPlugin (= 0.159.0)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- hermes-engine (from `../node_modules/react-native/sdks/hermes/hermes-engine.podspec`)
- libevent (~> 2.1.12)
- OpenSSL-Universal (= 1.1.1100)
- RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`)
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
@ -485,6 +574,7 @@ DEPENDENCIES:
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
- React-Codegen (from `build/generated/ios`)
- React-Core (from `../node_modules/react-native/`)
- React-Core/DevSupport (from `../node_modules/react-native/`)
- React-Core/RCTWebSocket (from `../node_modules/react-native/`)
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
@ -496,6 +586,7 @@ DEPENDENCIES:
- "react-native-blur (from `../node_modules/@react-native-community/blur`)"
- react-native-blurhash (from `../node_modules/react-native-blurhash`)
- "react-native-cameraroll (from `../node_modules/@react-native-camera-roll/camera-roll`)"
- react-native-flipper (from `../node_modules/react-native-flipper`)
- react-native-image-picker (from `../node_modules/react-native-image-picker`)
- react-native-ios-context-menu (from `../node_modules/react-native-ios-context-menu`)
- react-native-language-detection (from `../node_modules/react-native-language-detection`)
@ -531,15 +622,28 @@ DEPENDENCIES:
SPEC REPOS:
trunk:
- CocoaAsyncSocket
- Flipper
- Flipper-Boost-iOSX
- Flipper-DoubleConversion
- Flipper-Fmt
- Flipper-Folly
- Flipper-Glog
- Flipper-PeerTalk
- Flipper-RSocket
- FlipperKit
- fmt
- libevent
- libwebp
- MMKV
- MMKVCore
- OpenSSL-Universal
- SDWebImage
- SDWebImageWebPCoder
- Sentry
- SocketRocket
- Swime
- YogaKit
EXTERNAL SOURCES:
boost:
@ -630,6 +734,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-blurhash"
react-native-cameraroll:
:path: "../node_modules/@react-native-camera-roll/camera-roll"
react-native-flipper:
:path: "../node_modules/react-native-flipper"
react-native-image-picker:
:path: "../node_modules/react-native-image-picker"
react-native-ios-context-menu:
@ -697,6 +803,7 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
boost: a7c83b31436843459a1961bfd74b96033dc77234
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
EXApplication: 034b1c40a8e9fe1bff76a1e511ee90dff64ad834
EXAV: 9a45d37772c5329294c054a041dcc39931fc5032
@ -720,6 +827,15 @@ SPEC CHECKSUMS:
EXVideoThumbnails: 8b3e48f3716679dd0cbf949217a31eab5c555799
FBLazyVector: 48289402952f4f7a4e235de70a9a590aa0b79ef4
FBReactNativeSpec: dd1186fd05255e3457baa2f4ca65e94c2cd1e3ac
Flipper: dbc210f7008265335b812b2a5a1122b0300e5b64
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30
Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b
Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3
Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446
Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9
Flipper-RSocket: d9d9ade67cbecf6ac10730304bf5607266dd2541
FlipperKit: 57a0368f6a0416609fafe827f6a957ec3eff7cdc
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
hermes-engine: 2af7b7a59128f250adfd86f15aa1d5a2ecd39995
@ -727,6 +843,7 @@ SPEC CHECKSUMS:
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
MMKV: 9c4663aa7ca255d478ff10f2f5cb7d17c1651ccd
MMKVCore: 89f5c8a66bba2dcd551779dea4d412eeec8ff5bb
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda
RCTRequired: e1866f61af7049eb3d8e08e8b133abd38bc1ca7a
RCTTypeSafety: 27c2ac1b00609a432ced1ae701247593f07f901e
@ -745,6 +862,7 @@ SPEC CHECKSUMS:
react-native-blur: 50c9feabacbc5f49b61337ebc32192c6be7ec3c3
react-native-blurhash: add4df9a937b4e021a24bc67a0714f13e0bd40b7
react-native-cameraroll: 0ff04cc4e0ff5f19a94ff4313e5c8bc4503cd86d
react-native-flipper: 7e4b1c3fe1a2eecbe7304e5ff6b89231b3ec61dc
react-native-image-picker: 60f4246eb5bb7187fc15638a8c1f13abd3820695
react-native-ios-context-menu: b170594b4448c0cd10c79e13432216bac99de1ac
react-native-language-detection: f414937fa715108ab50a6269a3de0bcb95e4ceb0
@ -779,9 +897,11 @@ SPEC CHECKSUMS:
SDWebImage: b9a731e1d6307f44ca703b3976d18c24ca561e84
SDWebImageWebPCoder: 18503de6621dd2c420d680e33d46bf8e1d5169b0
Sentry: 08884c523575ec0f6690d94ed3ccb0246a1600bf
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b
Yoga: 99caf8d5ab45e9d637ee6e0174ec16fbbb01bcfc
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 05bf71d31ba782dfda5a6b47d38e98a6f6bc079a
PODFILE CHECKSUM: acb35c48d65adb321b72c9eb6ca2fb964ed29a55
COCOAPODS: 1.11.3

View File

@ -382,10 +382,16 @@
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-tooot/Pods-tooot-frameworks.sh",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-Glog/glog.framework/glog",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/double-conversion.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/glog.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/OpenSSL.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework",
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -110,6 +110,8 @@
"chalk": "^4.1.2",
"dotenv": "^16.0.3",
"react-native-clean-project": "^4.0.1",
"react-native-flipper": "^0.176.1",
"react-query-native-devtools": "^4.0.0",
"typescript": "^4.9.4"
},
"packageManager": "yarn@3.3.1",

View File

@ -31,6 +31,9 @@ declare namespace Mastodon {
source?: Source
suspended?: boolean
role?: Role
// Internal
_remote?: boolean
}
type Announcement = {
@ -389,6 +392,9 @@ declare namespace Mastodon {
username: string
acct: string
url: string
// Internal
_remote?: boolean
}
type Notification =

View File

@ -11,7 +11,7 @@ import Icon from './Icon'
import CustomText from './Text'
export interface Props {
account: Partial<Mastodon.Account> & Pick<Mastodon.Account, 'id' | 'acct' | 'username'>
account: Partial<Mastodon.Account> & Pick<Mastodon.Account, 'id' | 'acct' | 'username' | 'url'>
props?: PressableProps
}

View File

@ -168,10 +168,7 @@ const ParseHTML: React.FC<Props> = ({
matchedMention &&
!disableDetails &&
!sameAccount &&
navigation.push('Tab-Shared-Account', {
account: matchedMention,
isRemote: status?._remote
})
navigation.push('Tab-Shared-Account', { account: matchedMention })
}
children={node.children.map(unwrapNode).join('')}
/>

View File

@ -37,7 +37,6 @@ export interface Props {
disableDetails?: boolean
disableOnPress?: boolean
isConversation?: boolean
isRemote?: boolean
}
// When the poll is long
@ -48,8 +47,7 @@ const TimelineDefault: React.FC<Props> = ({
highlighted = false,
disableDetails = false,
disableOnPress = false,
isConversation = false,
isRemote = false
isConversation = false
}) => {
const status = item.reblog ? item.reblog : item
const rawContent = useRef<string[]>([])
@ -177,7 +175,7 @@ const TimelineDefault: React.FC<Props> = ({
disableDetails,
disableOnPress,
isConversation,
isRemote
isRemote: item._remote
}}
>
{disableOnPress ? (

View File

@ -38,7 +38,7 @@ const TimelineActioned: React.FC<Props> = ({ action, isNotification, ...rest })
)
const onPress = () =>
navigation.push('Tab-Shared-Account', { account, isRemote: status?._remote })
navigation.push('Tab-Shared-Account', { account })
const children = () => {
switch (action) {

View File

@ -114,7 +114,8 @@ const TimelineActions: React.FC = () => {
status,
payload: {
type: 'reblogged',
visibility: 'public'
visibility: 'public',
to: true
}
})
break
@ -126,7 +127,8 @@ const TimelineActions: React.FC = () => {
status,
payload: {
type: 'reblogged',
visibility: 'unlisted'
visibility: 'unlisted',
to: true
}
})
break
@ -141,7 +143,8 @@ const TimelineActions: React.FC = () => {
status,
payload: {
type: 'reblogged',
visibility: 'public'
visibility: 'public',
to: false
}
})
}
@ -153,7 +156,8 @@ const TimelineActions: React.FC = () => {
rootQueryKey,
status,
payload: {
type: 'favourited'
type: 'favourited',
to: !status.favourited
}
})
}
@ -164,7 +168,8 @@ const TimelineActions: React.FC = () => {
rootQueryKey,
status,
payload: {
type: 'bookmarked'
type: 'bookmarked',
to: !status.bookmarked
}
})
}

View File

@ -32,7 +32,7 @@ const TimelineAvatar: React.FC<Props> = ({ account }) => {
})}
onPress={() =>
!disableOnPress &&
navigation.push('Tab-Shared-Account', { account: actualAccount, isRemote: status?._remote })
navigation.push('Tab-Shared-Account', { account: actualAccount })
}
uri={{ original: actualAccount.avatar, static: actualAccount.avatar_static }}
dimension={

View File

@ -86,7 +86,8 @@ const TimelineCard: React.FC = () => {
}, [])
const accountQuery = useAccountQuery({
id: isAccount?.style === 'default' ? isAccount.id : '',
account:
isAccount?.style === 'default' ? { id: isAccount.id, url: status.card.url } : undefined,
options: { enabled: false }
})
useEffect(() => {

View File

@ -30,7 +30,7 @@ const menuAccount = ({
}: {
type: 'status' | 'account' // Where the action is coming from
openChange: boolean
account?: Partial<Mastodon.Account> & Pick<Mastodon.Account, 'id' | 'username' | 'acct'>
account?: Partial<Mastodon.Account> & Pick<Mastodon.Account, 'id' | 'username' | 'acct' | 'url'>
status?: Mastodon.Status
queryKey?: QueryKeyTimeline
rootQueryKey?: QueryKeyTimeline
@ -47,10 +47,7 @@ const menuAccount = ({
setEnabled(true)
}
}, [openChange, enabled])
const { data: fetchedAccount } = useAccountQuery({
remoteUrl: account?.url,
options: { enabled: !!status?._remote && enabled }
})
const { data: fetchedAccount } = useAccountQuery({ account, options: { enabled } })
const actualAccount = status?._remote ? fetchedAccount : account
const { data, isFetched } = useRelationshipQuery({
id: actualAccount?.id,

View File

@ -197,7 +197,8 @@ const menuStatus = ({
rootQueryKey,
status,
payload: {
type: 'muted'
type: 'muted',
to: !status.muted
}
}),
disabled: false,
@ -221,7 +222,8 @@ const menuStatus = ({
rootQueryKey,
status,
payload: {
type: 'pinned'
type: 'pinned',
to: !status.pinned
}
}),
disabled: status.visibility !== 'public' && status.visibility !== 'unlisted',

View File

@ -24,15 +24,30 @@ import AccountNav from './Nav'
const TabSharedAccount: React.FC<TabSharedStackScreenProps<'Tab-Shared-Account'>> = ({
navigation,
route: {
params: { account, isRemote }
params: { account }
}
}) => {
const { t } = useTranslation('screenTabs')
const { colors, mode } = useTheme()
const { data, dataUpdatedAt } = useAccountQuery({
id: account.id,
...(isRemote && { remoteUrl: account.url })
account,
options: {
onSuccess: a => {
if (account._remote) {
setQueryKey([
queryKey[0],
{
...queryKey[1],
page: 'Account',
id: a.id,
exclude_reblogs: true,
only_media: false
}
])
}
}
}
})
const mShare = menuShare({ type: 'account', url: data?.url })
@ -87,7 +102,12 @@ const TabSharedAccount: React.FC<TabSharedStackScreenProps<'Tab-Shared-Account'>
const queryClient = useQueryClient()
const [queryKey, setQueryKey] = useState<QueryKeyTimeline>([
'Timeline',
{ page: 'Account', id: data?.id, exclude_reblogs: true, only_media: false }
{
page: 'Account',
id: account._remote ? data?.id : account.id,
exclude_reblogs: true,
only_media: false
}
])
const page = queryKey[1]
@ -174,7 +194,7 @@ const TabSharedAccount: React.FC<TabSharedStackScreenProps<'Tab-Shared-Account'>
<Timeline
queryKey={queryKey}
disableRefresh
queryOptions={{ enabled: isRemote ? !!data?.id : true }}
queryOptions={{ enabled: account._remote ? !!data?.id : true }}
customProps={{
renderItem: ({ item }) => <TimelineDefault item={item} queryKey={queryKey} />,
onScroll: ({ nativeEvent }) => (scrollY.value = nativeEvent.contentOffset.y),

View File

@ -9,6 +9,7 @@ import apiInstance from '@utils/api/instance'
import { getHost } from '@utils/helpers/urlMatcher'
import { TabSharedStackScreenProps } from '@utils/navigation/navigators'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
import { getAccountStorage } from '@utils/storage/actions'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import React, { useEffect, useRef, useState } from 'react'
@ -65,8 +66,8 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
const flRef = useRef<FlatList>(null)
const scrolled = useRef(false)
const finalData = useRef<Mastodon.Status[]>([
{ ...toot, _level: 0, _remote: toot._remote }
const finalData = useRef<(Mastodon.Status & { key?: string })[]>([
{ ...toot, _level: 0, key: 'cached' }
])
const highlightIndex = useRef<number>(0)
const queryKey: { local: QueryKeyTimeline; remote: QueryKeyTimeline } = {
@ -86,7 +87,7 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
const statuses: (Mastodon.Status & { _level?: number })[] = [
...context.body.ancestors,
toot,
{ ...toot },
...context.body.descendants
]
@ -115,8 +116,7 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
return
}
if (finalData.current.length < data.pages[0].body.length) {
// if the remote has been loaded first
if (finalData.current[0].key === 'cached') {
finalData.current = data.pages[0].body
if (!scrolled.current) {
@ -178,7 +178,7 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
const statuses: (Mastodon.Status & { _level?: number })[] = [
...context.ancestors,
toot,
{ ...toot },
...context.descendants
]
@ -198,7 +198,9 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
return { pages: [{ body: statuses }] }
},
{
enabled: toot.account.acct !== toot.account.username, // When on the same instance, these two values are the same
enabled:
['public', 'unlisted'].includes(toot.visibility) &&
getHost(toot.uri) !== getAccountStorage.string('auth.domain'),
staleTime: 0,
refetchOnMount: true,
onSuccess: data => {
@ -211,12 +213,25 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
finalData.current = data.pages[0].body.map(remote => {
const localMatch = finalData.current.find(local => local.uri === remote.uri)
if (localMatch) {
delete localMatch.key
return localMatch
} else {
remote._remote = true
remote.account._remote = true
remote.mentions = remote.mentions.map(mention => ({ ...mention, _remote: true }))
if (remote.reblog) {
remote.reblog.account._remote = true
remote.reblog.mentions = remote.mentions.map(mention => ({
...mention,
_remote: true
}))
}
return remote
}
})
setHasRemoteContent(true)
}
@ -274,9 +289,8 @@ const TabSharedToot: React.FC<TabSharedStackScreenProps<'Tab-Shared-Toot'>> = ({
item={item}
queryKey={item._remote ? queryKey.remote : queryKey.local}
rootQueryKey={rootQueryKey}
highlighted={toot.id === item.id}
isConversation={toot.id !== item.id}
isRemote={item._remote}
highlighted={toot.id === item.id || item.id === 'cached'}
isConversation={toot.id !== item.id && item.id !== 'cached'}
/>
{curr > 1 || next > 1
? [...new Array(curr)].map((_, i) => {

View File

@ -84,8 +84,7 @@ export type ScreenTabsScreenProps<T extends keyof ScreenTabsStackParamList> = Bo
export type TabSharedStackParamList = {
'Tab-Shared-Account': {
account: Partial<Mastodon.Account> & Pick<Mastodon.Account, 'id' | 'username' | 'acct'>
isRemote?: boolean
account: Pick<Mastodon.Account, 'id' | 'username' | 'acct' | 'url' | '_remote'>
}
'Tab-Shared-Account-In-Lists': {
account: Pick<Mastodon.Account, 'id' | 'username'>
@ -99,7 +98,7 @@ export type TabSharedStackParamList = {
detectedLanguage: string
}
'Tab-Shared-Report': {
account: Partial<Mastodon.Account> & Pick<Mastodon.Account, 'id' | 'acct' | 'username'>
account: Pick<Mastodon.Account, 'id' | 'acct' | 'username' | 'url'>
status?: Pick<Mastodon.Status, 'id' | '_remote' | 'uri'>
}
'Tab-Shared-Search': undefined

View File

@ -3,21 +3,24 @@ import apiInstance from '@utils/api/instance'
import { AxiosError } from 'axios'
import { SearchResult } from './search'
export type QueryKeyAccount = ['Account', { id?: Mastodon.Account['id']; remoteUrl?: string }]
export type QueryKeyAccount = [
'Account',
Pick<Mastodon.Account, 'id' | 'url' | '_remote'> | undefined
]
const accountQueryFunction = async ({ queryKey }: QueryFunctionContext<QueryKeyAccount>) => {
const { id, remoteUrl } = queryKey[1]
if (!id && !remoteUrl) return Promise.reject()
const key = queryKey[1]
if (!key) return Promise.reject()
let matchedId = id
let matchedId = key.id
if (remoteUrl) {
if (key._remote) {
await apiInstance<SearchResult>({
version: 'v2',
method: 'get',
url: 'search',
params: {
q: remoteUrl,
q: key.url,
type: 'accounts',
limit: 1,
resolve: true
@ -25,7 +28,7 @@ const accountQueryFunction = async ({ queryKey }: QueryFunctionContext<QueryKeyA
})
.then(res => {
const account = res.body.accounts[0]
if (account.url !== remoteUrl) {
if (account.url !== key.url) {
return Promise.reject()
} else {
matchedId = account.id
@ -44,11 +47,23 @@ const accountQueryFunction = async ({ queryKey }: QueryFunctionContext<QueryKeyA
const useAccountQuery = ({
options,
...queryKeyParams
}: QueryKeyAccount[1] & {
}: { account?: QueryKeyAccount[1] } & {
options?: UseQueryOptions<Mastodon.Account, AxiosError>
}) => {
const queryKey: QueryKeyAccount = ['Account', { ...queryKeyParams }]
return useQuery(queryKey, accountQueryFunction, { ...options })
const queryKey: QueryKeyAccount = [
'Account',
queryKeyParams.account
? {
id: queryKeyParams.account.id,
url: queryKeyParams.account.url,
_remote: queryKeyParams.account._remote
}
: undefined
]
return useQuery(queryKey, accountQueryFunction, {
...options,
enabled: (queryKeyParams.account?._remote ? !!queryKeyParams.account : true) && options?.enabled
})
}
/* ----- */

View File

@ -18,4 +18,9 @@ const queryClient = new QueryClient({
}
})
// @ts-ignore
import('react-query-native-devtools').then(({ addPlugin }) => {
addPlugin({ queryClient })
})
export default queryClient

View File

@ -20,7 +20,7 @@ export type SearchResult = {
const queryFunction = async ({ queryKey }: QueryFunctionContext<QueryKeySearch>) => {
const { type, term, limit = 20 } = queryKey[1]
if (!term?.length) {
return Promise.reject()
return Promise.reject('Empty search term')
}
const res = await apiInstance<SearchResult>({
version: 'v2',
@ -59,6 +59,6 @@ export const searchFetchToot = (uri: Mastodon.Status['uri']): Promise<Mastodon.S
}
})
.then(res => res.body.statuses[0])
.catch(() => {})
.catch(err => console.warn(err))
export { useSearchQuery }

View File

@ -37,11 +37,11 @@ const useFollowedTagsQuery = (
})
},
{
enabled: canFollowTags,
staleTime: Infinity,
cacheTime: Infinity,
...params?.options,
...infinitePageParams,
enabled: canFollowTags && params?.options?.enabled,
onSuccess: data => {
setAccountStorage([
{

View File

@ -131,7 +131,7 @@ const queryFunction = async ({ queryKey, pageParam }: QueryFunctionContext<Query
})
case 'Account':
if (!page.id) return Promise.reject()
if (!page.id) return Promise.reject('Timeline query account id not provided')
if (page.exclude_reblogs) {
if (pageParam && pageParam.hasOwnProperty('max_id')) {
@ -214,7 +214,7 @@ const queryFunction = async ({ queryKey, pageParam }: QueryFunctionContext<Query
params
})
default:
return Promise.reject()
return Promise.reject('Timeline query no page matched')
}
}
@ -253,11 +253,17 @@ export type MutationVarsTimelineUpdateStatusProperty = {
status: Mastodon.Status
payload:
| {
type: 'bookmarked' | 'muted' | 'pinned' | 'favourited'
type: 'bookmarked' | 'muted' | 'pinned'
to: boolean
}
| {
type: 'favourited'
to: boolean
}
| {
type: 'reblogged'
visibility: 'public' | 'unlisted'
to: boolean
}
| {
type: 'poll'
@ -340,7 +346,7 @@ const mutationFunction = async (params: MutationVarsTimeline) => {
if (fetched) {
tootId = fetched.id
} else {
return Promise.reject()
return Promise.reject('Fetching for remote toot failed')
}
}
const body = new FormData()
@ -349,7 +355,7 @@ const mutationFunction = async (params: MutationVarsTimeline) => {
}
return apiInstance<Mastodon.Status>({
method: 'post',
url: `statuses/${tootId}/${params.status[params.payload.type] ? '' : 'un'}${
url: `statuses/${tootId}/${params.payload.to ? '' : 'un'}${
MapPropertyToUrl[params.payload.type]
}`,
...(params.payload.type === 'reblogged' && { body })

View File

@ -9,10 +9,11 @@ const updateStatusProperty = ({
payload,
poll
}: MutationVarsTimelineUpdateStatusProperty & { poll?: Mastodon.Poll }) => {
for (const key of [queryKey, rootQueryKey]) {
for (const key of [queryKey]) {
if (!key) continue
queryClient.setQueryData<InfiniteData<TimelineData> | undefined>(key, old => {
console.log('key', key)
if (old) {
let foundToot: Mastodon.Status | undefined = undefined
old.pages = old.pages.map(page => {
@ -25,7 +26,6 @@ const updateStatusProperty = ({
? last_status.reblog.id === status.id
: last_status?.id === status.id
)?.last_status
return page
} else if (typeof (page.body as Mastodon.Notification[])[0].type === 'string') {
foundToot = (page.body as Mastodon.Notification[]).find(no =>
no.status?.reblog ? no.status.reblog.id === status.id : no.status?.id === status.id
@ -41,6 +41,8 @@ const updateStatusProperty = ({
})
if (foundToot) {
const toot = foundToot as Mastodon.Status
console.log('updating', toot.id)
enum MapPropertyToCount {
favourited = 'favourites_count',
reblogged = 'reblogs_count'
@ -48,18 +50,19 @@ const updateStatusProperty = ({
switch (payload.type) {
case 'poll':
status.poll = poll
toot.poll = poll
break
default:
status[payload.type] =
typeof status[payload.type] === 'boolean' ? !status[payload.type] : true
console.log('11', toot[payload.type])
toot[payload.type] = payload.to
console.log('22', toot[payload.type])
switch (payload.type) {
case 'favourited':
case 'reblogged':
if (typeof status[payload.type] === 'boolean' && status[payload.type]) {
status[MapPropertyToCount[payload.type]]--
if (payload.to) {
toot[MapPropertyToCount[payload.type]]++
} else {
status[MapPropertyToCount[payload.type]]++
toot[MapPropertyToCount[payload.type]]--
}
break
}

View File

@ -212,7 +212,7 @@ export const generateAccountKey = ({
export const setAccount = async (account: string) => {
storage.account = new MMKV({ id: account })
setGlobalStorage('account.active', account)
await queryClient.resetQueries()
queryClient.clear()
}
export const removeAccount = async (account: string) => {

View File

@ -5987,6 +5987,13 @@ __metadata:
languageName: node
linkType: hard
"flatted@npm:^3.2.4":
version: 3.2.7
resolution: "flatted@npm:3.2.7"
checksum: 427633049d55bdb80201c68f7eb1cbd533e03eac541f97d3aecab8c5526f12a20ccecaeede08b57503e772c769e7f8680b37e8d482d1e5f8d7e2194687f9ea35
languageName: node
linkType: hard
"flow-parser@npm:0.*":
version: 0.196.3
resolution: "flow-parser@npm:0.196.3"
@ -9509,6 +9516,16 @@ __metadata:
languageName: node
linkType: hard
"react-native-flipper@npm:^0.176.1":
version: 0.176.1
resolution: "react-native-flipper@npm:0.176.1"
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-native: ">0.62.0"
checksum: f8ba597190baaed791a73d474ab8c2410048025f6bf8b1e49b5b64b71f08453d50fa118113a4c37e5fd8bb1c7700f8afe84671afeab6ad912a5f0c4da41a35be
languageName: node
linkType: hard
"react-native-gesture-handler@npm:~2.8.0":
version: 2.8.0
resolution: "react-native-gesture-handler@npm:2.8.0"
@ -9742,6 +9759,18 @@ __metadata:
languageName: node
linkType: hard
"react-query-native-devtools@npm:^4.0.0":
version: 4.0.0
resolution: "react-query-native-devtools@npm:4.0.0"
dependencies:
flatted: ^3.2.4
peerDependencies:
react-native-flipper: ^0.127.0
react-query: ^3.34.6
checksum: 7da16b14a59ac19805c315a25ab2c090cc277afe22aee412a743eda5296f282a91c0b35a269d015fbf27781e9c8b65c1a642a6fd5fc258a9318821a27c6da652
languageName: node
linkType: hard
"react-redux@npm:^8.0.5":
version: 8.0.5
resolution: "react-redux@npm:8.0.5"
@ -11272,6 +11301,7 @@ __metadata:
react-native-fast-image: ^8.6.3
react-native-feather: ^1.1.2
react-native-flash-message: ^0.3.1
react-native-flipper: ^0.176.1
react-native-gesture-handler: ~2.8.0
react-native-image-picker: ^4.10.3
react-native-ios-context-menu: ^1.15.1
@ -11286,6 +11316,7 @@ __metadata:
react-native-svg: ^13.6.0
react-native-swipe-list-view: ^3.2.9
react-native-tab-view: ^3.3.4
react-query-native-devtools: ^4.0.0
react-redux: ^8.0.5
rn-placeholder: ^3.0.3
typescript: ^4.9.4