mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-13 15:58:50 +00:00
[Glitch] Show new replies early if the fetch-all-replies task takes long to finish
Port 869eeecfee to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
@@ -38,7 +38,7 @@ const messages = defineMessages({
|
||||
},
|
||||
success: {
|
||||
id: 'status.context.loading_success',
|
||||
defaultMessage: 'All replies loaded',
|
||||
defaultMessage: 'New replies loaded',
|
||||
},
|
||||
error: {
|
||||
id: 'status.context.loading_error',
|
||||
@@ -81,22 +81,38 @@ export const RefreshController: React.FC<{
|
||||
useEffect(() => {
|
||||
let timeoutId: ReturnType<typeof setTimeout>;
|
||||
|
||||
const scheduleRefresh = (refresh: AsyncRefreshHeader) => {
|
||||
const scheduleRefresh = (
|
||||
refresh: AsyncRefreshHeader,
|
||||
iteration: number,
|
||||
) => {
|
||||
timeoutId = setTimeout(() => {
|
||||
void apiGetAsyncRefresh(refresh.id).then((result) => {
|
||||
// If the refresh status is not finished,
|
||||
// schedule another refresh and exit
|
||||
if (result.async_refresh.status !== 'finished') {
|
||||
scheduleRefresh(refresh);
|
||||
// At three scheduled refreshes, we consider the job
|
||||
// long-running and attempt to fetch any new replies so far
|
||||
const isLongRunning = iteration === 3;
|
||||
|
||||
const { status, result_count } = result.async_refresh;
|
||||
|
||||
// If the refresh status is not finished and not long-running,
|
||||
// we just schedule another refresh and exit
|
||||
if (status === 'running' && !isLongRunning) {
|
||||
scheduleRefresh(refresh, iteration + 1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Refresh status is finished. The action below will clear `refreshHeader`
|
||||
dispatch(completeContextRefresh({ statusId }));
|
||||
// If refresh status is finished, clear `refreshHeader`
|
||||
// (we don't want to do this if it's just a long-running job)
|
||||
if (status === 'finished') {
|
||||
dispatch(completeContextRefresh({ statusId }));
|
||||
}
|
||||
|
||||
// Exit if there's nothing to fetch
|
||||
if (result.async_refresh.result_count === 0) {
|
||||
setLoadingState('idle');
|
||||
if (result_count === 0) {
|
||||
if (status === 'finished') {
|
||||
setLoadingState('idle');
|
||||
} else {
|
||||
scheduleRefresh(refresh, iteration + 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -106,10 +122,15 @@ export const RefreshController: React.FC<{
|
||||
// If so, they will populate `contexts.pendingReplies[statusId]`
|
||||
void dispatch(fetchContext({ statusId, prefetchOnly: true }))
|
||||
.then(() => {
|
||||
// Reset loading state to `idle` – but if the fetch
|
||||
// has resulted in new pending replies, the `hasPendingReplies`
|
||||
// Reset loading state to `idle`. If the fetch has
|
||||
// resulted in new pending replies, the `hasPendingReplies`
|
||||
// flag will switch the loading state to 'more-available'
|
||||
setLoadingState('idle');
|
||||
if (status === 'finished') {
|
||||
setLoadingState('idle');
|
||||
} else {
|
||||
// Keep background fetch going if `isLongRunning` is true
|
||||
scheduleRefresh(refresh, iteration + 1);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
// Show an error if the fetch failed
|
||||
@@ -121,7 +142,7 @@ export const RefreshController: React.FC<{
|
||||
|
||||
// Initialise a refresh
|
||||
if (refreshHeader && !wasDismissed) {
|
||||
scheduleRefresh(refreshHeader);
|
||||
scheduleRefresh(refreshHeader, 1);
|
||||
setLoadingState('loading');
|
||||
}
|
||||
|
||||
@@ -135,7 +156,7 @@ export const RefreshController: React.FC<{
|
||||
if (loadingState === 'success') {
|
||||
const timeoutId = setTimeout(() => {
|
||||
setLoadingState('idle');
|
||||
}, 3000);
|
||||
}, 2500);
|
||||
|
||||
return () => {
|
||||
clearTimeout(timeoutId);
|
||||
|
||||
@@ -166,7 +166,10 @@ const updateContext = (state: Draft<State>, status: ApiStatusJSON): void => {
|
||||
export const contextsReducer = createReducer(initialState, (builder) => {
|
||||
builder
|
||||
.addCase(fetchContext.fulfilled, (state, action) => {
|
||||
if (action.payload.prefetchOnly) {
|
||||
const currentReplies = state.replies[action.meta.arg.statusId] ?? [];
|
||||
const hasReplies = currentReplies.length > 0;
|
||||
// Ignore prefetchOnly if there are no replies - then we can load them immediately
|
||||
if (action.payload.prefetchOnly && hasReplies) {
|
||||
storePrefetchedReplies(
|
||||
state,
|
||||
action.meta.arg.statusId,
|
||||
@@ -179,7 +182,7 @@ export const contextsReducer = createReducer(initialState, (builder) => {
|
||||
action.payload.context,
|
||||
);
|
||||
|
||||
if (action.payload.refresh) {
|
||||
if (action.payload.refresh && !action.payload.prefetchOnly) {
|
||||
state.refreshing[action.meta.arg.statusId] = action.payload.refresh;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user