Merge commit '15182d1e5e595b21c47b48c5d258f30a0251e753' into glitch-soc/merge-upstream

Conflicts:
- `.rubocop_todo.yml`:
  glitch-soc had extra ignores.
  Removed them.
th-new
Claire 2023-10-24 20:31:20 +02:00
commit 4ef66d6538
69 changed files with 419 additions and 374 deletions

View File

@ -0,0 +1,19 @@
name: 'Setup Javascript'
description: 'Setup a Javascript environment ready to run the Mastodon code'
inputs:
onlyProduction:
description: Only install production dependencies
default: 'false'
runs:
using: 'composite'
steps:
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
shell: bash
run: yarn --frozen-lockfile ${{ inputs.onlyProduction != 'false' && '--production' || '' }}

23
.github/actions/setup-ruby/action.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: 'Setup RUby'
description: 'Setup a Ruby environment ready to run the Mastodon code'
inputs:
ruby-version:
description: The Ruby version to install
default: '.ruby-version'
additional-system-dependencies:
description: 'Additional packages to install'
runs:
using: 'composite'
steps:
- name: Install system dependencies
shell: bash
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev ${{ inputs.additional-system-dependencies }}
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ inputs.ruby-version }}
bundler-cache: true

View File

@ -27,14 +27,8 @@ jobs:
- name: Clone repository
uses: actions/checkout@v4
- name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
- name: Run bundler-audit
run: bundle exec bundler-audit

View File

@ -19,25 +19,11 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Check for missing strings in English JSON
run: |

View File

@ -45,14 +45,8 @@ jobs:
run: sudo chown -R runner:docker .
# This is needed to run the normalize step
- name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
- name: Run i18n normalize task
run: bundle exec i18n-tasks normalize

View File

@ -35,14 +35,8 @@ jobs:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- uses: xt0rted/stylelint-problem-matcher@v1

View File

@ -30,16 +30,8 @@ jobs:
- name: Clone repository
uses: actions/checkout@v4
- name: Install native Ruby dependencies
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
- name: Run haml-lint
run: |

View File

@ -39,14 +39,8 @@ jobs:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: ESLint
run: yarn lint:js --max-warnings 0

View File

@ -31,14 +31,8 @@ jobs:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Prettier
run: yarn lint:json

View File

@ -31,14 +31,8 @@ jobs:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Prettier
run: yarn lint:md

View File

@ -31,14 +31,8 @@ jobs:
- name: Clone repository
uses: actions/checkout@v4
- name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
- name: Set-up RuboCop Problem Matcher
uses: r7kamura/rubocop-problem-matchers-action@v1

View File

@ -33,14 +33,8 @@ jobs:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Prettier
run: yarn lint:yml

View File

@ -35,14 +35,8 @@ jobs:
- name: Clone repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install all yarn packages
run: yarn --frozen-lockfile
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Jest testing
run: yarn jest --reporters github-actions summary

View File

@ -72,16 +72,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install native Ruby dependencies
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
- name: Create database
run: './bin/rails db:create'

View File

@ -71,16 +71,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Install native Ruby dependencies
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
- name: Create database
run: './bin/rails db:create'

View File

@ -34,24 +34,14 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v3
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
with:
cache: yarn
node-version-file: '.nvmrc'
onlyProduction: 'true'
- name: Install native Ruby dependencies
run: |
sudo apt-get update
sudo apt-get install -y libicu-dev libidn11-dev
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
with:
ruby-version: .ruby-version
bundler-cache: true
- run: yarn --frozen-lockfile --production
- name: Precompile assets
# Previously had set this, but it's not supported
# export NODE_OPTIONS=--openssl-legacy-provider
@ -135,20 +125,11 @@ jobs:
path: './public'
name: ${{ github.sha }}
- name: Update package index
run: sudo apt-get update
- name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Install additional system dependencies
run: sudo apt-get install -y ffmpeg imagemagick libpam-dev
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
with:
ruby-version: ${{ matrix.ruby-version}}
bundler-cache: true
additional-system-dependencies: ffmpeg imagemagick libpam-dev
- name: Load database schema
run: './bin/rails db:create db:schema:load db:seed'
@ -210,28 +191,14 @@ jobs:
path: './public'
name: ${{ github.sha }}
- name: Update package index
run: sudo apt-get update
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Install additional system dependencies
run: sudo apt-get install -y ffmpeg imagemagick
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
with:
ruby-version: ${{ matrix.ruby-version}}
bundler-cache: true
additional-system-dependencies: ffmpeg imagemagick
- run: yarn --frozen-lockfile
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Load database schema
run: './bin/rails db:create db:schema:load db:seed'
@ -328,28 +295,14 @@ jobs:
path: './public'
name: ${{ github.sha }}
- name: Update package index
run: sudo apt-get update
- name: Set up Node.js
uses: actions/setup-node@v3
with:
cache: yarn
node-version-file: '.nvmrc'
- name: Install native Ruby dependencies
run: sudo apt-get install -y libicu-dev libidn11-dev
- name: Install additional system dependencies
run: sudo apt-get install -y ffmpeg imagemagick
- name: Set up bundler cache
uses: ruby/setup-ruby@v1
- name: Set up Ruby environment
uses: ./.github/actions/setup-ruby
with:
ruby-version: ${{ matrix.ruby-version}}
bundler-cache: true
additional-system-dependencies: ffmpeg imagemagick
- run: yarn --frozen-lockfile
- name: Set up Javascript environment
uses: ./.github/actions/setup-javascript
- name: Load database schema
run: './bin/rails db:create db:schema:load db:seed'

