1
0
mirror of https://github.com/tooot-app/app synced 2025-06-05 22:19:13 +02:00

MVP last read position

This commit is contained in:
Zhiyuan Zheng
2022-01-16 23:26:05 +01:00
parent 0b4a8ead84
commit 9a41dd2191
20 changed files with 446 additions and 87 deletions

View File

@@ -1,4 +1,5 @@
import { ContextsV0 } from './v0'
import { ContextsV1 } from './v1'
const contextsMigration = {
1: (state: ContextsV0) => {
@@ -10,6 +11,11 @@ const contextsMigration = {
announcements: { shown: false, unread: 0 }
}
})
},
2: (state: ContextsV1) => {
// @ts-ignore
delete state.mePage
return state
}
}

View File

@@ -0,0 +1,17 @@
export type ContextsV1 = {
storeReview: {
context: Readonly<number>
current: number
shown: boolean
}
publicRemoteNotice: {
context: Readonly<number>
current: number
hidden: boolean
}
previousTab: 'Tab-Local' | 'Tab-Public' | 'Tab-Notifications' | 'Tab-Me'
mePage: {
lists: { shown: boolean }
announcements: { shown: boolean; unread: number }
}
}

View File

@@ -1,6 +1,7 @@
import { InstanceV3 } from './v3'
import { InstanceV4 } from './v4'
import { InstanceV5 } from './v5'
import { InstanceV6 } from './v6'
const instancesMigration = {
4: (state: InstanceV3) => {
@@ -54,6 +55,20 @@ const instancesMigration = {
return { ...instance, configuration: undefined }
})
}
},
7: (state: InstanceV6) => {
return {
instances: state.instances.map(instance => {
return {
...instance,
timelinesLookback: {},
mePage: {
lists: { shown: false },
announcements: { shown: false, unread: 0 }
}
}
})
}
}
}

View File

@@ -0,0 +1,66 @@
import { ComposeStateDraft } from '@screens/Compose/utils/types'
type Instance = {
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
}
max_toot_chars?: number // To be deprecated in v4
configuration?: Mastodon.Instance['configuration']
filters: Mastodon.Filter[]
notifications_filter: {
follow: boolean
favourite: boolean
reblog: boolean
mention: boolean
poll: boolean
follow_request: 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
}
}
drafts: ComposeStateDraft[]
}
export type InstanceV6 = {
instances: Instance[]
}

View File

@@ -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 {
getInstanceNotificationsFilter,
updateInstanceTimelineLookback
} from '@utils/slices/instancesSlice'
import { AxiosError } from 'axios'
import { uniqBy } from 'lodash'
import {
@@ -194,9 +197,7 @@ const useTimelineQuery = ({
...queryKeyParams
}: QueryKeyTimeline[1] & {
options?: UseInfiniteQueryOptions<
InstanceResponse<
Mastodon.Status[] | Mastodon.Notification[] | Mastodon.Conversation[]
>,
InstanceResponse<Mastodon.Status[]>,
AxiosError
>
}) => {
@@ -209,6 +210,53 @@ const useTimelineQuery = ({
})
}
const prefetchTimelineQuery = async ({
ids,
queryKey
}: {
ids: Mastodon.Status['id'][]
queryKey: QueryKeyTimeline
}): Promise<Mastodon.Status['id'] | undefined> => {
let page: string = ''
let local: boolean = false
switch (queryKey[1].page) {
case 'Following':
page = 'home'
break
case 'Local':
page = 'public'
local = true
break
case 'LocalPublic':
page = 'public'
break
}
for (const id of ids) {
const statuses = await apiInstance<Mastodon.Status[]>({
method: 'get',
url: `timelines/${page}`,
params: {
min_id: id,
limit: 1,
...(local && { local: 'true' })
}
})
if (statuses.body.length) {
await queryClient.prefetchInfiniteQuery(queryKey, props =>
queryFunction({
...props,
queryKey,
pageParam: {
max_id: statuses.body[0].id
}
})
)
return id
}
}
}
// --- Separator ---
enum MapPropertyToUrl {
@@ -388,4 +436,4 @@ const useTimelineMutation = ({
})
}
export { useTimelineQuery, useTimelineMutation }
export { prefetchTimelineQuery, useTimelineQuery, useTimelineMutation }

View File

@@ -17,10 +17,6 @@ export type ContextsState = {
hidden: boolean
}
previousTab: 'Tab-Local' | 'Tab-Public' | 'Tab-Notifications' | 'Tab-Me'
mePage: {
lists: { shown: boolean }
announcements: { shown: boolean; unread: number }
}
}
export const contextsInitialState = {
@@ -36,11 +32,7 @@ export const contextsInitialState = {
current: 0,
hidden: false
},
previousTab: 'Tab-Me',
mePage: {
lists: { shown: false },
announcements: { shown: false, unread: 0 }
}
previousTab: 'Tab-Me'
}
const contextsSlice = createSlice({
@@ -69,12 +61,6 @@ const contextsSlice = createSlice({
action: PayloadAction<ContextsState['previousTab']>
) => {
state.previousTab = action.payload
},
updateContextMePage: (
state,
action: PayloadAction<Partial<ContextsState['mePage']>>
) => {
state.mePage = { ...state.mePage, ...action.payload }
}
}
})
@@ -82,13 +68,11 @@ const contextsSlice = createSlice({
export const getPublicRemoteNotice = (state: RootState) =>
state.contexts.publicRemoteNotice
export const getPreviousTab = (state: RootState) => state.contexts.previousTab
export const getMePage = (state: RootState) => state.contexts.mePage
export const getContexts = (state: RootState) => state.contexts
export const {
updateStoreReview,
updatePublicRemoteNotice,
updatePreviousTab,
updateContextMePage
updatePreviousTab
} = contextsSlice.actions
export default contextsSlice.reducer

View File

@@ -101,6 +101,11 @@ const addInstance = createAsyncThunk(
},
keys: { auth: undefined, public: undefined, private: undefined }
},
timelinesLookback: {},
mePage: {
lists: { shown: false },
announcements: { shown: false, unread: 0 }
},
drafts: []
}
})

