trigger reload manually instead of relying on effects

This commit is contained in:
Athou
2022-08-13 21:57:03 +02:00
parent 4e5fd18eea
commit e803ce13eb
4 changed files with 22 additions and 60 deletions

View File

@@ -32,14 +32,7 @@ describe("entries", () => {
} as AxiosResponse<Entries>) } as AxiosResponse<Entries>)
const store = configureStore({ reducer: reducers }) const store = configureStore({ reducer: reducers })
const promise = store.dispatch( const promise = store.dispatch(loadEntries({ type: "feed", id: "feed-id" }))
loadEntries({
sourceType: "feed",
req: {
id: "feed-id",
},
})
)
expect(store.getState().entries.source.type).toBe("feed") expect(store.getState().entries.source.type).toBe("feed")
expect(store.getState().entries.source.id).toBe("feed-id") expect(store.getState().entries.source.id).toBe("feed-id")

View File

@@ -2,7 +2,7 @@ import { createAsyncThunk, createSlice, PayloadAction } from "@reduxjs/toolkit"
import { client } from "app/client" import { client } from "app/client"
import { Constants } from "app/constants" import { Constants } from "app/constants"
import { RootState } from "app/store" import { RootState } from "app/store"
import { Entries, Entry, GetEntriesRequest, MarkRequest } from "app/types" import { Entries, Entry, MarkRequest } from "app/types"
export type EntrySourceType = "category" | "feed" export type EntrySourceType = "category" | "feed"
export type EntrySource = { type: EntrySourceType; id: string } export type EntrySource = { type: EntrySourceType; id: string }
@@ -35,18 +35,18 @@ const initialState: EntriesState = {
} }
const getEndpoint = (sourceType: EntrySourceType) => (sourceType === "category" ? client.category.getEntries : client.feed.getEntries) const getEndpoint = (sourceType: EntrySourceType) => (sourceType === "category" ? client.category.getEntries : client.feed.getEntries)
export const loadEntries = createAsyncThunk<Entries, { req: GetEntriesRequest; sourceType: EntrySourceType }, { state: RootState }>( export const loadEntries = createAsyncThunk<Entries, EntrySource, { state: RootState }>("entries/load", async (source, thunkApi) => {
"entries/load", const state = thunkApi.getState()
async arg => { const endpoint = getEndpoint(source.type)
const endpoint = getEndpoint(arg.sourceType) const result = await endpoint({
const result = await endpoint({ id: source.id,
...arg.req, order: state.user.settings?.readingOrder,
offset: 0, readType: state.user.settings?.readingMode,
limit: 50, offset: 0,
}) limit: 50,
return result.data })
} return result.data
) })
export const loadMoreEntries = createAsyncThunk<Entries, void, { state: RootState }>("entries/loadMore", async (_, thunkApi) => { export const loadMoreEntries = createAsyncThunk<Entries, void, { state: RootState }>("entries/loadMore", async (_, thunkApi) => {
const state = thunkApi.getState() const state = thunkApi.getState()
const offset = const offset =
@@ -61,17 +61,9 @@ export const loadMoreEntries = createAsyncThunk<Entries, void, { state: RootStat
}) })
return result.data return result.data
}) })
export const reloadEntries = createAsyncThunk<Entries, void, { state: RootState }>("entries/reload", async (_, thunkApi) => { export const reloadEntries = createAsyncThunk<void, void, { state: RootState }>("entries/reload", async (_, thunkApi) => {
const state = thunkApi.getState() const state = thunkApi.getState()
const endpoint = getEndpoint(state.entries.source.type) thunkApi.dispatch(loadEntries(state.entries.source))
const result = await endpoint({
id: state.entries.source.id,
readType: state.user.settings?.readingMode,
order: state.user.settings?.readingOrder,
offset: 0,
limit: 50,
})
return result.data
}) })
export const markEntry = createAsyncThunk( export const markEntry = createAsyncThunk(
"entries/entry/mark", "entries/entry/mark",
@@ -160,10 +152,7 @@ export const entriesSlice = createSlice({
}) })
}) })
builder.addCase(loadEntries.pending, (state, action) => { builder.addCase(loadEntries.pending, (state, action) => {
state.source = { state.source = action.meta.arg
type: action.meta.arg.sourceType,
id: action.meta.arg.req.id,
}
state.entries = [] state.entries = []
state.timestamp = undefined state.timestamp = undefined
state.sourceLabel = "" state.sourceLabel = ""
@@ -184,21 +173,6 @@ export const entriesSlice = createSlice({
state.entries = [...state.entries, ...entriesToAdd] state.entries = [...state.entries, ...entriesToAdd]
state.hasMore = action.payload.hasMore state.hasMore = action.payload.hasMore
}) })
builder.addCase(reloadEntries.pending, state => {
state.entries = []
state.timestamp = undefined
state.sourceLabel = ""
state.sourceWebsiteUrl = ""
state.hasMore = true
state.selectedEntryId = undefined
})
builder.addCase(reloadEntries.fulfilled, (state, action) => {
state.entries = action.payload.entries
state.timestamp = action.payload.timestamp
state.sourceLabel = action.payload.name
state.sourceWebsiteUrl = action.payload.feedLink
state.hasMore = action.payload.hasMore
})
}, },
}) })