View File

@ -1,30 +1,74 @@
# This configuration was generated by
# `haml-lint --auto-gen-config`
# on 2023-10-11 11:31:24 -0400 using Haml-Lint version 0.51.0.
# on 2023-10-23 10:16:00 -0400 using Haml-Lint version 0.51.0.
# The point is for the user to remove these configuration records
# one by one as the lints are removed from the code base.
# Note that changes in the inspected code, or installation of new
# versions of Haml-Lint, may require this file to be generated again.
linters:
# Offense count: 946
# Offense count: 944
LineLength:
enabled: false
# Offense count: 22
UnnecessaryStringOutput:
enabled: false
# Offense count: 44
RuboCop:
enabled: false
# Offense count: 3
ViewLength:
exclude:
- 'app/views/admin/accounts/show.html.haml'
- 'app/views/admin/reports/show.html.haml'
- 'app/views/accounts/show.html.haml'
- 'app/views/admin/custom_emojis/_custom_emoji.html.haml'
- 'app/views/admin/relays/_relay.html.haml'
- 'app/views/admin/rules/_rule.html.haml'
- 'app/views/admin/statuses/index.html.haml'
- 'app/views/auth/registrations/_session.html.haml'
- 'app/views/disputes/strikes/show.html.haml'
- 'app/views/notification_mailer/_status.html.haml'
- 'app/views/settings/two_factor_authentication_methods/index.html.haml'
- 'app/views/statuses/_detailed_status.html.haml'
- 'app/views/statuses/_poll.html.haml'
- 'app/views/statuses/_simple_status.html.haml'
- 'app/views/user_mailer/suspicious_sign_in.html.haml'
- 'app/views/user_mailer/webauthn_credential_added.html.haml'
- 'app/views/user_mailer/webauthn_credential_deleted.html.haml'
- 'app/views/user_mailer/welcome.html.haml'
# Offense count: 45
RuboCop:
exclude:
- 'app/views/admin/accounts/_account.html.haml'
- 'app/views/admin/accounts/_buttons.html.haml'
- 'app/views/admin/accounts/_local_account.html.haml'
- 'app/views/admin/accounts/_remote_account.html.haml'
- 'app/views/admin/accounts/index.html.haml'
- 'app/views/admin/accounts/show.html.haml'
- 'app/views/admin/custom_emojis/index.html.haml'
- 'app/views/admin/dashboard/index.html.haml'
- 'app/views/admin/domain_blocks/confirm_suspension.html.haml'
- 'app/views/admin/follow_recommendations/show.html.haml'
- 'app/views/admin/invites/_invite.html.haml'
- 'app/views/admin/invites/index.html.haml'
- 'app/views/admin/ip_blocks/index.html.haml'
- 'app/views/admin/reports/_status.html.haml'
- 'app/views/admin/reports/show.html.haml'
- 'app/views/admin/roles/_form.html.haml'
- 'app/views/admin/software_updates/index.html.haml'
- 'app/views/admin/status_edits/_status_edit.html.haml'
- 'app/views/admin/statuses/index.html.haml'
- 'app/views/admin/tags/show.html.haml'
- 'app/views/admin/trends/tags/_tag.html.haml'
- 'app/views/auth/registrations/_session.html.haml'
- 'app/views/auth/registrations/new.html.haml'
- 'app/views/auth/sessions/two_factor.html.haml'
- 'app/views/auth/shared/_progress.html.haml'
- 'app/views/disputes/strikes/_card.html.haml'
- 'app/views/filters/statuses/index.html.haml'
- 'app/views/invites/_invite.html.haml'
- 'app/views/layouts/application.html.haml'
- 'app/views/layouts/error.html.haml'
- 'app/views/statuses/_detailed_status.html.haml'
- 'app/views/statuses/_og_image.html.haml'
- 'app/views/statuses/_simple_status.html.haml'
- 'app/views/statuses_cleanup/show.html.haml'
- 'app/views/user_mailer/warning.html.haml'
# Offense count: 2
IdNames:

View File

@ -1,6 +1,6 @@
# This configuration was generated by
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp`
# using RuboCop version 1.56.1.
# using RuboCop version 1.57.1.
# The point is for the user to remove these configuration records
# one by one as the offenses are removed from the code base.
# Note that changes in the inspected code, or installation of new
@ -217,19 +217,6 @@ Rails/ApplicationController:
Exclude:
- 'app/controllers/health_controller.rb'
# Configuration parameters: Include.
# Include: db/**/*.rb
Rails/CreateTableWithTimestamps:
Exclude:
- 'db/migrate/20170508230434_create_conversation_mutes.rb'
- 'db/migrate/20170823162448_create_status_pins.rb'
- 'db/migrate/20171116161857_create_list_accounts.rb'
- 'db/migrate/20180929222014_create_account_conversations.rb'
- 'db/migrate/20181007025445_create_pghero_space_stats.rb'
- 'db/migrate/20190103124649_create_scheduled_statuses.rb'
- 'db/migrate/20220824233535_create_status_trends.rb'
- 'db/migrate/20221006061337_create_preview_card_trends.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: Severity.
Rails/DuplicateAssociation:
@ -271,7 +258,6 @@ Rails/LexicallyScopedActionFilter:
Exclude:
- 'app/controllers/auth/passwords_controller.rb'
- 'app/controllers/auth/registrations_controller.rb'
- 'app/controllers/auth/sessions_controller.rb'
# This cop supports unsafe autocorrection (--autocorrect-all).
Rails/NegateInclude:
@ -287,7 +273,6 @@ Rails/NegateInclude:
- 'app/models/custom_filter.rb'
- 'app/services/activitypub/process_status_update_service.rb'
- 'app/services/fetch_link_card_service.rb'
- 'app/services/search_service.rb'
- 'app/workers/web/push_notification_worker.rb'
- 'lib/paperclip/color_extractor.rb'
@ -307,24 +292,6 @@ Rails/RakeEnvironment:
- 'lib/tasks/repo.rake'
- 'lib/tasks/statistics.rake'
# Configuration parameters: Include.
# Include: db/**/*.rb
Rails/ReversibleMigration:
Exclude:
- 'db/migrate/20160223164502_make_uris_nullable_in_statuses.rb'
- 'db/migrate/20161122163057_remove_unneeded_indexes.rb'
- 'db/migrate/20170205175257_remove_devices.rb'
- 'db/migrate/20170322143850_change_primary_key_to_bigint_on_statuses.rb'
- 'db/migrate/20170520145338_change_language_filter_to_opt_out.rb'
- 'db/migrate/20170609145826_remove_default_language_from_statuses.rb'
- 'db/migrate/20170711225116_fix_null_booleans.rb'
- 'db/migrate/20171129172043_add_index_on_stream_entries.rb'
- 'db/migrate/20171212195226_remove_duplicate_indexes_in_lists.rb'
- 'db/migrate/20171226094803_more_faster_index_on_notifications.rb'
- 'db/migrate/20180106000232_add_index_on_statuses_for_api_v1_accounts_account_id_statuses.rb'
- 'db/migrate/20180617162849_remove_unused_indexes.rb'
- 'db/migrate/20220827195229_change_canonical_email_blocks_nullable.rb'
# Configuration parameters: ForbiddenMethods, AllowedMethods.
# ForbiddenMethods: decrement!, decrement_counter, increment!, increment_counter, insert, insert!, insert_all, insert_all!, toggle!, touch, touch_all, update_all, update_attribute, update_column, update_columns, update_counters, upsert, upsert_all
Rails/SkipsModelValidations:
@ -377,31 +344,6 @@ Rails/SkipsModelValidations:
- 'spec/services/follow_service_spec.rb'
- 'spec/services/update_account_service_spec.rb'
# Configuration parameters: Include.
# Include: db/**/*.rb
Rails/ThreeStateBooleanColumn:
Exclude:
- 'db/migrate/20160325130944_add_admin_to_users.rb'
- 'db/migrate/20161123093447_add_sensitive_to_statuses.rb'
- 'db/migrate/20170123203248_add_reject_media_to_domain_blocks.rb'
- 'db/migrate/20170127165745_add_devise_two_factor_to_users.rb'
- 'db/migrate/20170209184350_add_reply_to_statuses.rb'
- 'db/migrate/20170330163835_create_imports.rb'
- 'db/migrate/20170905165803_add_local_to_statuses.rb'
- 'db/migrate/20171210213213_add_local_only_flag_to_statuses.rb'
- 'db/migrate/20181203021853_add_discoverable_to_accounts.rb'
- 'db/migrate/20190509164208_add_by_moderator_to_tombstone.rb'
- 'db/migrate/20190805123746_add_capabilities_to_tags.rb'
- 'db/migrate/20191212163405_add_hide_collections_to_accounts.rb'
- 'db/migrate/20200309150742_add_forwarded_to_reports.rb'
- 'db/migrate/20210609202149_create_login_activities.rb'
- 'db/migrate/20210621221010_add_skip_sign_in_token_to_users.rb'
- 'db/migrate/20211031031021_create_preview_card_providers.rb'
- 'db/migrate/20211115032527_add_trendable_to_preview_cards.rb'
- 'db/migrate/20220202200743_add_trendable_to_accounts.rb'
- 'db/migrate/20220202200926_add_trendable_to_statuses.rb'
- 'db/migrate/20220303000827_add_ordered_media_attachment_ids_to_status_edits.rb'
# Configuration parameters: Include.
# Include: app/models/**/*.rb
Rails/UniqueValidationWithoutIndex:
@ -465,7 +407,7 @@ Style/CaseEquality:
Exclude:
- 'config/initializers/trusted_proxies.rb'
# This cop supports safe autocorrection (--autocorrect).
# This cop supports unsafe autocorrection (--autocorrect-all).
# Configuration parameters: AllowedMethods, AllowedPatterns.
# AllowedMethods: ==, equal?, eql?
Style/ClassEqualityComparison:
@ -673,7 +615,6 @@ Style/RedundantReturn:
Style/SafeNavigation:
Exclude:
- 'app/models/concerns/account_finder_concern.rb'
- 'app/models/status.rb'
# This cop supports safe autocorrection (--autocorrect).
# Configuration parameters: EnforcedStyle.

View File

@ -3,7 +3,7 @@ import { PureComponent } from 'react';
import { assetHost } from 'mastodon/utils/config';
import unicodeMapping from '../features/emoji/emoji_unicode_mapping_light';
import { unicodeMapping } from '../features/emoji/emoji_unicode_mapping_light';
export default class AutosuggestEmoji extends PureComponent {

View File

@ -3,7 +3,11 @@ import React from 'react';
import { Router as OriginalRouter } from 'react-router';
import type { LocationDescriptor, Path } from 'history';
import type {
LocationDescriptor,
LocationDescriptorObject,
Path,
} from 'history';
import { createBrowserHistory } from 'history';
import { layoutFromWindow } from 'mastodon/is_mobile';
@ -20,39 +24,55 @@ const browserHistory = createBrowserHistory<
const originalPush = browserHistory.push.bind(browserHistory);
const originalReplace = browserHistory.replace.bind(browserHistory);
function extractRealPath(path: HistoryPath) {
if (typeof path === 'string') return path;
else return path.pathname;
function normalizePath(
path: HistoryPath,
state?: MastodonLocationState,
): LocationDescriptorObject<MastodonLocationState> {
const location = typeof path === 'string' ? { pathname: path } : { ...path };
if (location.state === undefined && state !== undefined) {
location.state = state;
} else if (
location.state !== undefined &&
state !== undefined &&
process.env.NODE_ENV === 'development'
) {
// eslint-disable-next-line no-console
console.log(
'You should avoid providing a 2nd state argument to push when the 1st argument is a location-like object that already has state; it is ignored',
);
}
if (
layoutFromWindow() === 'multi-column' &&
!location.pathname?.startsWith('/deck')
) {
location.pathname = `/deck${location.pathname}`;
}
return location;
}
browserHistory.push = (path: HistoryPath, state?: MastodonLocationState) => {
state = state ?? {};
state.fromMastodon = true;
const location = normalizePath(path, state);
const realPath = extractRealPath(path);
if (!realPath) return;
location.state = location.state ?? {};
location.state.fromMastodon = true;
if (layoutFromWindow() === 'multi-column' && !realPath.startsWith('/deck')) {
originalPush(`/deck${realPath}`, state);
} else {
originalPush(path, state);
}
originalPush(location);
};
browserHistory.replace = (path: HistoryPath, state?: MastodonLocationState) => {
const location = normalizePath(path, state);
if (!location.pathname) return;
if (browserHistory.location.state?.fromMastodon) {
state = state ?? {};
state.fromMastodon = true;
location.state = location.state ?? {};
location.state.fromMastodon = true;
}
const realPath = extractRealPath(path);
if (!realPath) return;
if (layoutFromWindow() === 'multi-column' && !realPath.startsWith('/deck')) {
originalReplace(`/deck${realPath}`, state);
} else {
originalReplace(path, state);
}
originalReplace(location);
};
export const Router: React.FC<PropsWithChildren> = ({ children }) => {

View File

@ -4,7 +4,7 @@ import { assetHost } from 'mastodon/utils/config';
import { autoPlayGif } from '../../initial_state';
import unicodeMapping from './emoji_unicode_mapping_light';
import { unicodeMapping } from './emoji_unicode_mapping_light';
const trie = new Trie(Object.keys(unicodeMapping));

View File

@ -13,15 +13,20 @@ export type Search = string;
* This could be a potential area of refactoring or error handling.
* The non-existence of 'skins' property is evident at [this location]{@link app/javascript/mastodon/features/emoji/emoji_compressed.js:121}.
*/
export type Skins = null;
type Skins = null;
export type FilenameData = string[] | string[][];
type Filename = string;
type UnicodeFilename = string;
export type FilenameData = [
filename: Filename,
unicodeFilename?: UnicodeFilename,
][];
export type ShortCodesToEmojiDataKey =
| EmojiData['id']
| BaseEmoji['native']
| keyof NimbleEmojiIndex['emojis'];
export type SearchData = [
type SearchData = [
BaseEmoji['native'],
Emoji['short_names'],
Search,
@ -32,9 +37,9 @@ export type ShortCodesToEmojiData = Record<
ShortCodesToEmojiDataKey,
[FilenameData, SearchData]
>;
export type EmojisWithoutShortCodes = FilenameData[];
type EmojisWithoutShortCodes = FilenameData;
export type EmojiCompressed = [
type EmojiCompressed = [
ShortCodesToEmojiData,
Skins,
Category[],

View File

@ -30,22 +30,13 @@ const emojis: Emojis = {};
// decompress
Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
const [_filenameData, searchData] = shortCodesToEmojiData[shortCode];
const native = searchData[0];
let short_names = searchData[1];
const search = searchData[2];
let unified = searchData[3];
const [native, short_names, search, unified] = searchData;
if (!unified) {
// unified name can be derived from unicodeToUnifiedName
unified = unicodeToUnifiedName(native);
}
if (short_names) short_names = [shortCode].concat(short_names);
emojis[shortCode] = {
native,
search,
short_names,
unified,
short_names: short_names ? [shortCode].concat(short_names) : undefined,
unified: unified ?? unicodeToUnifiedName(native),
};
});

View File

@ -1,37 +0,0 @@
// A mapping of unicode strings to an object containing the filename
// (i.e. the svg filename) and a shortCode intended to be shown
// as a "title" attribute in an HTML element (aka tooltip).
import emojiCompressed from './emoji_compressed';
import { unicodeToFilename } from './unicode_to_filename';
const [
shortCodesToEmojiData,
_skins,
_categories,
_short_names,
emojisWithoutShortCodes,
] = emojiCompressed;
// decompress
const unicodeMapping = {};
function processEmojiMapData(emojiMapData, shortCode) {
let [ native, filename ] = emojiMapData;
if (!filename) {
// filename name can be derived from unicodeToFilename
filename = unicodeToFilename(native);
}
unicodeMapping[native] = {
shortCode: shortCode,
filename: filename,
};
}
Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
let [ filenameData ] = shortCodesToEmojiData[shortCode];
filenameData.forEach(emojiMapData => processEmojiMapData(emojiMapData, shortCode));
});
emojisWithoutShortCodes.forEach(emojiMapData => processEmojiMapData(emojiMapData));
export default unicodeMapping;

View File

@ -0,0 +1,60 @@
// A mapping of unicode strings to an object containing the filename
// (i.e. the svg filename) and a shortCode intended to be shown
// as a "title" attribute in an HTML element (aka tooltip).
import type {
FilenameData,
ShortCodesToEmojiDataKey,
} from './emoji_compressed';
import emojiCompressed from './emoji_compressed';
import { unicodeToFilename } from './unicode_to_filename';
type UnicodeMapping = {
[key in FilenameData[number][0]]: {
shortCode: ShortCodesToEmojiDataKey;
filename: FilenameData[number][number];
};
};
const [
shortCodesToEmojiData,
_skins,
_categories,
_short_names,
emojisWithoutShortCodes,
] = emojiCompressed;
// decompress
const unicodeMapping: UnicodeMapping = {};
function processEmojiMapData(
emojiMapData: FilenameData[number],
shortCode?: ShortCodesToEmojiDataKey,
) {
const [native, _filename] = emojiMapData;
let filename = emojiMapData[1];
if (!filename) {
// filename name can be derived from unicodeToFilename
filename = unicodeToFilename(native);
}
unicodeMapping[native] = {
shortCode,
filename,
};
}
Object.keys(shortCodesToEmojiData).forEach(
(shortCode: ShortCodesToEmojiDataKey) => {
if (shortCode === undefined) return;
const [filenameData, _searchData] = shortCodesToEmojiData[shortCode];
filenameData.forEach((emojiMapData) => {
processEmojiMapData(emojiMapData, shortCode);
});
},
);
emojisWithoutShortCodes.forEach((emojiMapData) => {
processEmojiMapData(emojiMapData);
});
export { unicodeMapping };

View File

@ -18,7 +18,7 @@ import { AnimatedNumber } from 'mastodon/components/animated_number';
import { Icon } from 'mastodon/components/icon';
import { IconButton } from 'mastodon/components/icon_button';
import EmojiPickerDropdown from 'mastodon/features/compose/containers/emoji_picker_dropdown_container';
import unicodeMapping from 'mastodon/features/emoji/emoji_unicode_mapping_light';
import { unicodeMapping } from 'mastodon/features/emoji/emoji_unicode_mapping_light';
import { autoPlayGif, reduceMotion, disableSwiping, mascot } from 'mastodon/initial_state';
import { assetHost } from 'mastodon/utils/config';
import { WithRouterPropTypes } from 'mastodon/utils/react_router';

View File

@ -534,6 +534,7 @@
"reply_indicator.cancel": "Zrušit",
"report.block": "Blokovat",
"report.block_explanation": "Neuvidíte příspěvky tohoto uživatele. On neuvidí vaše příspěvky, ani vás nebude moci sledovat. Pozná, že je blokován.",
"report.categories.legal": "Právní ustanovení",
"report.categories.other": "Ostatní",
"report.categories.spam": "Spam",
"report.categories.violation": "Obsah porušuje jedno nebo více pravidel serveru",
@ -590,6 +591,7 @@
"search_popout.options": "Možnosti hledání",
"search_popout.quick_actions": "Rychlé akce",
"search_popout.recent": "Nedávná vyhledávání",
"search_popout.specific_date": "konkrétní datum",
"search_popout.user": "uživatel",
"search_results.accounts": "Profily",
"search_results.all": "Vše",

View File

@ -590,6 +590,7 @@
"search.quick_action.open_url": "在 Mastodon 中打開網址",
"search.quick_action.status_search": "符合的帖文 {x}",
"search.search_or_paste": "搜尋或貼上網址",
"search_popout.full_text_search_disabled_message": "在 {domain} 上無法使用。",
"search_popout.language_code": "ISO 語言代碼",
"search_popout.options": "搜尋選項",
"search_popout.quick_actions": "快速動作",

View File

@ -662,9 +662,9 @@
"status.share": "分享",
"status.show_filter_reason": "仍要顯示",
"status.show_less": "減少顯示",
"status.show_less_all": "減少顯示這類嘟文",
"status.show_less_all": "隱藏所有內容警告與額外標籤",
"status.show_more": "顯示更多",
"status.show_more_all": "顯示更多這類嘟文",
"status.show_more_all": "顯示所有內容警告與額外標籤",
"status.show_original": "顯示原文",
"status.title.with_attachments": "{user} 嘟了 {attachmentCount, plural, other {{attachmentCount} 個附加檔案}}",
"status.translate": "翻譯",

View File

@ -23,10 +23,7 @@ class AccountAlias < ApplicationRecord
after_create :add_to_account
after_destroy :remove_from_account
def acct=(val)
val = val.to_s.strip
super(val.start_with?('@') ? val[1..] : val)
end
normalizes :acct, with: ->(acct) { acct.strip.delete_prefix('@') }
def pretty_acct
username, domain = acct.split('@', 2)

View File

@ -25,6 +25,8 @@ class AccountMigration < ApplicationRecord
before_validation :set_target_account
before_validation :set_followers_count
normalizes :acct, with: ->(acct) { acct.strip.delete_prefix('@') }
validates :acct, presence: true, domain: { acct: true }
validate :validate_migration_cooldown
validate :validate_target_account
@ -51,10 +53,6 @@ class AccountMigration < ApplicationRecord
created_at + COOLDOWN_PERIOD
end
def acct=(val)
super(val.to_s.strip.gsub(/\A@/, ''))
end
private
def set_target_account

View File

@ -27,7 +27,7 @@ class AccountWarning < ApplicationRecord
suspend: 4_000,
}, _suffix: :action
before_validation :before_validate
normalizes :text, with: ->(text) { text.to_s }, apply_to_nil: true
belongs_to :account, inverse_of: :account_warnings
belongs_to :target_account, class_name: 'Account', inverse_of: :strikes
@ -50,10 +50,4 @@ class AccountWarning < ApplicationRecord
def to_log_human_identifier
target_account.acct
end
private
def before_validate
self.text = '' if text.blank?
end
end

View File

@ -23,7 +23,7 @@ class FeaturedTag < ApplicationRecord
validate :validate_tag_uniqueness, on: :create
validate :validate_featured_tags_limit, on: :create
before_validation :strip_name
normalizes :name, with: ->(name) { name.strip.delete_prefix('#') }
before_create :set_tag
before_create :reset_data
@ -50,10 +50,6 @@ class FeaturedTag < ApplicationRecord
private
def strip_name
self.name = name&.strip&.delete_prefix('#')
end
def set_tag
self.tag = Tag.find_or_create_by_names(name)&.first
end

View File

@ -19,7 +19,8 @@ class Relay < ApplicationRecord
scope :enabled, -> { accepted }
before_validation :strip_url
normalizes :inbox_url, with: ->(inbox_url) { inbox_url.strip }
before_destroy :ensure_disabled
alias enabled? accepted?
@ -76,8 +77,4 @@ class Relay < ApplicationRecord
def ensure_disabled
disable! if enabled?
end
def strip_url
inbox_url&.strip!
end
end

View File

@ -3,7 +3,7 @@
- if self_destruct?
.flash-message.warning
= t('auth.status.self_destruct', domain: ENV['LOCAL_DOMAIN'])
= t('auth.status.self_destruct', domain: ENV.fetch('LOCAL_DOMAIN'))
- else
= render partial: 'status', locals: { user: @user, strikes: @strikes }

View File

@ -3,7 +3,7 @@
.simple_form
%h1.title= t('self_destruct.title')
%p.lead= t('self_destruct.lead_html', domain: ENV['LOCAL_DOMAIN'])
%p.lead= t('self_destruct.lead_html', domain: ENV.fetch('LOCAL_DOMAIN'))
.form-footer
%ul.no-list

View File

@ -556,6 +556,7 @@ cs:
total_reported: Hlášení o nich
total_storage: Mediální přílohy
totals_time_period_hint_html: Níže zobrazené součty zahrnují data za celou dobu.
unknown_instance: Na tomto serveru momentálně neexistuje žádný záznam o této doméně.
invites:
deactivate_all: Deaktivovat vše
filter:

View File

@ -578,6 +578,7 @@ cy:
total_reported: Adroddiadau amdanyn nhw
total_storage: Atodiadau cyfryngau
totals_time_period_hint_html: Mae'r cyfansymiau sy'n cael eu dangos isod yn cynnwys data am y cyfnod cyfan.
unknown_instance: Nid oes cofnod o'r parth hwn ar y gweinydd hwn ar hyn o bryd.
invites:
deactivate_all: Dadweithredu popeth
filter:

View File

@ -534,6 +534,7 @@ da:
total_reported: Anmeldelser om dem
total_storage: Medievedhæftninger
totals_time_period_hint_html: Nedenfor viste totaler omfatter data for alle tidsperioder.
unknown_instance: Der er i pt. ingen post for dette domæne på denne server.
invites:
deactivate_all: Deaktivér alle
filter:

View File

@ -534,6 +534,7 @@ de:
total_reported: Beschwerden über sie
total_storage: Medienanhänge
totals_time_period_hint_html: Die unten angezeigten Summen enthalten Daten für alle Zeiten.
unknown_instance: Auf diesem Server gibt es derzeit keinen Eintrag dieser Domain.
invites:
deactivate_all: Alle deaktivieren
filter:
@ -1101,6 +1102,7 @@ de:
functional: Dein Konto ist voll funktionsfähig.
pending: Die Prüfung deiner Bewerbung steht noch aus. Dies kann einige Zeit in Anspruch nehmen. Sobald deine Bewerbung genehmigt wurde, erhältst du eine E-Mail.
redirecting_to: Dein Konto ist inaktiv, weil es zu %{acct} umgezogen ist.
self_destruct: Da %{domain} den Betrieb einstellen wird, wirst du nur begrenzten Zugriff auf dein Konto haben.
view_strikes: Vorherige Verstöße deines Kontos ansehen
too_fast: Formular zu schnell übermittelt. Bitte versuche es erneut.
use_security_key: Sicherheitsschlüssel verwenden
@ -1570,6 +1572,9 @@ de:
over_daily_limit: Du hast das Limit von %{limit} geplanten Beiträgen für heute erreicht
over_total_limit: Du hast das Limit für geplante Beiträge, das %{limit} beträgt, erreicht
too_soon: Das geplante Datum muss in der Zukunft liegen
self_destruct:
lead_html: Bedauerlicherweise wird <strong>%{domain}</strong> den Betrieb für immer einstellen. Wenn du dort ein Konto angelegt hast, wirst du es nicht weiter verwenden können. Du kannst allerdings eine Sicherung deiner Daten anfordern.
title: Dieser Server wird den Betrieb einstellen
sessions:
activity: Letzte Aktivität
browser: Browser
@ -1769,7 +1774,7 @@ de:
subject: Dein Einspruch vom %{date} wurde abgelehnt
title: Einspruch abgelehnt
backup_ready:
explanation: Du hast eine vollständige Sicherung deines Mastodon-Kontos angefordert. Das Backup kann jetzt heruntergeladen werden!
explanation: Du hast eine vollständige Sicherung deines Mastodon-Kontos angefordert. Die Sicherung kann jetzt heruntergeladen werden!
subject: Dein persönliches Archiv kann heruntergeladen werden
title: Archiv-Download
suspicious_sign_in:

View File

@ -534,6 +534,7 @@ es-AR:
total_reported: Denuncias sobre ellas
total_storage: Adjuntos
totals_time_period_hint_html: Los datos totales mostrados a continuación incluyen datos para todo el tiempo.
unknown_instance: Actualmente no hay ningún registro de este dominio en este servidor.
invites:
deactivate_all: Desactivar todas
filter:
@ -1101,6 +1102,7 @@ es-AR:
functional: Tu cuenta está totalmente operativa.
pending: Tu solicitud está pendiente de revisión por nuestra administración. Eso puede tardar algún tiempo. Si se aprueba tu solicitud, vas a recibir un correo electrónico.
redirecting_to: Tu cuenta se encuentra inactiva porque está siendo redirigida a %{acct}.
self_destruct: Como %{domain} está en proceso de cierre, solo tendrás acceso limitado a tu cuenta.
view_strikes: Ver incumplimientos pasados contra tu cuenta
too_fast: Formulario enviado demasiado rápido, probá de nuevo.
use_security_key: Usar la llave de seguridad
@ -1570,6 +1572,9 @@ es-AR:
over_daily_limit: Superaste el límite de %{limit} mensajes programados para ese día
over_total_limit: Superaste el límite de %{limit} mensajes programados
too_soon: La fecha programada debe estar en el futuro
self_destruct:
lead_html: Desafortunadamente, <strong>%{domain}</strong> va a cerrar permanentemente. Si tenías una cuenta ahí, no podrás continuar usándola, pero aún podés solicitar una copia de tus datos.
title: Este servidor está cerrando
sessions:
activity: Última actividad
browser: Navegador web

View File

@ -534,6 +534,7 @@ es-MX:
total_reported: Informes sobre ellas
total_storage: Archivos multimedia
totals_time_period_hint_html: Los totales mostrados a continuación incluyen datos para todo el tiempo.
unknown_instance: Actualmente no hay registros de este dominio en el servidor.
invites:
deactivate_all: Desactivar todos
filter:
@ -1101,6 +1102,7 @@ es-MX:
functional: Tu cuenta está completamente operativa.
pending: Su solicitud está pendiente de revisión por nuestros administradores. Eso puede tardar algún tiempo. Usted recibirá un correo electrónico si el solicitud sea aprobada.
redirecting_to: Tu cuenta se encuentra inactiva porque está siendo redirigida a %{acct}.
self_destruct: Como %{domain} está cerrando, solo tendrás acceso limitado a tu cuenta.
view_strikes: Ver amonestaciones pasadas contra tu cuenta
too_fast: Formulario enviado demasiado rápido, inténtelo de nuevo.
use_security_key: Usar la clave de seguridad
@ -1570,6 +1572,9 @@ es-MX:
over_daily_limit: Ha superado el límite de %{limit} toots programados para ese día
over_total_limit: Ha superado el límite de %{limit} toots programados
too_soon: La fecha programada debe estar en el futuro
self_destruct:
lead_html: Desafortunadamente, <strong>%{domain}</strong> está cerrando de manera permanente. Si tenías una cuenta ahí, no puedes continuar utilizándolo, pero puedes solicitar un respaldo de tus datos.
title: Este servidor está cerrando
sessions:
activity: Última actividad
browser: Navegador

View File

@ -534,6 +534,7 @@ es:
total_reported: Informes sobre ellas
total_storage: Archivos multimedia
totals_time_period_hint_html: Los totales mostrados a continuación incluyen datos para todo el tiempo.
unknown_instance: Actualmente no hay ningún registro de este dominio en este servidor.
invites:
deactivate_all: Desactivar todos
filter:
@ -1101,6 +1102,7 @@ es:
functional: Tu cuenta está completamente operativa.
pending: Su solicitud está pendiente de revisión por nuestros administradores. Eso puede tardar algún tiempo. Usted recibirá un correo electrónico si el solicitud sea aprobada.
redirecting_to: Tu cuenta se encuentra inactiva porque está siendo redirigida a %{acct}.
self_destruct: Como %{domain} está en proceso de cierre, solo tendrás acceso limitado a tu cuenta.
view_strikes: Ver amonestaciones pasadas contra tu cuenta
too_fast: Formulario enviado demasiado rápido, inténtelo de nuevo.
use_security_key: Usar la clave de seguridad
@ -1570,6 +1572,9 @@ es:
over_daily_limit: Ha superado el límite de %{limit} publicaciones programadas para ese día
over_total_limit: Ha superado el límite de %{limit} publicaciones programadas
too_soon: La fecha programada debe estar en el futuro
self_destruct:
lead_html: Desafortunadamente, <strong>%{domain}</strong> va a cerrar permanentemente. Si tenías una cuenta allí, no podrás continuar usándola, pero aún puedes solicitar una copia de tus datos.
title: Este servidor está cerrando
sessions:
activity: Última actividad