mirror of
https://github.com/glitch-soc/mastodon.git
synced 2025-12-14 08:19:05 +00:00
Merge commit '241ad1c5878161f5f4a19c16ed6c042f1c2cb6c2' into glitch-soc/merge-upstream
This commit is contained in:
@@ -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}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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`
|
||||||
|
// (we don't want to do this if it's just a long-running job)
|
||||||
|
if (status === 'finished') {
|
||||||
dispatch(completeContextRefresh({ statusId }));
|
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) {
|
||||||
|
if (status === 'finished') {
|
||||||
setLoadingState('idle');
|
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'
|
||||||
|
if (status === 'finished') {
|
||||||
setLoadingState('idle');
|
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);
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user