View File

@@ -4,6 +4,7 @@ import { createAsyncThunk, createSlice, isAnyOf } from "@reduxjs/toolkit"
import { client } from "app/client" import { client } from "app/client"
import { RootState } from "app/store" import { RootState } from "app/store"
import { ReadingMode, ReadingOrder, Settings, UserModel } from "app/types" import { ReadingMode, ReadingOrder, Settings, UserModel } from "app/types"
import { reloadEntries } from "./entries"
interface UserState { interface UserState {
settings?: Settings settings?: Settings
@@ -20,6 +21,7 @@ export const changeReadingMode = createAsyncThunk<void, ReadingMode, { state: Ro
const { settings } = thunkApi.getState().user const { settings } = thunkApi.getState().user
if (!settings) return if (!settings) return
client.user.saveSettings({ ...settings, readingMode }) client.user.saveSettings({ ...settings, readingMode })
thunkApi.dispatch(reloadEntries())
} }
) )
export const changeReadingOrder = createAsyncThunk<void, ReadingOrder, { state: RootState }>( export const changeReadingOrder = createAsyncThunk<void, ReadingOrder, { state: RootState }>(
@@ -28,6 +30,7 @@ export const changeReadingOrder = createAsyncThunk<void, ReadingOrder, { state:
const { settings } = thunkApi.getState().user const { settings } = thunkApi.getState().user
if (!settings) return if (!settings) return
client.user.saveSettings({ ...settings, readingOrder }) client.user.saveSettings({ ...settings, readingOrder })
thunkApi.dispatch(reloadEntries())
} }
) )
export const changeLanguage = createAsyncThunk<void, string, { state: RootState }>("settings/language", (language, thunkApi) => { export const changeLanguage = createAsyncThunk<void, string, { state: RootState }>("settings/language", (language, thunkApi) => {

View File

@@ -36,8 +36,6 @@ export function FeedEntriesPage(props: FeedEntriesPageProps) {
const sourceLabel = useAppSelector(state => state.entries.sourceLabel) const sourceLabel = useAppSelector(state => state.entries.sourceLabel)
const sourceWebsiteUrl = useAppSelector(state => state.entries.sourceWebsiteUrl) const sourceWebsiteUrl = useAppSelector(state => state.entries.sourceWebsiteUrl)
const hasMore = useAppSelector(state => state.entries.hasMore) const hasMore = useAppSelector(state => state.entries.hasMore)
const readType = useAppSelector(state => state.user.settings?.readingMode)
const order = useAppSelector(state => state.user.settings?.readingOrder)
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const titleClicked = () => { const titleClicked = () => {
@@ -46,14 +44,8 @@ export function FeedEntriesPage(props: FeedEntriesPageProps) {
} }
useEffect(() => { useEffect(() => {
if (!readType || !order) return dispatch(loadEntries({ type: props.sourceType, id }))
dispatch( }, [dispatch, props.sourceType, id, location.state])
loadEntries({
sourceType: props.sourceType,
req: { id, readType, order },
})
)
}, [dispatch, props.sourceType, id, readType, order, location.state])
const hideEditButton = props.sourceType === "category" && id === Constants.categoryIds.all const hideEditButton = props.sourceType === "category" && id === Constants.categoryIds.all