Merge commit '241ad1c5878161f5f4a19c16ed6c042f1c2cb6c2' into glitch-soc/merge-upstream

This commit is contained in:
Claire
2025-10-16 18:36:25 +02:00
7 changed files with 48 additions and 24 deletions

View File

@@ -208,12 +208,12 @@ FROM build AS ffmpeg
# renovate: datasource=repology depName=ffmpeg packageName=openpkg_current/ffmpeg # renovate: datasource=repology depName=ffmpeg packageName=openpkg_current/ffmpeg
ARG FFMPEG_VERSION=8.0 ARG FFMPEG_VERSION=8.0
# ffmpeg download URL, change with [--build-arg FFMPEG_URL="https://ffmpeg.org/releases"] # ffmpeg download URL, change with [--build-arg FFMPEG_URL="https://ffmpeg.org/releases"]
ARG FFMPEG_URL=https://ffmpeg.org/releases ARG FFMPEG_URL=https://github.com/FFmpeg/FFmpeg/archive/refs/tags
WORKDIR /usr/local/ffmpeg/src WORKDIR /usr/local/ffmpeg/src
# Download and extract ffmpeg source code # Download and extract ffmpeg source code
ADD ${FFMPEG_URL}/ffmpeg-${FFMPEG_VERSION}.tar.xz /usr/local/ffmpeg/src/ ADD ${FFMPEG_URL}/n${FFMPEG_VERSION}.tar.gz /usr/local/ffmpeg/src/
RUN tar xf ffmpeg-${FFMPEG_VERSION}.tar.xz; RUN tar xf n${FFMPEG_VERSION}.tar.gz && mv FFmpeg-n${FFMPEG_VERSION} ffmpeg-${FFMPEG_VERSION};
WORKDIR /usr/local/ffmpeg/src/ffmpeg-${FFMPEG_VERSION} WORKDIR /usr/local/ffmpeg/src/ffmpeg-${FFMPEG_VERSION}

View File