View File

@@ -2,6 +2,7 @@ import analytics from '@components/analytics'
import { createSlice, PayloadAction } from '@reduxjs/toolkit'
import { RootState } from '@root/store'
import { ComposeStateDraft } from '@screens/Compose/utils/types'
import { QueryKeyTimeline } from '@utils/queryHooks/timeline'
import { findIndex } from 'lodash'
import addInstance from './instances/add'
import removeInstance from './instances/remove'
@@ -70,6 +71,16 @@ export type Instance = {
private?: string // legacy
}
}
timelinesLookback?: {
[key: string]: {
queryKey: QueryKeyTimeline
ids: Mastodon.Status['id'][]
}
}
mePage: {
lists: { shown: boolean }
announcements: { shown: boolean; unread: number }
}
drafts: ComposeStateDraft[]
}
@@ -154,6 +165,26 @@ const instancesSlice = createSlice({
newInstance.push.global.value = false
return newInstance
})
},
updateInstanceTimelineLookback: (
{ instances },
action: PayloadAction<Instance['timelinesLookback']>
) => {
const activeIndex = findInstanceActive(instances)
instances[activeIndex].timelinesLookback = {
...instances[activeIndex].timelinesLookback,
...action.payload
}
},
updateInstanceMePage: (
{ instances },
action: PayloadAction<Partial<Instance['mePage']>>
) => {
const activeIndex = findInstanceActive(instances)
instances[activeIndex].mePage = {
...instances[activeIndex].mePage,
...action.payload
}
}
},
extraReducers: builder => {
@@ -354,6 +385,13 @@ export const getInstanceNotificationsFilter = ({
export const getInstancePush = ({ instances: { instances } }: RootState) =>
instances[findInstanceActive(instances)]?.push
export const getInstanceTimelinesLookback = ({
instances: { instances }
}: RootState) => instances[findInstanceActive(instances)]?.timelinesLookback
export const getInstanceMePage = ({ instances: { instances } }: RootState) =>
instances[findInstanceActive(instances)]?.mePage
export const getInstanceDrafts = ({ instances: { instances } }: RootState) =>
instances[findInstanceActive(instances)]?.drafts
@@ -364,7 +402,9 @@ export const {
updateInstanceDraft,
removeInstanceDraft,
clearPushLoading,
disableAllPushes
disableAllPushes,
updateInstanceTimelineLookback,
updateInstanceMePage
} = instancesSlice.actions
export default instancesSlice.reducer