diff --git a/Gemfile.lock b/Gemfile.lock index 04d5aac6cd..f8c830291a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -587,7 +587,7 @@ GEM pastel (0.8.0) tty-color (~> 0.5) pg (1.5.9) - pghero (3.6.1) + pghero (3.6.2) activerecord (>= 6.1) pp (0.6.2) prettyprint @@ -830,7 +830,7 @@ GEM stoplight (4.1.1) redlock (~> 1.0) stringio (3.1.5) - strong_migrations (2.2.0) + strong_migrations (2.2.1) activerecord (>= 7) swd (2.0.3) activesupport (>= 3) @@ -866,7 +866,7 @@ GEM unf (~> 0.1.0) tzinfo (2.0.6) concurrent-ruby (~> 1.0) - tzinfo-data (1.2025.1) + tzinfo-data (1.2025.2) tzinfo (>= 1.0.0) unf (0.1.4) unf_ext diff --git a/app/controllers/backups_controller.rb b/app/controllers/backups_controller.rb index 5df1af5f2f..076d19874b 100644 --- a/app/controllers/backups_controller.rb +++ b/app/controllers/backups_controller.rb @@ -9,13 +9,15 @@ class BackupsController < ApplicationController before_action :authenticate_user! before_action :set_backup + BACKUP_LINK_TIMEOUT = 1.hour.freeze + def download case Paperclip::Attachment.default_options[:storage] when :s3, :azure - redirect_to @backup.dump.expiring_url(10), allow_other_host: true + redirect_to @backup.dump.expiring_url(BACKUP_LINK_TIMEOUT.to_i), allow_other_host: true when :fog if Paperclip::Attachment.default_options.dig(:fog_credentials, :openstack_temp_url_key).present? - redirect_to @backup.dump.expiring_url(Time.now.utc + 10), allow_other_host: true + redirect_to @backup.dump.expiring_url(BACKUP_LINK_TIMEOUT.from_now), allow_other_host: true else redirect_to full_asset_url(@backup.dump.url), allow_other_host: true end diff --git a/app/javascript/mastodon/components/media_gallery.jsx b/app/javascript/mastodon/components/media_gallery.jsx index e52e14b1ed..b841745add 100644 --- a/app/javascript/mastodon/components/media_gallery.jsx +++ b/app/javascript/mastodon/components/media_gallery.jsx @@ -12,6 +12,7 @@ import { debounce } from 'lodash'; import { AltTextBadge } from 'mastodon/components/alt_text_badge'; import { Blurhash } from 'mastodon/components/blurhash'; +import { SpoilerButton } from 'mastodon/components/spoiler_button'; import { formatTime } from 'mastodon/features/video'; import { autoPlayGif, displayMedia, useBlurhash } from '../initial_state'; @@ -299,7 +300,7 @@ class MediaGallery extends PureComponent { const { visible } = this.state; const width = this.state.width || defaultWidth; - let children, spoilerButton; + let children; const style = {}; @@ -318,35 +319,11 @@ class MediaGallery extends PureComponent { children = media.map((attachment, i) => ); } - if (uncached) { - spoilerButton = ( - - ); - } else if (!visible) { - spoilerButton = ( - - ); - } - return (
{children} - {(!visible || uncached) && ( -
- {spoilerButton} -
- )} + {(!visible || uncached) && } {(visible && !uncached) && (
diff --git a/app/javascript/mastodon/components/spoiler_button.tsx b/app/javascript/mastodon/components/spoiler_button.tsx new file mode 100644 index 0000000000..3ba2cbc5fa --- /dev/null +++ b/app/javascript/mastodon/components/spoiler_button.tsx @@ -0,0 +1,73 @@ +import { FormattedMessage } from 'react-intl'; + +import classNames from 'classnames'; + +interface Props { + hidden?: boolean; + sensitive: boolean; + uncached?: boolean; + onClick: React.MouseEventHandler; +} + +export const SpoilerButton: React.FC = ({ + hidden = false, + sensitive, + uncached = false, + onClick, +}) => { + let warning; + let action; + + if (uncached) { + warning = ( + + ); + action = ( + + ); + } else if (sensitive) { + warning = ( + + ); + action = ( + + ); + } else { + warning = ( + + ); + action = ( + + ); + } + + return ( +
+ +
+ ); +}; diff --git a/app/javascript/mastodon/features/audio/index.jsx b/app/javascript/mastodon/features/audio/index.jsx index 56c0e524ad..2ce67a94ab 100644 --- a/app/javascript/mastodon/features/audio/index.jsx +++ b/app/javascript/mastodon/features/audio/index.jsx @@ -1,7 +1,7 @@ import PropTypes from 'prop-types'; import { PureComponent } from 'react'; -import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; +import { defineMessages, injectIntl } from 'react-intl'; import classNames from 'classnames'; @@ -16,6 +16,7 @@ import VisibilityOffIcon from '@/material-icons/400-24px/visibility_off.svg?reac import VolumeOffIcon from '@/material-icons/400-24px/volume_off-fill.svg?react'; import VolumeUpIcon from '@/material-icons/400-24px/volume_up-fill.svg?react'; import { Icon } from 'mastodon/components/icon'; +import { SpoilerButton } from 'mastodon/components/spoiler_button'; import { formatTime, getPointerPosition, fileNameFromURL } from 'mastodon/features/video'; import { Blurhash } from '../../components/blurhash'; @@ -476,14 +477,6 @@ class Audio extends PureComponent { const progress = Math.min((currentTime / duration) * 100, 100); const muted = this.state.muted || volume === 0; - let warning; - - if (sensitive) { - warning = ; - } else { - warning = ; - } - return (
@@ -521,14 +514,7 @@ class Audio extends PureComponent { lang={lang} /> -
- -
+