Merge pull request #323 from kmycode/kbtopic-upstream-patch
Release: 9.1
This commit is contained in:
commit
d43b55189e
11 changed files with 94 additions and 14 deletions
27
CHANGELOG.md
27
CHANGELOG.md
|
@ -2,6 +2,33 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## [4.2.2] - 2023-12-04
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Change dismissed banners to be stored server-side ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27055))
|
||||||
|
- Change GIF max matrix size error to explicitly mention GIF files ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27927))
|
||||||
|
- Change `Follow` activities delivery to bypass availability check ([ShadowJonathan](https://github.com/mastodon/mastodon/pull/27586))
|
||||||
|
- Change single-column navigation notice to be displayed outside of the logo container ([renchap](https://github.com/mastodon/mastodon/pull/27462), [renchap](https://github.com/mastodon/mastodon/pull/27476))
|
||||||
|
- Change Content-Security-Policy to be tighter on media paths ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/26889))
|
||||||
|
- Change post language code to include country code when relevant ([gunchleoc](https://github.com/mastodon/mastodon/pull/27099), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27207))
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Fix upper border radius of onboarding columns ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27890))
|
||||||
|
- Fix incoming status creation date not being restricted to standard ISO8601 ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27655), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/28081))
|
||||||
|
- Fix some posts from threads received out-of-order sometimes not being inserted into timelines ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27653))
|
||||||
|
- Fix posts from force-sensitized accounts being able to trend ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27620))
|
||||||
|
- Fix error when trying to delete already-deleted file with OpenStack Swift ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27569))
|
||||||
|
- Fix batch attachment deletion when using OpenStack Swift ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27554))
|
||||||
|
- Fix processing LDSigned activities from actors with unknown public keys ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27474))
|
||||||
|
- Fix error and incorrect URLs in `/api/v1/accounts/:id/featured_tags` for remote accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27459))
|
||||||
|
- Fix report processing notice not mentioning the report number when performing a custom action ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27442))
|
||||||
|
- Fix handling of `inLanguage` attribute in preview card processing ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27423))
|
||||||
|
- Fix own posts being removed from home timeline when unfollowing a used hashtag ([kmycode](https://github.com/mastodon/mastodon/pull/27391))
|
||||||
|
- Fix some link anchors being recognized as hashtags ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27271), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/27584))
|
||||||
|
- Fix format-dependent redirects being cached regardless of requested format ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/27634))
|
||||||
|
|
||||||
## [4.2.1] - 2023-10-10
|
## [4.2.1] - 2023-10-10
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AccountsIndex < Chewy::Index
|
class AccountsIndex < Chewy::Index
|
||||||
|
include DatetimeClampingConcern
|
||||||
|
|
||||||
DEVELOPMENT_SETTINGS = {
|
DEVELOPMENT_SETTINGS = {
|
||||||
filter: {
|
filter: {
|
||||||
english_stop: {
|
english_stop: {
|
||||||
|
@ -153,7 +155,7 @@ class AccountsIndex < Chewy::Index
|
||||||
field(:following_count, type: 'long', value: ->(account) { account.public_following_count })
|
field(:following_count, type: 'long', value: ->(account) { account.public_following_count })
|
||||||
field(:followers_count, type: 'long', value: ->(account) { account.public_followers_count })
|
field(:followers_count, type: 'long', value: ->(account) { account.public_followers_count })
|
||||||
field(:properties, type: 'keyword', value: ->(account) { account.searchable_properties })
|
field(:properties, type: 'keyword', value: ->(account) { account.searchable_properties })
|
||||||
field(:last_status_at, type: 'date', value: ->(account) { account.last_status_at || account.created_at })
|
field(:last_status_at, type: 'date', value: ->(account) { clamp_date(account.last_status_at || account.created_at) })
|
||||||
field(:domain, type: 'keyword', value: ->(account) { account.domain || '' })
|
field(:domain, type: 'keyword', value: ->(account) { account.domain || '' })
|
||||||
field(:display_name, type: 'text', analyzer: 'verbatim') { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' }
|
field(:display_name, type: 'text', analyzer: 'verbatim') { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' }
|
||||||
field(:username, type: 'text', analyzer: 'verbatim', value: ->(account) { [account.username, account.domain].compact.join('@') }) { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' }
|
field(:username, type: 'text', analyzer: 'verbatim', value: ->(account) { [account.username, account.domain].compact.join('@') }) { field :edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'verbatim' }
|
||||||
|
|
14
app/chewy/concerns/datetime_clamping_concern.rb
Normal file
14
app/chewy/concerns/datetime_clamping_concern.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module DatetimeClampingConcern
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
MIN_ISO8601_DATETIME = '0000-01-01T00:00:00Z'.to_datetime.freeze
|
||||||
|
MAX_ISO8601_DATETIME = '9999-12-31T23:59:59Z'.to_datetime.freeze
|
||||||
|
|
||||||
|
class_methods do
|
||||||
|
def clamp_date(datetime)
|
||||||
|
datetime.clamp(MIN_ISO8601_DATETIME, MAX_ISO8601_DATETIME)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class PublicStatusesIndex < Chewy::Index
|
class PublicStatusesIndex < Chewy::Index
|
||||||
|
include DatetimeClampingConcern
|
||||||
|
|
||||||
DEVELOPMENT_SETTINGS = {
|
DEVELOPMENT_SETTINGS = {
|
||||||
filter: {
|
filter: {
|
||||||
english_stop: {
|
english_stop: {
|
||||||
|
@ -154,6 +156,6 @@ class PublicStatusesIndex < Chewy::Index
|
||||||
field(:language, type: 'keyword')
|
field(:language, type: 'keyword')
|
||||||
field(:domain, type: 'keyword', value: ->(status) { status.account.domain || '' })
|
field(:domain, type: 'keyword', value: ->(status) { status.account.domain || '' })
|
||||||
field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties })
|
field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties })
|
||||||
field(:created_at, type: 'date')
|
field(:created_at, type: 'date', value: ->(status) { clamp_date(status.created_at) })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class StatusesIndex < Chewy::Index
|
class StatusesIndex < Chewy::Index
|
||||||
|
include DatetimeClampingConcern
|
||||||
|
|
||||||
DEVELOPMENT_SETTINGS = {
|
DEVELOPMENT_SETTINGS = {
|
||||||
filter: {
|
filter: {
|
||||||
english_stop: {
|
english_stop: {
|
||||||
|
@ -184,6 +186,6 @@ class StatusesIndex < Chewy::Index
|
||||||
field(:language, type: 'keyword')
|
field(:language, type: 'keyword')
|
||||||
field(:domain, type: 'keyword', value: ->(status) { status.account.domain || '' })
|
field(:domain, type: 'keyword', value: ->(status) { status.account.domain || '' })
|
||||||
field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties })
|
field(:properties, type: 'keyword', value: ->(status) { status.searchable_properties })
|
||||||
field(:created_at, type: 'date')
|
field(:created_at, type: 'date', value: ->(status) { clamp_date(status.created_at) })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class TagsIndex < Chewy::Index
|
class TagsIndex < Chewy::Index
|
||||||
|
include DatetimeClampingConcern
|
||||||
|
|
||||||
settings index: index_preset(refresh_interval: '30s'), analysis: {
|
settings index: index_preset(refresh_interval: '30s'), analysis: {
|
||||||
analyzer: {
|
analyzer: {
|
||||||
content: {
|
content: {
|
||||||
|
@ -42,6 +44,6 @@ class TagsIndex < Chewy::Index
|
||||||
field(:name, type: 'text', analyzer: 'content', value: :display_name) { field(:edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'content') }
|
field(:name, type: 'text', analyzer: 'content', value: :display_name) { field(:edge_ngram, type: 'text', analyzer: 'edge_ngram', search_analyzer: 'content') }
|
||||||
field(:reviewed, type: 'boolean', value: ->(tag) { tag.reviewed? })
|
field(:reviewed, type: 'boolean', value: ->(tag) { tag.reviewed? })
|
||||||
field(:usage, type: 'long', value: ->(tag, crutches) { tag.history.aggregate(crutches.time_period).accounts })
|
field(:usage, type: 'long', value: ->(tag, crutches) { tag.history.aggregate(crutches.time_period).accounts })
|
||||||
field(:last_status_at, type: 'date', value: ->(tag) { tag.last_status_at || tag.created_at })
|
field(:last_status_at, type: 'date', value: ->(tag) { clamp_date(tag.last_status_at || tag.created_at) })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
|
/* eslint-disable @typescript-eslint/no-unsafe-call,
|
||||||
|
@typescript-eslint/no-unsafe-return,
|
||||||
|
@typescript-eslint/no-unsafe-assignment,
|
||||||
|
@typescript-eslint/no-unsafe-member-access
|
||||||
|
-- the settings store is not yet typed */
|
||||||
import type { PropsWithChildren } from 'react';
|
import type { PropsWithChildren } from 'react';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState, useEffect } from 'react';
|
||||||
|
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
|
import { ReactComponent as CloseIcon } from '@material-symbols/svg-600/outlined/close.svg';
|
||||||
|
|
||||||
|
import { changeSetting } from 'mastodon/actions/settings';
|
||||||
import { bannerSettings } from 'mastodon/settings';
|
import { bannerSettings } from 'mastodon/settings';
|
||||||
|
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
||||||
|
|
||||||
import { IconButton } from './icon_button';
|
import { IconButton } from './icon_button';
|
||||||
|
|
||||||
|
@ -21,13 +28,25 @@ export const DismissableBanner: React.FC<PropsWithChildren<Props>> = ({
|
||||||
id,
|
id,
|
||||||
children,
|
children,
|
||||||
}) => {
|
}) => {
|
||||||
const [visible, setVisible] = useState(!bannerSettings.get(id));
|
const dismissed = useAppSelector((state) =>
|
||||||
|
state.settings.getIn(['dismissed_banners', id], false),
|
||||||
|
);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const [visible, setVisible] = useState(!bannerSettings.get(id) && !dismissed);
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
const handleDismiss = useCallback(() => {
|
const handleDismiss = useCallback(() => {
|
||||||
setVisible(false);
|
setVisible(false);
|
||||||
bannerSettings.set(id, true);
|
bannerSettings.set(id, true);
|
||||||
}, [id]);
|
dispatch(changeSetting(['dismissed_banners', id], true));
|
||||||
|
}, [id, dispatch]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!visible && !dismissed) {
|
||||||
|
dispatch(changeSetting(['dismissed_banners', id], true));
|
||||||
|
}
|
||||||
|
}, [id, dispatch, visible, dismissed]);
|
||||||
|
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -113,6 +113,15 @@ const initialState = ImmutableMap({
|
||||||
body: '',
|
body: '',
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
dismissed_banners: ImmutableMap({
|
||||||
|
'public_timeline': false,
|
||||||
|
'community_timeline': false,
|
||||||
|
'home.explore_prompt': false,
|
||||||
|
'explore/links': false,
|
||||||
|
'explore/statuses': false,
|
||||||
|
'explore/tags': false,
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
const defaultColumns = fromJS([
|
const defaultColumns = fromJS([
|
||||||
|
|
|
@ -2371,8 +2371,7 @@ $ui-header-height: 55px;
|
||||||
|
|
||||||
> .scrollable {
|
> .scrollable {
|
||||||
background: $ui-base-color;
|
background: $ui-base-color;
|
||||||
border-bottom-left-radius: 4px;
|
border-radius: 0 0 4px 4px;
|
||||||
border-bottom-right-radius: 4px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,9 +52,13 @@ module Attachmentable
|
||||||
return if attachment.blank? || !/image.*/.match?(attachment.content_type) || attachment.queued_for_write[:original].blank?
|
return if attachment.blank? || !/image.*/.match?(attachment.content_type) || attachment.queued_for_write[:original].blank?
|
||||||
|
|
||||||
width, height = FastImage.size(attachment.queued_for_write[:original].path)
|
width, height = FastImage.size(attachment.queued_for_write[:original].path)
|
||||||
matrix_limit = attachment.content_type == 'image/gif' ? GIF_MATRIX_LIMIT : MAX_MATRIX_LIMIT
|
return unless width.present? && height.present?
|
||||||
|
|
||||||
raise Mastodon::DimensionsValidationError, "#{width}x#{height} images are not supported" if width.present? && height.present? && (width * height > matrix_limit)
|
if attachment.content_type == 'image/gif' && width * height > GIF_MATRIX_LIMIT
|
||||||
|
raise Mastodon::DimensionsValidationError, "#{width}x#{height} GIF files are not supported"
|
||||||
|
elsif width * height > MAX_MATRIX_LIMIT
|
||||||
|
raise Mastodon::DimensionsValidationError, "#{width}x#{height} images are not supported"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def appropriate_extension(attachment)
|
def appropriate_extension(attachment)
|
||||||
|
|
|
@ -56,7 +56,7 @@ services:
|
||||||
|
|
||||||
web:
|
web:
|
||||||
build: .
|
build: .
|
||||||
image: ghcr.io/mastodon/mastodon:v4.2.1
|
image: ghcr.io/mastodon/mastodon:v4.2.2
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
|
command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000"
|
||||||
|
@ -77,7 +77,7 @@ services:
|
||||||
|
|
||||||
streaming:
|
streaming:
|
||||||
build: .
|
build: .
|
||||||
image: ghcr.io/mastodon/mastodon:v4.2.1
|
image: ghcr.io/mastodon/mastodon:v4.2.2
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: node ./streaming
|
command: node ./streaming
|
||||||
|
@ -95,7 +95,7 @@ services:
|
||||||
|
|
||||||
sidekiq:
|
sidekiq:
|
||||||
build: .
|
build: .
|
||||||
image: ghcr.io/mastodon/mastodon:v4.2.1
|
image: ghcr.io/mastodon/mastodon:v4.2.2
|
||||||
restart: always
|
restart: always
|
||||||
env_file: .env.production
|
env_file: .env.production
|
||||||
command: bundle exec sidekiq
|
command: bundle exec sidekiq
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue