mirror of
https://github.com/tooot-app/app
synced 2025-06-05 22:19:13 +02:00
Transform into TypeScript
This commit is contained in:
256
src/stacks/common/timelineSlice.ts
Normal file
256
src/stacks/common/timelineSlice.ts
Normal file
@ -0,0 +1,256 @@
|
||||
import {
|
||||
AnyAction,
|
||||
createAsyncThunk,
|
||||
createSlice,
|
||||
PayloadAction
|
||||
} from '@reduxjs/toolkit'
|
||||
|
||||
import client from 'src/api/client'
|
||||
|
||||
export const fetch = createAsyncThunk(
|
||||
'timeline/fetch',
|
||||
async (
|
||||
{
|
||||
page,
|
||||
paginationDirection,
|
||||
query = {},
|
||||
account,
|
||||
hashtag,
|
||||
list,
|
||||
toot
|
||||
}: {
|
||||
page: string
|
||||
paginationDirection?: 'prev' | 'next'
|
||||
query?: {
|
||||
[key: string]: string | number | boolean
|
||||
}
|
||||
account?: string
|
||||
hashtag?: string
|
||||
list?: string
|
||||
toot?: string
|
||||
},
|
||||
{ getState }
|
||||
) => {
|
||||
let res
|
||||
|
||||
if (paginationDirection) {
|
||||
//@ts-ignore
|
||||
const allToots = getState().timelines[page].toots
|
||||
switch (paginationDirection) {
|
||||
case 'prev':
|
||||
query.min_id = allToots[0].id
|
||||
break
|
||||
case 'next':
|
||||
query.max_id = allToots[allToots.length - 1].id
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
switch (page) {
|
||||
case 'Following':
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: 'timelines/home',
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Local':
|
||||
query.local = 'true'
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: 'timelines/public',
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'LocalPublic':
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: 'timelines/public',
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'RemotePublic':
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'remote',
|
||||
endpoint: 'timelines/public',
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Notifications':
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: 'notifications',
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Account_Default':
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `accounts/${account}/statuses`,
|
||||
query: {
|
||||
pinned: 'true'
|
||||
}
|
||||
})
|
||||
const toots = res.body
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `accounts/${account}/statuses`,
|
||||
query: {
|
||||
exclude_replies: 'true'
|
||||
}
|
||||
})
|
||||
toots.push(...res.body)
|
||||
return { toots: toots }
|
||||
|
||||
case 'Account_All':
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `accounts/${account}/statuses`,
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Account_Media':
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `accounts/${account}/statuses`,
|
||||
query: {
|
||||
only_media: 'true'
|
||||
}
|
||||
})
|
||||
return {
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Hashtag':
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `timelines/tag/${hashtag}`,
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'List':
|
||||
res = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `timelines/list/${list}`,
|
||||
query
|
||||
})
|
||||
return {
|
||||
toots: res.body
|
||||
}
|
||||
|
||||
case 'Toot':
|
||||
const current = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `statuses/${toot}`
|
||||
})
|
||||
const context = await client({
|
||||
method: 'get',
|
||||
instance: 'local',
|
||||
endpoint: `statuses/${toot}/context`
|
||||
})
|
||||
return {
|
||||
toots: [...context.ancestors, current, ...context.descendants],
|
||||
pointer: context.ancestors.length
|
||||
}
|
||||
|
||||
default:
|
||||
console.error('First time fetching timeline error')
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
const timelineInitState: store.TimelineState = {
|
||||
toots: [],
|
||||
pointer: undefined,
|
||||
status: 'idle'
|
||||
}
|
||||
|
||||
export const timelineSlice = createSlice({
|
||||
name: 'timeline',
|
||||
initialState: {
|
||||
Following: timelineInitState,
|
||||
Local: timelineInitState,
|
||||
LocalPublic: timelineInitState,
|
||||
RemotePublic: timelineInitState,
|
||||
Notifications: timelineInitState,
|
||||
Hashtag: timelineInitState,
|
||||
List: timelineInitState,
|
||||
Toot: timelineInitState,
|
||||
Account_Default: timelineInitState,
|
||||
Account_All: timelineInitState,
|
||||
Account_Media: timelineInitState
|
||||
},
|
||||
reducers: {
|
||||
reset: (state, action: PayloadAction<store.TimelinePage>) => {
|
||||
state[action.payload] = timelineInitState
|
||||
}
|
||||
},
|
||||
extraReducers: builder => {
|
||||
builder.addCase(fetch.pending, (state, action: AnyAction) => {
|
||||
//@ts-ignore
|
||||
state[action.meta.arg.page].status = 'loading'
|
||||
})
|
||||
|
||||
builder.addCase(fetch.fulfilled, (state, action) => {
|
||||
//@ts-ignore
|
||||
state[action.meta.arg.page].status = 'succeeded'
|
||||
|
||||
if (action.payload?.toots) {
|
||||
if (action.meta.arg.paginationDirection === 'prev') {
|
||||
//@ts-ignore
|
||||
state[action.meta.arg.page].toots.unshift(...action.payload.toots)
|
||||
} else {
|
||||
//@ts-ignore
|
||||
state[action.meta.arg.page].toots.push(...action.payload.toots)
|
||||
}
|
||||
}
|
||||
|
||||
if (action.payload?.pointer) {
|
||||
//@ts-ignore
|
||||
state[action.meta.arg.page].pointer = action.payload.pointer
|
||||
}
|
||||
})
|
||||
|
||||
builder.addCase(fetch.rejected, (state, action) => {
|
||||
//@ts-ignore
|
||||
state[action.meta.arg.page].status = 'failed'
|
||||
console.error(action.error.message)
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
export const { reset } = timelineSlice.actions
|
||||
export default timelineSlice.reducer
|
Reference in New Issue
Block a user