mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
Basic new react-navigation types
This commit is contained in:
173
src/utils/navigation/navigators.ts
Normal file
173
src/utils/navigation/navigators.ts
Normal file
@@ -0,0 +1,173 @@
|
||||
import { BottomTabScreenProps } from '@react-navigation/bottom-tabs'
|
||||
import { NavigatorScreenParams } from '@react-navigation/native'
|
||||
import { NativeStackScreenProps } from '@react-navigation/native-stack'
|
||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
|
||||
export type RootStackParamList = {
|
||||
'Screen-Tabs': NavigatorScreenParams<ScreenTabsStackParamList>
|
||||
'Screen-Actions':
|
||||
| {
|
||||
type: 'status'
|
||||
queryKey: QueryKeyTimeline
|
||||
rootQueryKey?: QueryKeyTimeline
|
||||
status: Mastodon.Status
|
||||
}
|
||||
| {
|
||||
type: 'account'
|
||||
account: Mastodon.Account
|
||||
}
|
||||
| {
|
||||
type: 'notifications_filter'
|
||||
}
|
||||
'Screen-Announcements': { showAll: boolean }
|
||||
'Screen-Compose':
|
||||
| {
|
||||
type: 'edit'
|
||||
incomingStatus: Mastodon.Status
|
||||
replyToStatus?: Mastodon.Status
|
||||
queryKey?: [
|
||||
'Timeline',
|
||||
{
|
||||
page: App.Pages
|
||||
hashtag?: Mastodon.Tag['name']
|
||||
list?: Mastodon.List['id']
|
||||
toot?: Mastodon.Status['id']
|
||||
account?: Mastodon.Account['id']
|
||||
}
|
||||
]
|
||||
}
|
||||
| {
|
||||
type: 'reply'
|
||||
incomingStatus: Mastodon.Status
|
||||
accts: Mastodon.Account['acct'][]
|
||||
queryKey?: [
|
||||
'Timeline',
|
||||
{
|
||||
page: App.Pages
|
||||
hashtag?: Mastodon.Tag['name']
|
||||
list?: Mastodon.List['id']
|
||||
toot?: Mastodon.Status['id']
|
||||
account?: Mastodon.Account['id']
|
||||
}
|
||||
]
|
||||
}
|
||||
| {
|
||||
type: 'conversation'
|
||||
accts: Mastodon.Account['acct'][]
|
||||
}
|
||||
| undefined
|
||||
'Screen-ImagesViewer': {
|
||||
imageUrls: {
|
||||
id: Mastodon.Attachment['id']
|
||||
preview_url: Mastodon.AttachmentImage['preview_url']
|
||||
url: Mastodon.AttachmentImage['url']
|
||||
remote_url?: Mastodon.AttachmentImage['remote_url']
|
||||
blurhash: Mastodon.AttachmentImage['blurhash']
|
||||
width?: number
|
||||
height?: number
|
||||
}[]
|
||||
id: Mastodon.Attachment['id']
|
||||
}
|
||||
}
|
||||
export type RootStackScreenProps<
|
||||
T extends keyof RootStackParamList
|
||||
> = NativeStackScreenProps<RootStackParamList, T>
|
||||
|
||||
export type ScreenComposeStackParamList = {
|
||||
'Screen-Compose-Root': undefined
|
||||
'Screen-Compose-EditAttachment': { index: number }
|
||||
'Screen-Compose-DraftsList': { timestamp: number }
|
||||
}
|
||||
export type ScreenComposeStackScreenProps<
|
||||
T extends keyof ScreenComposeStackParamList
|
||||
> = NativeStackScreenProps<ScreenComposeStackParamList, T>
|
||||
|
||||
export type ScreenTabsStackParamList = {
|
||||
'Tab-Local': NavigatorScreenParams<TabLocalStackParamList>
|
||||
'Tab-Public': NavigatorScreenParams<TabPublicStackParamList>
|
||||
'Tab-Compose': undefined
|
||||
'Tab-Notifications': NavigatorScreenParams<TabNotificationsStackParamList>
|
||||
'Tab-Me': NavigatorScreenParams<TabMeStackParamList>
|
||||
}
|
||||
export type ScreenTabsScreenProps<
|
||||
T extends keyof ScreenTabsStackParamList
|
||||
> = BottomTabScreenProps<ScreenTabsStackParamList, T>
|
||||
|
||||
export type TabSharedStackParamList = {
|
||||
'Tab-Shared-Account': {
|
||||
account: Mastodon.Account | Mastodon.Mention
|
||||
}
|
||||
'Tab-Shared-Attachments': { account: Mastodon.Account }
|
||||
'Tab-Shared-Hashtag': {
|
||||
hashtag: Mastodon.Tag['name']
|
||||
}
|
||||
'Tab-Shared-Search': { text: string | undefined }
|
||||
'Tab-Shared-Toot': {
|
||||
toot: Mastodon.Status
|
||||
rootQueryKey?: QueryKeyTimeline
|
||||
}
|
||||
'Tab-Shared-Users':
|
||||
| {
|
||||
reference: 'accounts'
|
||||
id: Mastodon.Account['id']
|
||||
type: 'following' | 'followers'
|
||||
count: number
|
||||
}
|
||||
| {
|
||||
reference: 'statuses'
|
||||
id: Mastodon.Status['id']
|
||||
type: 'reblogged_by' | 'favourited_by'
|
||||
count: number
|
||||
}
|
||||
}
|
||||
export type TabSharedStackScreenProps<
|
||||
T extends keyof TabSharedStackParamList
|
||||
> = NativeStackScreenProps<TabSharedStackParamList, T>
|
||||
|
||||
export type TabLocalStackParamList = {
|
||||
'Tab-Local-Root': undefined
|
||||
} & TabSharedStackParamList
|
||||
|
||||
export type TabPublicStackParamList = {
|
||||
'Tab-Public-Root': undefined
|
||||
} & TabSharedStackParamList
|
||||
|
||||
export type TabNotificationsStackParamList = {
|
||||
'Tab-Notifications-Root': undefined
|
||||
} & TabSharedStackParamList
|
||||
|
||||
export type TabMeStackParamList = {
|
||||
'Tab-Me-Root': undefined
|
||||
'Tab-Me-Bookmarks': undefined
|
||||
'Tab-Me-Conversations': undefined
|
||||
'Tab-Me-Favourites': undefined
|
||||
'Tab-Me-Lists': undefined
|
||||
'Tab-Me-Lists-List': {
|
||||
list: Mastodon.List['id']
|
||||
title: Mastodon.List['title']
|
||||
}
|
||||
'Tab-Me-Profile': undefined
|
||||
'Tab-Me-Push': undefined
|
||||
'Tab-Me-Settings': undefined
|
||||
'Tab-Me-Settings-Fontsize': undefined
|
||||
'Tab-Me-Switch': undefined
|
||||
} & TabSharedStackParamList
|
||||
export type TabMeStackScreenProps<
|
||||
T extends keyof TabMeStackParamList
|
||||
> = NativeStackScreenProps<TabMeStackParamList, T>
|
||||
|
||||
export type TabMeProfileStackParamList = {
|
||||
'Tab-Me-Profile-Root': undefined
|
||||
'Tab-Me-Profile-Name': {
|
||||
display_name: Mastodon.Account['display_name']
|
||||
}
|
||||
'Tab-Me-Profile-Note': {
|
||||
note: Mastodon.Source['note']
|
||||
}
|
||||
'Tab-Me-Profile-Fields': {
|
||||
fields?: Mastodon.Source['fields']
|
||||
}
|
||||
}
|
||||
export type TabMeProfileStackScreenProps<
|
||||
T extends keyof TabMeProfileStackParamList
|
||||
> = NativeStackScreenProps<TabMeProfileStackParamList, T>
|
@@ -1,7 +1,7 @@
|
||||
import apiGeneral from '@api/general'
|
||||
import apiTooot from '@api/tooot'
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { NavigationContainerRef } from '@react-navigation/native'
|
||||
import navigationRef from '@helpers/navigationRef'
|
||||
import { Dispatch } from '@reduxjs/toolkit'
|
||||
import { disableAllPushes, Instance } from '@utils/slices/instancesSlice'
|
||||
import * as Notifications from 'expo-notifications'
|
||||
@@ -9,20 +9,13 @@ import { useEffect } from 'react'
|
||||
import { TFunction } from 'react-i18next'
|
||||
|
||||
export interface Params {
|
||||
navigationRef: React.RefObject<NavigationContainerRef>
|
||||
mode: 'light' | 'dark'
|
||||
t: TFunction<'screens'>
|
||||
instances: Instance[]
|
||||
dispatch: Dispatch<any>
|
||||
}
|
||||
|
||||
const pushUseConnect = ({
|
||||
navigationRef,
|
||||
mode,
|
||||
t,
|
||||
instances,
|
||||
dispatch
|
||||
}: Params) => {
|
||||
const pushUseConnect = ({ mode, t, instances, dispatch }: Params) => {
|
||||
return useEffect(() => {
|
||||
const connect = async () => {
|
||||
const expoToken = (
|
||||
@@ -48,13 +41,13 @@ const pushUseConnect = ({
|
||||
message: t('pushError.message'),
|
||||
description: t('pushError.description'),
|
||||
onPress: () => {
|
||||
navigationRef.current?.navigate('Screen-Tabs', {
|
||||
navigationRef.navigate('Screen-Tabs', {
|
||||
screen: 'Tab-Me',
|
||||
params: {
|
||||
screen: 'Tab-Me-Root'
|
||||
}
|
||||
})
|
||||
navigationRef.current?.navigate('Screen-Tabs', {
|
||||
navigationRef.navigate('Screen-Tabs', {
|
||||
screen: 'Tab-Me',
|
||||
params: {
|
||||
screen: 'Tab-Me-Settings'
|
||||
|
@@ -1,11 +1,8 @@
|
||||
import apiInstance from '@api/instance'
|
||||
import { NavigationContainerRef } from '@react-navigation/native'
|
||||
import navigationRef from '@helpers/navigationRef'
|
||||
|
||||
const pushUseNavigate = (
|
||||
navigationRef: React.RefObject<NavigationContainerRef>,
|
||||
id?: Mastodon.Notification['id']
|
||||
) => {
|
||||
navigationRef.current?.navigate('Screen-Tabs', {
|
||||
const pushUseNavigate = (id?: Mastodon.Notification['id']) => {
|
||||
navigationRef.navigate('Screen-Tabs', {
|
||||
screen: 'Tab-Notifications',
|
||||
params: {
|
||||
screen: 'Tab-Notifications-Root'
|
||||
@@ -21,7 +18,7 @@ const pushUseNavigate = (
|
||||
url: `notifications/${id}`
|
||||
}).then(({ body }) => {
|
||||
if (body.status) {
|
||||
navigationRef.current?.navigate('Screen-Tabs', {
|
||||
navigationRef.navigate('Screen-Tabs', {
|
||||
screen: 'Tab-Notifications',
|
||||
params: {
|
||||
screen: 'Tab-Shared-Toot',
|
||||
|
@@ -1,5 +1,4 @@
|
||||
import { displayMessage } from '@components/Message'
|
||||
import { NavigationContainerRef } from '@react-navigation/native'
|
||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
import { Instance, updateInstanceActive } from '@utils/slices/instancesSlice'
|
||||
import * as Notifications from 'expo-notifications'
|
||||
@@ -10,12 +9,11 @@ import { useDispatch } from 'react-redux'
|
||||
import pushUseNavigate from './useNavigate'
|
||||
|
||||
export interface Params {
|
||||
navigationRef: React.RefObject<NavigationContainerRef>
|
||||
queryClient: QueryClient
|
||||
instances: Instance[]
|
||||
}
|
||||
|
||||
const pushUseReceive = ({ navigationRef, queryClient, instances }: Params) => {
|
||||
const pushUseReceive = ({ queryClient, instances }: Params) => {
|
||||
const dispatch = useDispatch()
|
||||
|
||||
return useEffect(() => {
|
||||
@@ -46,7 +44,7 @@ const pushUseReceive = ({ navigationRef, queryClient, instances }: Params) => {
|
||||
if (notificationIndex !== -1) {
|
||||
dispatch(updateInstanceActive(instances[notificationIndex]))
|
||||
}
|
||||
pushUseNavigate(navigationRef, payloadData.notification_id)
|
||||
pushUseNavigate(payloadData.notification_id)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import { NavigationContainerRef } from '@react-navigation/native'
|
||||
import { Dispatch } from '@reduxjs/toolkit'
|
||||
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
|
||||
import { Instance, updateInstanceActive } from '@utils/slices/instancesSlice'
|
||||
@@ -9,18 +8,12 @@ import { QueryClient } from 'react-query'
|
||||
import pushUseNavigate from './useNavigate'
|
||||
|
||||
export interface Params {
|
||||
navigationRef: React.RefObject<NavigationContainerRef>
|
||||
queryClient: QueryClient
|
||||
instances: Instance[]
|
||||
dispatch: Dispatch<any>
|
||||
}
|
||||
|
||||
const pushUseRespond = ({
|
||||
navigationRef,
|
||||
queryClient,
|
||||
instances,
|
||||
dispatch
|
||||
}: Params) => {
|
||||
const pushUseRespond = ({ queryClient, instances, dispatch }: Params) => {
|
||||
return useEffect(() => {
|
||||
const subscription = Notifications.addNotificationResponseReceivedListener(
|
||||
({ notification }) => {
|
||||
@@ -44,7 +37,7 @@ const pushUseRespond = ({
|
||||
if (notificationIndex !== -1) {
|
||||
dispatch(updateInstanceActive(instances[notificationIndex]))
|
||||
}
|
||||
pushUseNavigate(navigationRef, payloadData.notification_id)
|
||||
pushUseNavigate(payloadData.notification_id)
|
||||
}
|
||||
)
|
||||
return () => subscription.remove()
|
||||
|
@@ -87,7 +87,9 @@ const queryFunction = async ({
|
||||
}
|
||||
})
|
||||
} else {
|
||||
const res1 = await apiInstance<(Mastodon.Status & { _pinned: boolean} )[]>({
|
||||
const res1 = await apiInstance<
|
||||
(Mastodon.Status & { _pinned: boolean })[]
|
||||
>({
|
||||
method: 'get',
|
||||
url: `accounts/${account}/statuses`,
|
||||
params: {
|
||||
@@ -105,7 +107,7 @@ const queryFunction = async ({
|
||||
exclude_replies: 'true'
|
||||
}
|
||||
})
|
||||
return await {
|
||||
return {
|
||||
body: uniqBy([...res1.body, ...res2.body], 'id'),
|
||||
...(res2.links.next && { links: { next: res2.links.next } })
|
||||
}
|
||||
@@ -175,8 +177,12 @@ const queryFunction = async ({
|
||||
method: 'get',
|
||||
url: `statuses/${toot}/context`
|
||||
})
|
||||
return await {
|
||||
body: [...res2_1.body.ancestors, res1_1.body, ...res2_1.body.descendants]
|
||||
return {
|
||||
body: [
|
||||
...res2_1.body.ancestors,
|
||||
res1_1.body,
|
||||
...res2_1.body.descendants
|
||||
]
|
||||
}
|
||||
default:
|
||||
return Promise.reject()
|
||||
|
@@ -1,10 +1,11 @@
|
||||
import apiInstance from '@api/instance'
|
||||
import { TabSharedStackParamList } from '@utils/navigation/navigators'
|
||||
import { AxiosError } from 'axios'
|
||||
import { useInfiniteQuery, UseInfiniteQueryOptions } from 'react-query'
|
||||
|
||||
export type QueryKeyUsers = [
|
||||
'Users',
|
||||
Nav.TabSharedStackParamList['Tab-Shared-Users']
|
||||
TabSharedStackParamList['Tab-Shared-Users']
|
||||
]
|
||||
|
||||
const queryFunction = ({
|
||||
|
@@ -54,6 +54,13 @@ const addInstance = createAsyncThunk(
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
})
|
||||
|
||||
const { body: filters } = await apiGeneral<Mastodon.Filter[]>({
|
||||
method: 'get',
|
||||
domain,
|
||||
url: `api/v1/filters`,
|
||||
headers: { Authorization: `Bearer ${token}` }
|
||||
})
|
||||
|
||||
return Promise.resolve({
|
||||
type,
|
||||
data: {
|
||||
@@ -70,6 +77,7 @@ const addInstance = createAsyncThunk(
|
||||
avatarStatic: avatar_static,
|
||||
preferences
|
||||
},
|
||||
filters,
|
||||
notifications_filter: {
|
||||
follow: true,
|
||||
favourite: true,
|
||||
|
@@ -12,7 +12,7 @@ export const updateInstancePushDecode = createAsyncThunk(
|
||||
async (
|
||||
disable: boolean,
|
||||
{ getState }
|
||||
): Promise<Instance['push']['decode']['value']> => {
|
||||
): Promise<{ disable: Instance['push']['decode']['value'] }> => {
|
||||
const state = getState() as RootState
|
||||
const instance = getInstance(state)
|
||||
if (!instance?.url || !instance.account.id || !instance.push.keys) {
|
||||
@@ -89,6 +89,6 @@ export const updateInstancePushDecode = createAsyncThunk(
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.resolve(disable)
|
||||
return Promise.resolve({ disable })
|
||||
}
|
||||
)
|
||||
|
@@ -274,7 +274,7 @@ const instancesSlice = createSlice({
|
||||
.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
|
||||
state.instances[activeIndex].push.decode.value = action.payload.disable
|
||||
})
|
||||
.addCase(updateInstancePushDecode.rejected, state => {
|
||||
const activeIndex = findInstanceActive(state.instances)
|
||||
|
@@ -13,7 +13,7 @@ export const changeAnalytics = createAsyncThunk(
|
||||
'settings/changeAnalytics',
|
||||
async (newValue: SettingsState['analytics']) => {
|
||||
await Analytics.setAnalyticsCollectionEnabled(newValue)
|
||||
return newValue
|
||||
return { newValue }
|
||||
}
|
||||
)
|
||||
|
||||
@@ -75,7 +75,7 @@ const settingsSlice = createSlice({
|
||||
},
|
||||
extraReducers: builder => {
|
||||
builder.addCase(changeAnalytics.fulfilled, (state, action) => {
|
||||
state.analytics = action.payload
|
||||
state.analytics = action.payload.newValue
|
||||
})
|
||||
}
|
||||
})
|
||||
|
@@ -29,7 +29,7 @@ const versionSlice = createSlice({
|
||||
reducers: {},
|
||||
extraReducers: builder => {
|
||||
builder.addCase(retriveVersionLatest.fulfilled, (state, action) => {
|
||||
if (action.payload && Constants.manifest.version) {
|
||||
if (action.payload && Constants.manifest?.version) {
|
||||
if (parseInt(action.payload) > parseInt(Constants.manifest.version)) {
|
||||
state.update = true
|
||||
}
|
||||
|
Reference in New Issue
Block a user