@@ -142,7 +142,7 @@ class HashtagTimeline extends PureComponent {
const { params, local } = this.props; const { params, local } = this.props;
const { id, tags } = prevProps.params; const { id, tags } = prevProps.params;
if (id !== params.id || !isEqual(tags, params.tags) || !isEqual(local, params.local)) { if (id !== params.id || !isEqual(tags, params.tags) || !isEqual(local, prevProps.local)) {
this._unload(); this._unload();
this._load(); this._load();
} }

View File

@@ -38,7 +38,7 @@ const messages = defineMessages({
}, },
success: { success: {
id: 'status.context.loading_success', id: 'status.context.loading_success',
defaultMessage: 'All replies loaded', defaultMessage: 'New replies loaded',
}, },
error: { error: {
id: 'status.context.loading_error', id: 'status.context.loading_error',
@@ -81,22 +81,38 @@ export const RefreshController: React.FC<{
useEffect(() => { useEffect(() => {
let timeoutId: ReturnType<typeof setTimeout>; let timeoutId: ReturnType<typeof setTimeout>;
const scheduleRefresh = (refresh: AsyncRefreshHeader) => { const scheduleRefresh = (
refresh: AsyncRefreshHeader,
iteration: number,
) => {
timeoutId = setTimeout(() => { timeoutId = setTimeout(() => {
void apiGetAsyncRefresh(refresh.id).then((result) => { void apiGetAsyncRefresh(refresh.id).then((result) => {
// If the refresh status is not finished, // At three scheduled refreshes, we consider the job
// schedule another refresh and exit // long-running and attempt to fetch any new replies so far
if (result.async_refresh.status !== 'finished') { const isLongRunning = iteration === 3;
scheduleRefresh(refresh);
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; return;
} }
// Refresh status is finished. The action below will clear `refreshHeader` // If refresh status is finished, clear `refreshHeader`
dispatch(completeContextRefresh({ statusId })); // (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 // Exit if there's nothing to fetch
if (result.async_refresh.result_count === 0) { if (result_count === 0) {
setLoadingState('idle'); if (status === 'finished') {
setLoadingState('idle');
} else {
scheduleRefresh(refresh, iteration + 1);
}
return; return;
} }
@@ -106,10 +122,15 @@ export const RefreshController: React.FC<{
// If so, they will populate `contexts.pendingReplies[statusId]` // If so, they will populate `contexts.pendingReplies[statusId]`
void dispatch(fetchContext({ statusId, prefetchOnly: true })) void dispatch(fetchContext({ statusId, prefetchOnly: true }))
.then(() => { .then(() => {
// Reset loading state to `idle` but if the fetch // Reset loading state to `idle`. If the fetch has
// has resulted in new pending replies, the `hasPendingReplies` // resulted in new pending replies, the `hasPendingReplies`
// flag will switch the loading state to 'more-available' // 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(() => { .catch(() => {
// Show an error if the fetch failed // Show an error if the fetch failed
@@ -121,7 +142,7 @@ export const RefreshController: React.FC<{
// Initialise a refresh // Initialise a refresh
if (refreshHeader && !wasDismissed) { if (refreshHeader && !wasDismissed) {
scheduleRefresh(refreshHeader); scheduleRefresh(refreshHeader, 1);
setLoadingState('loading'); setLoadingState('loading');
} }
@@ -135,7 +156,7 @@ export const RefreshController: React.FC<{
if (loadingState === 'success') { if (loadingState === 'success') {
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
setLoadingState('idle'); setLoadingState('idle');
}, 3000); }, 2500);
return () => { return () => {
clearTimeout(timeoutId); clearTimeout(timeoutId);

View File

@@ -876,7 +876,7 @@
"status.contains_quote": "Contains quote", "status.contains_quote": "Contains quote",
"status.context.loading": "Loading more replies", "status.context.loading": "Loading more replies",
"status.context.loading_error": "Couldn't load new replies", "status.context.loading_error": "Couldn't load new replies",
"status.context.loading_success": "All replies loaded", "status.context.loading_success": "New replies loaded",
"status.context.more_replies_found": "More replies found", "status.context.more_replies_found": "More replies found",
"status.context.retry": "Retry", "status.context.retry": "Retry",
"status.context.show": "Show", "status.context.show": "Show",

View File

@@ -166,7 +166,10 @@ const updateContext = (state: Draft<State>, status: ApiStatusJSON): void => {
export const contextsReducer = createReducer(initialState, (builder) => { export const contextsReducer = createReducer(initialState, (builder) => {
builder builder
.addCase(fetchContext.fulfilled, (state, action) => { .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( storePrefetchedReplies(
state, state,
action.meta.arg.statusId, action.meta.arg.statusId,
@@ -179,7 +182,7 @@ export const contextsReducer = createReducer(initialState, (builder) => {
action.payload.context, action.payload.context,
); );
if (action.payload.refresh) { if (action.payload.refresh && !action.payload.prefetchOnly) {
state.refreshing[action.meta.arg.statusId] = action.payload.refresh; state.refreshing[action.meta.arg.statusId] = action.payload.refresh;
} }
} }

View File

@@ -10439,7 +10439,7 @@ noscript {
&:hover, &:hover,
&:focus, &:focus,
&:active { &:active {
background: color.change($ui-base-color, $alpha: 0.85); background: color.change($white, $alpha: 0.15);
} }
} }

View File

@@ -115,7 +115,7 @@ services:
volumes: volumes:
- ./public/system:/mastodon/public/system - ./public/system:/mastodon/public/system
healthcheck: healthcheck:
test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 7' || false"] test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ [78]' || false"]
## Uncomment to enable federation with tor instances along with adding the following ENV variables ## Uncomment to enable federation with tor instances along with adding the following ENV variables
## http_hidden_proxy=http://privoxy:8118 ## http_hidden_proxy=http://privoxy:8118