Merge remote-tracking branch 'parent/main' into upstream-20240624
This commit is contained in:
commit
af2727387e
88 changed files with 703 additions and 597 deletions
27
.eslintrc.js
27
.eslintrc.js
|
@ -20,10 +20,6 @@ module.exports = defineConfig({
|
||||||
es6: true,
|
es6: true,
|
||||||
},
|
},
|
||||||
|
|
||||||
globals: {
|
|
||||||
ATTACHMENT_HOST: false,
|
|
||||||
},
|
|
||||||
|
|
||||||
parser: '@typescript-eslint/parser',
|
parser: '@typescript-eslint/parser',
|
||||||
|
|
||||||
plugins: [
|
plugins: [
|
||||||
|
@ -79,7 +75,7 @@ module.exports = defineConfig({
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'no-empty': 'off',
|
'no-empty': ['error', { "allowEmptyCatch": true }],
|
||||||
'no-restricted-properties': [
|
'no-restricted-properties': [
|
||||||
'error',
|
'error',
|
||||||
{ property: 'substring', message: 'Use .slice instead of .substring.' },
|
{ property: 'substring', message: 'Use .slice instead of .substring.' },
|
||||||
|
@ -94,7 +90,6 @@ module.exports = defineConfig({
|
||||||
message: "Use '·' (middle dot) instead of '•' (bullet)",
|
message: "Use '·' (middle dot) instead of '•' (bullet)",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'no-self-assign': 'off',
|
|
||||||
'no-unused-expressions': 'error',
|
'no-unused-expressions': 'error',
|
||||||
'no-unused-vars': 'off',
|
'no-unused-vars': 'off',
|
||||||
'@typescript-eslint/no-unused-vars': [
|
'@typescript-eslint/no-unused-vars': [
|
||||||
|
@ -119,12 +114,10 @@ module.exports = defineConfig({
|
||||||
'react/jsx-tag-spacing': 'error',
|
'react/jsx-tag-spacing': 'error',
|
||||||
'react/jsx-uses-react': 'off', // not needed with new JSX transform
|
'react/jsx-uses-react': 'off', // not needed with new JSX transform
|
||||||
'react/jsx-wrap-multilines': 'error',
|
'react/jsx-wrap-multilines': 'error',
|
||||||
'react/no-deprecated': 'off',
|
|
||||||
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
|
'react/react-in-jsx-scope': 'off', // not needed with new JSX transform
|
||||||
'react/self-closing-comp': 'error',
|
'react/self-closing-comp': 'error',
|
||||||
|
|
||||||
// recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.8.0/src/index.js#L46
|
// recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/v6.8.0/src/index.js#L46
|
||||||
'jsx-a11y/accessible-emoji': 'warn',
|
|
||||||
'jsx-a11y/click-events-have-key-events': 'off',
|
'jsx-a11y/click-events-have-key-events': 'off',
|
||||||
'jsx-a11y/label-has-associated-control': 'off',
|
'jsx-a11y/label-has-associated-control': 'off',
|
||||||
'jsx-a11y/media-has-caption': 'off',
|
'jsx-a11y/media-has-caption': 'off',
|
||||||
|
@ -139,23 +132,6 @@ module.exports = defineConfig({
|
||||||
// ],
|
// ],
|
||||||
'jsx-a11y/no-interactive-element-to-noninteractive-role': 'off',
|
'jsx-a11y/no-interactive-element-to-noninteractive-role': 'off',
|
||||||
// recommended rule is:
|
// recommended rule is:
|
||||||
// 'jsx-a11y/no-noninteractive-element-interactions': [
|
|
||||||
// 'error',
|
|
||||||
// {
|
|
||||||
// body: ['onError', 'onLoad'],
|
|
||||||
// iframe: ['onError', 'onLoad'],
|
|
||||||
// img: ['onError', 'onLoad'],
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
'jsx-a11y/no-noninteractive-element-interactions': [
|
|
||||||
'warn',
|
|
||||||
{
|
|
||||||
handlers: [
|
|
||||||
'onClick',
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
// recommended rule is:
|
|
||||||
// 'jsx-a11y/no-noninteractive-tabindex': [
|
// 'jsx-a11y/no-noninteractive-tabindex': [
|
||||||
// 'error',
|
// 'error',
|
||||||
// {
|
// {
|
||||||
|
@ -165,7 +141,6 @@ module.exports = defineConfig({
|
||||||
// },
|
// },
|
||||||
// ],
|
// ],
|
||||||
'jsx-a11y/no-noninteractive-tabindex': 'off',
|
'jsx-a11y/no-noninteractive-tabindex': 'off',
|
||||||
'jsx-a11y/no-onchange': 'off',
|
|
||||||
// recommended is full 'error'
|
// recommended is full 'error'
|
||||||
'jsx-a11y/no-static-element-interactions': [
|
'jsx-a11y/no-static-element-interactions': [
|
||||||
'warn',
|
'warn',
|
||||||
|
|
3
.github/renovate.json5
vendored
3
.github/renovate.json5
vendored
|
@ -14,6 +14,9 @@
|
||||||
// to `null` after any other rule set it to something.
|
// to `null` after any other rule set it to something.
|
||||||
dependencyDashboardHeader: 'This issue lists Renovate updates and detected dependencies. Read the [Dependency Dashboard](https://docs.renovatebot.com/key-concepts/dashboard/) docs to learn more. Before approving any upgrade: read the description and comments in the [`renovate.json5` file](https://github.com/mastodon/mastodon/blob/main/.github/renovate.json5).',
|
dependencyDashboardHeader: 'This issue lists Renovate updates and detected dependencies. Read the [Dependency Dashboard](https://docs.renovatebot.com/key-concepts/dashboard/) docs to learn more. Before approving any upgrade: read the description and comments in the [`renovate.json5` file](https://github.com/mastodon/mastodon/blob/main/.github/renovate.json5).',
|
||||||
postUpdateOptions: ['yarnDedupeHighest'],
|
postUpdateOptions: ['yarnDedupeHighest'],
|
||||||
|
lockFileMaintenance: {
|
||||||
|
enabled: true,
|
||||||
|
},
|
||||||
packageRules: [
|
packageRules: [
|
||||||
{
|
{
|
||||||
// Require Dependency Dashboard Approval for major version bumps of these node packages
|
// Require Dependency Dashboard Approval for major version bumps of these node packages
|
||||||
|
|
8
.github/workflows/test-ruby.yml
vendored
8
.github/workflows/test-ruby.yml
vendored
|
@ -287,9 +287,13 @@ jobs:
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: './public'
|
path: './'
|
||||||
name: ${{ github.sha }}
|
name: ${{ github.sha }}
|
||||||
|
|
||||||
|
- name: Expand archived asset artifacts
|
||||||
|
run: |
|
||||||
|
tar xvzf artifacts.tar.gz
|
||||||
|
|
||||||
- name: Set up Ruby environment
|
- name: Set up Ruby environment
|
||||||
uses: ./.github/actions/setup-ruby
|
uses: ./.github/actions/setup-ruby
|
||||||
with:
|
with:
|
||||||
|
@ -407,7 +411,7 @@ jobs:
|
||||||
|
|
||||||
- uses: actions/download-artifact@v4
|
- uses: actions/download-artifact@v4
|
||||||
with:
|
with:
|
||||||
path: './public'
|
path: './'
|
||||||
name: ${{ github.sha }}
|
name: ${{ github.sha }}
|
||||||
|
|
||||||
- name: Set up Ruby environment
|
- name: Set up Ruby environment
|
||||||
|
|
2
.nvmrc
2
.nvmrc
|
@ -1 +1 @@
|
||||||
20.14
|
20.15
|
||||||
|
|
|
@ -1,21 +1,14 @@
|
||||||
---
|
---
|
||||||
AllCops:
|
AllCops:
|
||||||
CacheRootDirectory: tmp
|
CacheRootDirectory: tmp
|
||||||
DisplayCopNames: true
|
|
||||||
DisplayStyleGuide: true
|
DisplayStyleGuide: true
|
||||||
Exclude:
|
Exclude:
|
||||||
- db/schema.rb
|
|
||||||
- bin/*
|
|
||||||
- node_modules/**/*
|
|
||||||
- Vagrantfile
|
- Vagrantfile
|
||||||
- vendor/**/*
|
|
||||||
- config/initializers/json_ld*
|
- config/initializers/json_ld*
|
||||||
- lib/mastodon/migration_helpers.rb
|
- lib/mastodon/migration_helpers.rb
|
||||||
- lib/templates/**/*
|
|
||||||
ExtraDetails: true
|
ExtraDetails: true
|
||||||
NewCops: enable
|
NewCops: enable
|
||||||
TargetRubyVersion: 3.1 # Oldest supported ruby version
|
TargetRubyVersion: 3.1 # Oldest supported ruby version
|
||||||
UseCache: true
|
|
||||||
|
|
||||||
inherit_from:
|
inherit_from:
|
||||||
- .rubocop/layout.yml
|
- .rubocop/layout.yml
|
||||||
|
|
|
@ -5,10 +5,6 @@ Rails/FilePath:
|
||||||
Rails/HttpStatus:
|
Rails/HttpStatus:
|
||||||
EnforcedStyle: numeric
|
EnforcedStyle: numeric
|
||||||
|
|
||||||
Rails/LexicallyScopedActionFilter:
|
|
||||||
Exclude:
|
|
||||||
- app/controllers/auth/* # Conflicts with `Lint/UselessMethodDefinition` for inherited controller actions
|
|
||||||
|
|
||||||
Rails/NegateInclude:
|
Rails/NegateInclude:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# This configuration was generated by
|
# This configuration was generated by
|
||||||
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-exclude-limit --no-offense-counts --no-auto-gen-timestamp`
|
# `rubocop --auto-gen-config --auto-gen-only-exclude --no-offense-counts --no-auto-gen-timestamp`
|
||||||
# using RuboCop version 1.63.5.
|
# using RuboCop version 1.64.1.
|
||||||
# The point is for the user to remove these configuration records
|
# The point is for the user to remove these configuration records
|
||||||
# one by one as the offenses are removed from the code base.
|
# one by one as the offenses are removed from the code base.
|
||||||
# Note that changes in the inspected code, or installation of new
|
# Note that changes in the inspected code, or installation of new
|
||||||
|
@ -35,14 +35,6 @@ Rails/OutputSafety:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'config/initializers/simple_form.rb'
|
- 'config/initializers/simple_form.rb'
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
# Configuration parameters: AllowedMethods, AllowedPatterns.
|
|
||||||
# AllowedMethods: ==, equal?, eql?
|
|
||||||
Style/ClassEqualityComparison:
|
|
||||||
Exclude:
|
|
||||||
- 'app/helpers/jsonld_helper.rb'
|
|
||||||
- 'app/serializers/activitypub/outbox_serializer.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
# Configuration parameters: AllowedVars.
|
# Configuration parameters: AllowedVars.
|
||||||
Style/FetchEnvVar:
|
Style/FetchEnvVar:
|
||||||
|
@ -59,7 +51,6 @@ Style/FetchEnvVar:
|
||||||
- 'config/initializers/vapid.rb'
|
- 'config/initializers/vapid.rb'
|
||||||
- 'lib/mastodon/redis_config.rb'
|
- 'lib/mastodon/redis_config.rb'
|
||||||
- 'lib/tasks/repo.rake'
|
- 'lib/tasks/repo.rake'
|
||||||
- 'spec/system/profile_spec.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns.
|
# Configuration parameters: EnforcedStyle, MaxUnannotatedPlaceholdersAllowed, AllowedMethods, AllowedPatterns.
|
||||||
|
@ -70,40 +61,10 @@ Style/FormatStringToken:
|
||||||
- 'config/initializers/devise.rb'
|
- 'config/initializers/devise.rb'
|
||||||
- 'lib/paperclip/color_extractor.rb'
|
- 'lib/paperclip/color_extractor.rb'
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
Style/GlobalStdStream:
|
|
||||||
Exclude:
|
|
||||||
- 'config/environments/development.rb'
|
|
||||||
- 'config/environments/production.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
|
# Configuration parameters: MinBodyLength, AllowConsecutiveConditionals.
|
||||||
Style/GuardClause:
|
Style/GuardClause:
|
||||||
Exclude:
|
Enabled: false
|
||||||
- 'app/lib/activitypub/activity/block.rb'
|
|
||||||
- 'app/lib/request.rb'
|
|
||||||
- 'app/lib/request_pool.rb'
|
|
||||||
- 'app/lib/webfinger.rb'
|
|
||||||
- 'app/lib/webfinger_resource.rb'
|
|
||||||
- 'app/models/concerns/account/counters.rb'
|
|
||||||
- 'app/models/concerns/user/ldap_authenticable.rb'
|
|
||||||
- 'app/models/tag.rb'
|
|
||||||
- 'app/models/user.rb'
|
|
||||||
- 'app/services/fan_out_on_write_service.rb'
|
|
||||||
- 'app/services/post_status_service.rb'
|
|
||||||
- 'app/services/process_hashtags_service.rb'
|
|
||||||
- 'app/workers/move_worker.rb'
|
|
||||||
- 'app/workers/redownload_avatar_worker.rb'
|
|
||||||
- 'app/workers/redownload_header_worker.rb'
|
|
||||||
- 'app/workers/redownload_media_worker.rb'
|
|
||||||
- 'app/workers/remote_account_refresh_worker.rb'
|
|
||||||
- 'config/initializers/devise.rb'
|
|
||||||
- 'lib/devise/strategies/two_factor_ldap_authenticatable.rb'
|
|
||||||
- 'lib/devise/strategies/two_factor_pam_authenticatable.rb'
|
|
||||||
- 'lib/mastodon/cli/accounts.rb'
|
|
||||||
- 'lib/mastodon/cli/maintenance.rb'
|
|
||||||
- 'lib/mastodon/cli/media.rb'
|
|
||||||
- 'lib/tasks/repo.rake'
|
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
# This cop supports unsafe autocorrection (--autocorrect-all).
|
||||||
Style/HashTransformValues:
|
Style/HashTransformValues:
|
||||||
|
@ -125,16 +86,10 @@ Style/MutableConstant:
|
||||||
- 'app/services/delete_account_service.rb'
|
- 'app/services/delete_account_service.rb'
|
||||||
- 'lib/mastodon/migration_warning.rb'
|
- 'lib/mastodon/migration_warning.rb'
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
|
||||||
Style/NilLambda:
|
|
||||||
Exclude:
|
|
||||||
- 'config/initializers/paperclip.rb'
|
|
||||||
|
|
||||||
# Configuration parameters: AllowedMethods.
|
# Configuration parameters: AllowedMethods.
|
||||||
# AllowedMethods: respond_to_missing?
|
# AllowedMethods: respond_to_missing?
|
||||||
Style/OptionalBooleanParameter:
|
Style/OptionalBooleanParameter:
|
||||||
Exclude:
|
Exclude:
|
||||||
- 'app/helpers/admin/account_moderation_notes_helper.rb'
|
|
||||||
- 'app/helpers/jsonld_helper.rb'
|
- 'app/helpers/jsonld_helper.rb'
|
||||||
- 'app/lib/admin/system_check/message.rb'
|
- 'app/lib/admin/system_check/message.rb'
|
||||||
- 'app/lib/request.rb'
|
- 'app/lib/request.rb'
|
||||||
|
@ -158,13 +113,6 @@ Style/RedundantConstantBase:
|
||||||
- 'config/environments/production.rb'
|
- 'config/environments/production.rb'
|
||||||
- 'config/initializers/sidekiq.rb'
|
- 'config/initializers/sidekiq.rb'
|
||||||
|
|
||||||
# This cop supports unsafe autocorrection (--autocorrect-all).
|
|
||||||
# Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods, MaxChainLength.
|
|
||||||
# AllowedMethods: present?, blank?, presence, try, try!
|
|
||||||
Style/SafeNavigation:
|
|
||||||
Exclude:
|
|
||||||
- 'app/models/concerns/account/finder_concern.rb'
|
|
||||||
|
|
||||||
# This cop supports safe autocorrection (--autocorrect).
|
# This cop supports safe autocorrection (--autocorrect).
|
||||||
# Configuration parameters: WordRegex.
|
# Configuration parameters: WordRegex.
|
||||||
# SupportedStyles: percent, brackets
|
# SupportedStyles: percent, brackets
|
||||||
|
|
105
Dockerfile
105
Dockerfile
|
@ -1,4 +1,4 @@
|
||||||
# syntax=docker/dockerfile:1.7
|
# syntax=docker/dockerfile:1.8
|
||||||
|
|
||||||
# This file is designed for production server deployment, not local development work
|
# This file is designed for production server deployment, not local development work
|
||||||
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/README.md#docker
|
# For a containerized local dev environment, see: https://github.com/mastodon/mastodon/blob/main/README.md#docker
|
||||||
|
@ -19,15 +19,15 @@ ARG NODE_MAJOR_VERSION="20"
|
||||||
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
||||||
ARG DEBIAN_VERSION="bookworm"
|
ARG DEBIAN_VERSION="bookworm"
|
||||||
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
|
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
|
||||||
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim as node
|
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim AS node
|
||||||
# Ruby image to use for base image based on combined variables (ex: 3.3.x-slim-bookworm)
|
# Ruby image to use for base image based on combined variables (ex: 3.3.x-slim-bookworm)
|
||||||
FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} as ruby
|
FROM docker.io/ruby:${RUBY_VERSION}-slim-${DEBIAN_VERSION} AS ruby
|
||||||
|
|
||||||
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
|
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
|
||||||
# Example: v4.2.0-nightly.2023.11.09+something
|
# Example: v4.3.0-nightly.2023.11.09+pr-123456
|
||||||
# Overwrite existence of 'alpha.0' in version.rb [--build-arg MASTODON_VERSION_PRERELEASE="nightly.2023.11.09"]
|
# Overwrite existence of 'alpha.X' in version.rb [--build-arg MASTODON_VERSION_PRERELEASE="nightly.2023.11.09"]
|
||||||
ARG MASTODON_VERSION_PRERELEASE=""
|
ARG MASTODON_VERSION_PRERELEASE=""
|
||||||
# Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="pr-12345"]
|
# Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="pr-123456"]
|
||||||
ARG MASTODON_VERSION_METADATA=""
|
ARG MASTODON_VERSION_METADATA=""
|
||||||
|
|
||||||
# Allow Ruby on Rails to serve static files
|
# Allow Ruby on Rails to serve static files
|
||||||
|
@ -100,9 +100,7 @@ RUN \
|
||||||
apt-get dist-upgrade -yq; \
|
apt-get dist-upgrade -yq; \
|
||||||
# Install jemalloc, curl and other necessary components
|
# Install jemalloc, curl and other necessary components
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
ca-certificates \
|
|
||||||
curl \
|
curl \
|
||||||
ffmpeg \
|
|
||||||
file \
|
file \
|
||||||
libjemalloc2 \
|
libjemalloc2 \
|
||||||
patchelf \
|
patchelf \
|
||||||
|
@ -119,7 +117,7 @@ RUN \
|
||||||
;
|
;
|
||||||
|
|
||||||
# Create temporary build layer from base image
|
# Create temporary build layer from base image
|
||||||
FROM ruby as build
|
FROM ruby AS build
|
||||||
|
|
||||||
# Copy Node package configuration files into working directory
|
# Copy Node package configuration files into working directory
|
||||||
COPY package.json yarn.lock .yarnrc.yml /opt/mastodon/
|
COPY package.json yarn.lock .yarnrc.yml /opt/mastodon/
|
||||||
|
@ -137,7 +135,10 @@ RUN \
|
||||||
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
|
--mount=type=cache,id=apt-lib-${TARGETPLATFORM},target=/var/lib/apt,sharing=locked \
|
||||||
# Install build tools and bundler dependencies from APT
|
# Install build tools and bundler dependencies from APT
|
||||||
apt-get install -y --no-install-recommends \
|
apt-get install -y --no-install-recommends \
|
||||||
|
autoconf \
|
||||||
|
automake \
|
||||||
build-essential \
|
build-essential \
|
||||||
|
cmake \
|
||||||
git \
|
git \
|
||||||
libgdbm-dev \
|
libgdbm-dev \
|
||||||
libglib2.0-dev \
|
libglib2.0-dev \
|
||||||
|
@ -146,9 +147,12 @@ RUN \
|
||||||
libidn-dev \
|
libidn-dev \
|
||||||
libpq-dev \
|
libpq-dev \
|
||||||
libssl-dev \
|
libssl-dev \
|
||||||
|
libtool \
|
||||||
meson \
|
meson \
|
||||||
|
nasm \
|
||||||
pkg-config \
|
pkg-config \
|
||||||
shared-mime-info \
|
shared-mime-info \
|
||||||
|
xz-utils \
|
||||||
# libvips components
|
# libvips components
|
||||||
libcgif-dev \
|
libcgif-dev \
|
||||||
libexif-dev \
|
libexif-dev \
|
||||||
|
@ -162,6 +166,16 @@ RUN \
|
||||||
libspng-dev \
|
libspng-dev \
|
||||||
libtiff-dev \
|
libtiff-dev \
|
||||||
libwebp-dev \
|
libwebp-dev \
|
||||||
|
# ffmpeg components
|
||||||
|
libdav1d-dev \
|
||||||
|
liblzma-dev \
|
||||||
|
libmp3lame-dev \
|
||||||
|
libopus-dev \
|
||||||
|
libsnappy-dev \
|
||||||
|
libvorbis-dev \
|
||||||
|
libvpx-dev \
|
||||||
|
libx264-dev \
|
||||||
|
libx265-dev \
|
||||||
;
|
;
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
|
@ -171,7 +185,7 @@ RUN \
|
||||||
corepack prepare --activate;
|
corepack prepare --activate;
|
||||||
|
|
||||||
# Create temporary libvips specific build layer from build layer
|
# Create temporary libvips specific build layer from build layer
|
||||||
FROM build as libvips
|
FROM build AS libvips
|
||||||
|
|
||||||
# libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"]
|
# libvips version to compile, change with [--build-arg VIPS_VERSION="8.15.2"]
|
||||||
# renovate: datasource=github-releases depName=libvips packageName=libvips/libvips
|
# renovate: datasource=github-releases depName=libvips packageName=libvips/libvips
|
||||||
|
@ -190,8 +204,50 @@ RUN \
|
||||||
ninja; \
|
ninja; \
|
||||||
ninja install;
|
ninja install;
|
||||||
|
|
||||||
|
# Create temporary ffmpeg specific build layer from build layer
|
||||||
|
FROM build AS ffmpeg
|
||||||
|
|
||||||
|
# ffmpeg version to compile, change with [--build-arg FFMPEG_VERSION="7.0.x"]
|
||||||
|
# renovate: datasource=repology depName=ffmpeg packageName=openpkg_current/ffmpeg
|
||||||
|
ARG FFMPEG_VERSION=7.0.1
|
||||||
|
# ffmpeg download URL, change with [--build-arg FFMPEG_URL="https://ffmpeg.org/releases"]
|
||||||
|
ARG FFMPEG_URL=https://ffmpeg.org/releases
|
||||||
|
|
||||||
|
WORKDIR /usr/local/ffmpeg/src
|
||||||
|
|
||||||
|
RUN \
|
||||||
|
curl -sSL -o ffmpeg-${FFMPEG_VERSION}.tar.xz ${FFMPEG_URL}/ffmpeg-${FFMPEG_VERSION}.tar.xz; \
|
||||||
|
tar xf ffmpeg-${FFMPEG_VERSION}.tar.xz; \
|
||||||
|
cd ffmpeg-${FFMPEG_VERSION}; \
|
||||||
|
./configure \
|
||||||
|
--prefix=/usr/local/ffmpeg \
|
||||||
|
--toolchain=hardened \
|
||||||
|
--disable-debug \
|
||||||
|
--disable-devices \
|
||||||
|
--disable-doc \
|
||||||
|
--disable-ffplay \
|
||||||
|
--disable-network \
|
||||||
|
--disable-static \
|
||||||
|
--enable-ffmpeg \
|
||||||
|
--enable-ffprobe \
|
||||||
|
--enable-gpl \
|
||||||
|
--enable-libdav1d \
|
||||||
|
--enable-libmp3lame \
|
||||||
|
--enable-libopus \
|
||||||
|
--enable-libsnappy \
|
||||||
|
--enable-libvorbis \
|
||||||
|
--enable-libvpx \
|
||||||
|
--enable-libwebp \
|
||||||
|
--enable-libx264 \
|
||||||
|
--enable-libx265 \
|
||||||
|
--enable-shared \
|
||||||
|
--enable-version3 \
|
||||||
|
; \
|
||||||
|
make -j$(nproc); \
|
||||||
|
make install;
|
||||||
|
|
||||||
# Create temporary bundler specific build layer from build layer
|
# Create temporary bundler specific build layer from build layer
|
||||||
FROM build as bundler
|
FROM build AS bundler
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
|
@ -213,7 +269,7 @@ RUN \
|
||||||
bundle install -j"$(nproc)";
|
bundle install -j"$(nproc)";
|
||||||
|
|
||||||
# Create temporary node specific build layer from build layer
|
# Create temporary node specific build layer from build layer
|
||||||
FROM build as yarn
|
FROM build AS yarn
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
|
@ -230,7 +286,7 @@ RUN \
|
||||||
yarn workspaces focus --production @mastodon/mastodon;
|
yarn workspaces focus --production @mastodon/mastodon;
|
||||||
|
|
||||||
# Create temporary assets build layer from build layer
|
# Create temporary assets build layer from build layer
|
||||||
FROM build as precompiler
|
FROM build AS precompiler
|
||||||
|
|
||||||
# Copy Mastodon sources into precompiler layer
|
# Copy Mastodon sources into precompiler layer
|
||||||
COPY . /opt/mastodon/
|
COPY . /opt/mastodon/
|
||||||
|
@ -254,7 +310,7 @@ RUN \
|
||||||
rm -fr /opt/mastodon/tmp;
|
rm -fr /opt/mastodon/tmp;
|
||||||
|
|
||||||
# Prep final Mastodon Ruby layer
|
# Prep final Mastodon Ruby layer
|
||||||
FROM ruby as mastodon
|
FROM ruby AS mastodon
|
||||||
|
|
||||||
ARG TARGETPLATFORM
|
ARG TARGETPLATFORM
|
||||||
|
|
||||||
|
@ -289,6 +345,20 @@ RUN \
|
||||||
libwebp7 \
|
libwebp7 \
|
||||||
libwebpdemux2 \
|
libwebpdemux2 \
|
||||||
libwebpmux3 \
|
libwebpmux3 \
|
||||||
|
# ffmpeg components
|
||||||
|
libdav1d6 \
|
||||||
|
libmp3lame0 \
|
||||||
|
libopencore-amrnb0 \
|
||||||
|
libopencore-amrwb0 \
|
||||||
|
libopus0 \
|
||||||
|
libsnappy1v5 \
|
||||||
|
libtheora0 \
|
||||||
|
libvorbis0a \
|
||||||
|
libvorbisenc2 \
|
||||||
|
libvorbisfile3 \
|
||||||
|
libvpx7 \
|
||||||
|
libx264-164 \
|
||||||
|
libx265-199 \
|
||||||
;
|
;
|
||||||
|
|
||||||
# Copy Mastodon sources into final layer
|
# Copy Mastodon sources into final layer
|
||||||
|
@ -302,11 +372,16 @@ COPY --from=bundler /usr/local/bundle/ /usr/local/bundle/
|
||||||
# Copy libvips components to layer
|
# Copy libvips components to layer
|
||||||
COPY --from=libvips /usr/local/libvips/bin /usr/local/bin
|
COPY --from=libvips /usr/local/libvips/bin /usr/local/bin
|
||||||
COPY --from=libvips /usr/local/libvips/lib /usr/local/lib
|
COPY --from=libvips /usr/local/libvips/lib /usr/local/lib
|
||||||
|
# Copy ffpmeg components to layer
|
||||||
|
COPY --from=ffmpeg /usr/local/ffmpeg/bin /usr/local/bin
|
||||||
|
COPY --from=ffmpeg /usr/local/ffmpeg/lib /usr/local/lib
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
ldconfig; \
|
ldconfig; \
|
||||||
# Smoketest media processors
|
# Smoketest media processors
|
||||||
vips -v;
|
vips -v; \
|
||||||
|
ffmpeg -version; \
|
||||||
|
ffprobe -version;
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
# Precompile bootsnap code for faster Rails startup
|
# Precompile bootsnap code for faster Rails startup
|
||||||
|
|
8
Gemfile
8
Gemfile
|
@ -9,9 +9,6 @@ gem 'rack', '~> 2.2.7'
|
||||||
gem 'rails', '~> 7.1.1'
|
gem 'rails', '~> 7.1.1'
|
||||||
gem 'thor', '~> 1.2'
|
gem 'thor', '~> 1.2'
|
||||||
|
|
||||||
# For why irb is in the Gemfile, see: https://ruby.social/@st0012/111444685161478182
|
|
||||||
gem 'irb', '~> 1.8'
|
|
||||||
|
|
||||||
gem 'dotenv'
|
gem 'dotenv'
|
||||||
gem 'haml-rails', '~>2.0'
|
gem 'haml-rails', '~>2.0'
|
||||||
gem 'pg', '~> 1.5'
|
gem 'pg', '~> 1.5'
|
||||||
|
@ -61,6 +58,7 @@ gem 'httplog', '~> 1.7.0'
|
||||||
gem 'i18n'
|
gem 'i18n'
|
||||||
gem 'idn-ruby', require: 'idn'
|
gem 'idn-ruby', require: 'idn'
|
||||||
gem 'inline_svg'
|
gem 'inline_svg'
|
||||||
|
gem 'irb', '~> 1.8'
|
||||||
gem 'kaminari', '~> 1.2'
|
gem 'kaminari', '~> 1.2'
|
||||||
gem 'link_header', '~> 0.0'
|
gem 'link_header', '~> 0.0'
|
||||||
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
||||||
|
@ -71,7 +69,7 @@ gem 'oj', '~> 3.14'
|
||||||
gem 'ox', '~> 2.14'
|
gem 'ox', '~> 2.14'
|
||||||
gem 'parslet'
|
gem 'parslet'
|
||||||
gem 'premailer-rails'
|
gem 'premailer-rails'
|
||||||
gem 'public_suffix', '~> 5.0'
|
gem 'public_suffix', '~> 6.0'
|
||||||
gem 'pundit', '~> 2.3'
|
gem 'pundit', '~> 2.3'
|
||||||
gem 'rack-attack', '~> 6.6'
|
gem 'rack-attack', '~> 6.6'
|
||||||
gem 'rack-cors', '~> 2.0', require: 'rack/cors'
|
gem 'rack-cors', '~> 2.0', require: 'rack/cors'
|
||||||
|
@ -107,7 +105,7 @@ gem 'private_address_check', '~> 0.5'
|
||||||
gem 'opentelemetry-api', '~> 1.2.5'
|
gem 'opentelemetry-api', '~> 1.2.5'
|
||||||
|
|
||||||
group :opentelemetry do
|
group :opentelemetry do
|
||||||
gem 'opentelemetry-exporter-otlp', '~> 0.27.0', require: false
|
gem 'opentelemetry-exporter-otlp', '~> 0.28.0', require: false
|
||||||
gem 'opentelemetry-instrumentation-active_job', '~> 0.7.1', require: false
|
gem 'opentelemetry-instrumentation-active_job', '~> 0.7.1', require: false
|
||||||
gem 'opentelemetry-instrumentation-active_model_serializers', '~> 0.20.1', require: false
|
gem 'opentelemetry-instrumentation-active_model_serializers', '~> 0.20.1', require: false
|
||||||
gem 'opentelemetry-instrumentation-concurrent_ruby', '~> 0.21.2', require: false
|
gem 'opentelemetry-instrumentation-concurrent_ruby', '~> 0.21.2', require: false
|
||||||
|
|
53
Gemfile.lock
53
Gemfile.lock
|
@ -89,8 +89,8 @@ GEM
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
mutex_m
|
mutex_m
|
||||||
tzinfo (~> 2.0)
|
tzinfo (~> 2.0)
|
||||||
addressable (2.8.6)
|
addressable (2.8.7)
|
||||||
public_suffix (>= 2.0.2, < 6.0)
|
public_suffix (>= 2.0.2, < 7.0)
|
||||||
aes_key_wrap (1.1.0)
|
aes_key_wrap (1.1.0)
|
||||||
android_key_attestation (0.3.0)
|
android_key_attestation (0.3.0)
|
||||||
annotate (3.2.0)
|
annotate (3.2.0)
|
||||||
|
@ -143,7 +143,7 @@ GEM
|
||||||
brpoplpush-redis_script (0.1.3)
|
brpoplpush-redis_script (0.1.3)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.5)
|
concurrent-ruby (~> 1.0, >= 1.0.5)
|
||||||
redis (>= 1.0, < 6)
|
redis (>= 1.0, < 6)
|
||||||
builder (3.2.4)
|
builder (3.3.0)
|
||||||
bundler-audit (0.9.1)
|
bundler-audit (0.9.1)
|
||||||
bundler (>= 1.2.0, < 3)
|
bundler (>= 1.2.0, < 3)
|
||||||
thor (~> 1.0)
|
thor (~> 1.0)
|
||||||
|
@ -195,7 +195,7 @@ GEM
|
||||||
railties (>= 4.1.0)
|
railties (>= 4.1.0)
|
||||||
responders
|
responders
|
||||||
warden (~> 1.2.3)
|
warden (~> 1.2.3)
|
||||||
devise-two-factor (5.0.0)
|
devise-two-factor (5.1.0)
|
||||||
activesupport (~> 7.0)
|
activesupport (~> 7.0)
|
||||||
devise (~> 4.0)
|
devise (~> 4.0)
|
||||||
railties (~> 7.0)
|
railties (~> 7.0)
|
||||||
|
@ -226,7 +226,7 @@ GEM
|
||||||
htmlentities (~> 4.3.3)
|
htmlentities (~> 4.3.3)
|
||||||
launchy (~> 2.1)
|
launchy (~> 2.1)
|
||||||
mail (~> 2.7)
|
mail (~> 2.7)
|
||||||
erubi (1.12.0)
|
erubi (1.13.0)
|
||||||
et-orbi (1.2.11)
|
et-orbi (1.2.11)
|
||||||
tzinfo
|
tzinfo
|
||||||
excon (0.110.0)
|
excon (0.110.0)
|
||||||
|
@ -398,6 +398,7 @@ GEM
|
||||||
llhttp-ffi (0.5.0)
|
llhttp-ffi (0.5.0)
|
||||||
ffi-compiler (~> 1.0)
|
ffi-compiler (~> 1.0)
|
||||||
rake (~> 13.0)
|
rake (~> 13.0)
|
||||||
|
logger (1.6.0)
|
||||||
lograge (0.14.0)
|
lograge (0.14.0)
|
||||||
actionpack (>= 4)
|
actionpack (>= 4)
|
||||||
activesupport (>= 4)
|
activesupport (>= 4)
|
||||||
|
@ -489,8 +490,8 @@ GEM
|
||||||
opentelemetry-api (1.2.5)
|
opentelemetry-api (1.2.5)
|
||||||
opentelemetry-common (0.20.1)
|
opentelemetry-common (0.20.1)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
opentelemetry-exporter-otlp (0.27.0)
|
opentelemetry-exporter-otlp (0.28.0)
|
||||||
google-protobuf (~> 3.14)
|
google-protobuf (>= 3.18)
|
||||||
googleapis-common-protos-types (~> 1.3)
|
googleapis-common-protos-types (~> 1.3)
|
||||||
opentelemetry-api (~> 1.1)
|
opentelemetry-api (~> 1.1)
|
||||||
opentelemetry-common (~> 0.20)
|
opentelemetry-common (~> 0.20)
|
||||||
|
@ -528,32 +529,27 @@ GEM
|
||||||
opentelemetry-instrumentation-concurrent_ruby (0.21.3)
|
opentelemetry-instrumentation-concurrent_ruby (0.21.3)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
opentelemetry-instrumentation-base (~> 0.22.1)
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
||||||
opentelemetry-instrumentation-excon (0.22.1)
|
opentelemetry-instrumentation-excon (0.22.3)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
opentelemetry-common (~> 0.20.0)
|
|
||||||
opentelemetry-instrumentation-base (~> 0.22.1)
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
||||||
opentelemetry-instrumentation-faraday (0.24.2)
|
opentelemetry-instrumentation-faraday (0.24.4)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
opentelemetry-common (~> 0.20.0)
|
|
||||||
opentelemetry-instrumentation-base (~> 0.22.1)
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
||||||
opentelemetry-instrumentation-http (0.23.3)
|
opentelemetry-instrumentation-http (0.23.3)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
opentelemetry-instrumentation-base (~> 0.22.1)
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
||||||
opentelemetry-instrumentation-http_client (0.22.4)
|
opentelemetry-instrumentation-http_client (0.22.6)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
opentelemetry-common (~> 0.20.0)
|
|
||||||
opentelemetry-instrumentation-base (~> 0.22.1)
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
||||||
opentelemetry-instrumentation-net_http (0.22.4)
|
opentelemetry-instrumentation-net_http (0.22.6)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
opentelemetry-common (~> 0.20.0)
|
|
||||||
opentelemetry-instrumentation-base (~> 0.22.1)
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
||||||
opentelemetry-instrumentation-pg (0.27.3)
|
opentelemetry-instrumentation-pg (0.27.3)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
opentelemetry-helpers-sql-obfuscation
|
opentelemetry-helpers-sql-obfuscation
|
||||||
opentelemetry-instrumentation-base (~> 0.22.1)
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
||||||
opentelemetry-instrumentation-rack (0.24.3)
|
opentelemetry-instrumentation-rack (0.24.5)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
opentelemetry-common (~> 0.20.0)
|
|
||||||
opentelemetry-instrumentation-base (~> 0.22.1)
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
||||||
opentelemetry-instrumentation-rails (0.30.2)
|
opentelemetry-instrumentation-rails (0.30.2)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
|
@ -564,13 +560,11 @@ GEM
|
||||||
opentelemetry-instrumentation-active_record (~> 0.7.0)
|
opentelemetry-instrumentation-active_record (~> 0.7.0)
|
||||||
opentelemetry-instrumentation-active_support (~> 0.5.0)
|
opentelemetry-instrumentation-active_support (~> 0.5.0)
|
||||||
opentelemetry-instrumentation-base (~> 0.22.1)
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
||||||
opentelemetry-instrumentation-redis (0.25.4)
|
opentelemetry-instrumentation-redis (0.25.6)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
opentelemetry-common (~> 0.20.0)
|
|
||||||
opentelemetry-instrumentation-base (~> 0.22.1)
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
||||||
opentelemetry-instrumentation-sidekiq (0.25.3)
|
opentelemetry-instrumentation-sidekiq (0.25.5)
|
||||||
opentelemetry-api (~> 1.0)
|
opentelemetry-api (~> 1.0)
|
||||||
opentelemetry-common (~> 0.20.0)
|
|
||||||
opentelemetry-instrumentation-base (~> 0.22.1)
|
opentelemetry-instrumentation-base (~> 0.22.1)
|
||||||
opentelemetry-registry (0.3.1)
|
opentelemetry-registry (0.3.1)
|
||||||
opentelemetry-api (~> 1.1)
|
opentelemetry-api (~> 1.1)
|
||||||
|
@ -609,7 +603,7 @@ GEM
|
||||||
railties (>= 7.0.0)
|
railties (>= 7.0.0)
|
||||||
psych (5.1.2)
|
psych (5.1.2)
|
||||||
stringio
|
stringio
|
||||||
public_suffix (5.1.1)
|
public_suffix (6.0.0)
|
||||||
puma (6.4.2)
|
puma (6.4.2)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
pundit (2.3.2)
|
pundit (2.3.2)
|
||||||
|
@ -682,7 +676,7 @@ GEM
|
||||||
link_header (~> 0.0, >= 0.0.8)
|
link_header (~> 0.0, >= 0.0.8)
|
||||||
rdf-normalize (0.7.0)
|
rdf-normalize (0.7.0)
|
||||||
rdf (~> 3.3)
|
rdf (~> 3.3)
|
||||||
rdoc (6.6.3.1)
|
rdoc (6.7.0)
|
||||||
psych (>= 4.0.0)
|
psych (>= 4.0.0)
|
||||||
redcarpet (3.6.0)
|
redcarpet (3.6.0)
|
||||||
redis (4.8.1)
|
redis (4.8.1)
|
||||||
|
@ -709,7 +703,7 @@ GEM
|
||||||
rqrcode_core (1.2.0)
|
rqrcode_core (1.2.0)
|
||||||
rspec-core (3.13.0)
|
rspec-core (3.13.0)
|
||||||
rspec-support (~> 3.13.0)
|
rspec-support (~> 3.13.0)
|
||||||
rspec-expectations (3.13.0)
|
rspec-expectations (3.13.1)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.13.0)
|
rspec-support (~> 3.13.0)
|
||||||
rspec-github (2.4.0)
|
rspec-github (2.4.0)
|
||||||
|
@ -717,7 +711,7 @@ GEM
|
||||||
rspec-mocks (3.13.1)
|
rspec-mocks (3.13.1)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.13.0)
|
rspec-support (~> 3.13.0)
|
||||||
rspec-rails (6.1.2)
|
rspec-rails (6.1.3)
|
||||||
actionpack (>= 6.1)
|
actionpack (>= 6.1)
|
||||||
activesupport (>= 6.1)
|
activesupport (>= 6.1)
|
||||||
railties (>= 6.1)
|
railties (>= 6.1)
|
||||||
|
@ -778,8 +772,9 @@ GEM
|
||||||
scenic (1.8.0)
|
scenic (1.8.0)
|
||||||
activerecord (>= 4.0.0)
|
activerecord (>= 4.0.0)
|
||||||
railties (>= 4.0.0)
|
railties (>= 4.0.0)
|
||||||
selenium-webdriver (4.21.1)
|
selenium-webdriver (4.22.0)
|
||||||
base64 (~> 0.2)
|
base64 (~> 0.2)
|
||||||
|
logger (~> 1.4)
|
||||||
rexml (~> 3.2, >= 3.2.5)
|
rexml (~> 3.2, >= 3.2.5)
|
||||||
rubyzip (>= 1.2.2, < 3.0)
|
rubyzip (>= 1.2.2, < 3.0)
|
||||||
websocket (~> 1.0)
|
websocket (~> 1.0)
|
||||||
|
@ -898,7 +893,7 @@ GEM
|
||||||
xorcist (1.1.3)
|
xorcist (1.1.3)
|
||||||
xpath (3.2.0)
|
xpath (3.2.0)
|
||||||
nokogiri (~> 1.8)
|
nokogiri (~> 1.8)
|
||||||
zeitwerk (2.6.15)
|
zeitwerk (2.6.16)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
ruby
|
||||||
|
@ -979,7 +974,7 @@ DEPENDENCIES
|
||||||
omniauth-saml (~> 2.0)
|
omniauth-saml (~> 2.0)
|
||||||
omniauth_openid_connect (~> 0.6.1)
|
omniauth_openid_connect (~> 0.6.1)
|
||||||
opentelemetry-api (~> 1.2.5)
|
opentelemetry-api (~> 1.2.5)
|
||||||
opentelemetry-exporter-otlp (~> 0.27.0)
|
opentelemetry-exporter-otlp (~> 0.28.0)
|
||||||
opentelemetry-instrumentation-active_job (~> 0.7.1)
|
opentelemetry-instrumentation-active_job (~> 0.7.1)
|
||||||
opentelemetry-instrumentation-active_model_serializers (~> 0.20.1)
|
opentelemetry-instrumentation-active_model_serializers (~> 0.20.1)
|
||||||
opentelemetry-instrumentation-concurrent_ruby (~> 0.21.2)
|
opentelemetry-instrumentation-concurrent_ruby (~> 0.21.2)
|
||||||
|
@ -1001,7 +996,7 @@ DEPENDENCIES
|
||||||
premailer-rails
|
premailer-rails
|
||||||
private_address_check (~> 0.5)
|
private_address_check (~> 0.5)
|
||||||
propshaft
|
propshaft
|
||||||
public_suffix (~> 5.0)
|
public_suffix (~> 6.0)
|
||||||
puma (~> 6.3)
|
puma (~> 6.3)
|
||||||
pundit (~> 2.3)
|
pundit (~> 2.3)
|
||||||
rack (~> 2.2.7)
|
rack (~> 2.2.7)
|
||||||
|
|
|
@ -15,7 +15,7 @@ class Api::V2Alpha::NotificationsController < Api::BaseController
|
||||||
@relationships = StatusRelationshipsPresenter.new(target_statuses_from_notifications, current_user&.account_id)
|
@relationships = StatusRelationshipsPresenter.new(target_statuses_from_notifications, current_user&.account_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
render json: @notifications.map { |notification| NotificationGroup.from_notification(notification) }, each_serializer: REST::NotificationGroupSerializer, relationships: @relationships, group_metadata: @group_metadata
|
render json: @notifications.map { |notification| NotificationGroup.from_notification(notification, max_id: @group_metadata.dig(notification.group_key, :max_id)) }, each_serializer: REST::NotificationGroupSerializer, relationships: @relationships, group_metadata: @group_metadata
|
||||||
end
|
end
|
||||||
|
|
||||||
def show
|
def show
|
||||||
|
|
|
@ -25,6 +25,14 @@ class Auth::RegistrationsController < Devise::RegistrationsController
|
||||||
super(&:build_invite_request)
|
super(&:build_invite_request)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def edit # rubocop:disable Lint/UselessMethodDefinition
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def create # rubocop:disable Lint/UselessMethodDefinition
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
super do |resource|
|
super do |resource|
|
||||||
resource.clear_other_sessions(current_session.session_id) if resource.saved_change_to_encrypted_password?
|
resource.clear_other_sessions(current_session.session_id) if resource.saved_change_to_encrypted_password?
|
||||||
|
|
|
@ -149,7 +149,7 @@ module JsonLdHelper
|
||||||
def safe_for_forwarding?(original, compacted)
|
def safe_for_forwarding?(original, compacted)
|
||||||
original.without('@context', 'signature').all? do |key, value|
|
original.without('@context', 'signature').all? do |key, value|
|
||||||
compacted_value = compacted[key]
|
compacted_value = compacted[key]
|
||||||
return false unless value.class == compacted_value.class
|
return false unless value.instance_of?(compacted_value.class)
|
||||||
|
|
||||||
if value.is_a?(Hash)
|
if value.is_a?(Hash)
|
||||||
safe_for_forwarding?(value, compacted_value)
|
safe_for_forwarding?(value, compacted_value)
|
||||||
|
|
16
app/javascript/mastodon/actions/notification_policies.ts
Normal file
16
app/javascript/mastodon/actions/notification_policies.ts
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import {
|
||||||
|
apiGetNotificationPolicy,
|
||||||
|
apiUpdateNotificationsPolicy,
|
||||||
|
} from 'mastodon/api/notification_policies';
|
||||||
|
import type { NotificationPolicy } from 'mastodon/models/notification_policy';
|
||||||
|
import { createDataLoadingThunk } from 'mastodon/store/typed_functions';
|
||||||
|
|
||||||
|
export const fetchNotificationPolicy = createDataLoadingThunk(
|
||||||
|
'notificationPolicy/fetch',
|
||||||
|
() => apiGetNotificationPolicy(),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const updateNotificationsPolicy = createDataLoadingThunk(
|
||||||
|
'notificationPolicy/update',
|
||||||
|
(policy: Partial<NotificationPolicy>) => apiUpdateNotificationsPolicy(policy),
|
||||||
|
);
|
|
@ -45,10 +45,6 @@ export const NOTIFICATIONS_MARK_AS_READ = 'NOTIFICATIONS_MARK_AS_READ';
|
||||||
export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT';
|
export const NOTIFICATIONS_SET_BROWSER_SUPPORT = 'NOTIFICATIONS_SET_BROWSER_SUPPORT';
|
||||||
export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION';
|
export const NOTIFICATIONS_SET_BROWSER_PERMISSION = 'NOTIFICATIONS_SET_BROWSER_PERMISSION';
|
||||||
|
|
||||||
export const NOTIFICATION_POLICY_FETCH_REQUEST = 'NOTIFICATION_POLICY_FETCH_REQUEST';
|
|
||||||
export const NOTIFICATION_POLICY_FETCH_SUCCESS = 'NOTIFICATION_POLICY_FETCH_SUCCESS';
|
|
||||||
export const NOTIFICATION_POLICY_FETCH_FAIL = 'NOTIFICATION_POLICY_FETCH_FAIL';
|
|
||||||
|
|
||||||
export const NOTIFICATION_REQUESTS_FETCH_REQUEST = 'NOTIFICATION_REQUESTS_FETCH_REQUEST';
|
export const NOTIFICATION_REQUESTS_FETCH_REQUEST = 'NOTIFICATION_REQUESTS_FETCH_REQUEST';
|
||||||
export const NOTIFICATION_REQUESTS_FETCH_SUCCESS = 'NOTIFICATION_REQUESTS_FETCH_SUCCESS';
|
export const NOTIFICATION_REQUESTS_FETCH_SUCCESS = 'NOTIFICATION_REQUESTS_FETCH_SUCCESS';
|
||||||
export const NOTIFICATION_REQUESTS_FETCH_FAIL = 'NOTIFICATION_REQUESTS_FETCH_FAIL';
|
export const NOTIFICATION_REQUESTS_FETCH_FAIL = 'NOTIFICATION_REQUESTS_FETCH_FAIL';
|
||||||
|
@ -363,40 +359,6 @@ export function setBrowserPermission (value) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fetchNotificationPolicy = () => (dispatch) => {
|
|
||||||
dispatch(fetchNotificationPolicyRequest());
|
|
||||||
|
|
||||||
api().get('/api/v1/notifications/policy').then(({ data }) => {
|
|
||||||
dispatch(fetchNotificationPolicySuccess(data));
|
|
||||||
}).catch(err => {
|
|
||||||
dispatch(fetchNotificationPolicyFail(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const fetchNotificationPolicyRequest = () => ({
|
|
||||||
type: NOTIFICATION_POLICY_FETCH_REQUEST,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const fetchNotificationPolicySuccess = policy => ({
|
|
||||||
type: NOTIFICATION_POLICY_FETCH_SUCCESS,
|
|
||||||
policy,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const fetchNotificationPolicyFail = error => ({
|
|
||||||
type: NOTIFICATION_POLICY_FETCH_FAIL,
|
|
||||||
error,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const updateNotificationsPolicy = params => (dispatch) => {
|
|
||||||
dispatch(fetchNotificationPolicyRequest());
|
|
||||||
|
|
||||||
api().put('/api/v1/notifications/policy', params).then(({ data }) => {
|
|
||||||
dispatch(fetchNotificationPolicySuccess(data));
|
|
||||||
}).catch(err => {
|
|
||||||
dispatch(fetchNotificationPolicyFail(err));
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const fetchNotificationRequests = () => (dispatch, getState) => {
|
export const fetchNotificationRequests = () => (dispatch, getState) => {
|
||||||
const params = {};
|
const params = {};
|
||||||
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
|
||||||
},
|
},
|
||||||
|
|
||||||
onDisconnect() {
|
onDisconnect() {
|
||||||
dispatch(disconnectTimeline(timelineId));
|
dispatch(disconnectTimeline({ timeline: timelineId }));
|
||||||
|
|
||||||
if (options.fallback) {
|
if (options.fallback) {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
|
|
|
@ -6,9 +6,11 @@ import { usePendingItems as preferPendingItems } from 'mastodon/initial_state';
|
||||||
|
|
||||||
import { importFetchedStatus, importFetchedStatuses } from './importer';
|
import { importFetchedStatus, importFetchedStatuses } from './importer';
|
||||||
import { submitMarkers } from './markers';
|
import { submitMarkers } from './markers';
|
||||||
|
import {timelineDelete} from './timelines_typed';
|
||||||
|
|
||||||
|
export { disconnectTimeline } from './timelines_typed';
|
||||||
|
|
||||||
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
|
export const TIMELINE_UPDATE = 'TIMELINE_UPDATE';
|
||||||
export const TIMELINE_DELETE = 'TIMELINE_DELETE';
|
|
||||||
export const TIMELINE_CLEAR = 'TIMELINE_CLEAR';
|
export const TIMELINE_CLEAR = 'TIMELINE_CLEAR';
|
||||||
|
|
||||||
export const TIMELINE_EXPAND_REQUEST = 'TIMELINE_EXPAND_REQUEST';
|
export const TIMELINE_EXPAND_REQUEST = 'TIMELINE_EXPAND_REQUEST';
|
||||||
|
@ -17,7 +19,6 @@ export const TIMELINE_EXPAND_FAIL = 'TIMELINE_EXPAND_FAIL';
|
||||||
|
|
||||||
export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP';
|
export const TIMELINE_SCROLL_TOP = 'TIMELINE_SCROLL_TOP';
|
||||||
export const TIMELINE_LOAD_PENDING = 'TIMELINE_LOAD_PENDING';
|
export const TIMELINE_LOAD_PENDING = 'TIMELINE_LOAD_PENDING';
|
||||||
export const TIMELINE_DISCONNECT = 'TIMELINE_DISCONNECT';
|
|
||||||
export const TIMELINE_CONNECT = 'TIMELINE_CONNECT';
|
export const TIMELINE_CONNECT = 'TIMELINE_CONNECT';
|
||||||
|
|
||||||
export const TIMELINE_MARK_AS_PARTIAL = 'TIMELINE_MARK_AS_PARTIAL';
|
export const TIMELINE_MARK_AS_PARTIAL = 'TIMELINE_MARK_AS_PARTIAL';
|
||||||
|
@ -62,16 +63,10 @@ export function updateTimeline(timeline, status, accept) {
|
||||||
export function deleteFromTimelines(id) {
|
export function deleteFromTimelines(id) {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
const accountId = getState().getIn(['statuses', id, 'account']);
|
const accountId = getState().getIn(['statuses', id, 'account']);
|
||||||
const references = getState().get('statuses').filter(status => status.get('reblog') === id).map(status => status.get('id'));
|
const references = getState().get('statuses').filter(status => status.get('reblog') === id).map(status => status.get('id')).valueSeq().toJSON();
|
||||||
const reblogOf = getState().getIn(['statuses', id, 'reblog'], null);
|
const reblogOf = getState().getIn(['statuses', id, 'reblog'], null);
|
||||||
|
|
||||||
dispatch({
|
dispatch(timelineDelete({ statusId: id, accountId, references, reblogOf }));
|
||||||
type: TIMELINE_DELETE,
|
|
||||||
id,
|
|
||||||
accountId,
|
|
||||||
references,
|
|
||||||
reblogOf,
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,12 +222,6 @@ export function connectTimeline(timeline) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export const disconnectTimeline = timeline => ({
|
|
||||||
type: TIMELINE_DISCONNECT,
|
|
||||||
timeline,
|
|
||||||
usePendingItems: preferPendingItems,
|
|
||||||
});
|
|
||||||
|
|
||||||
export const markAsPartial = timeline => ({
|
export const markAsPartial = timeline => ({
|
||||||
type: TIMELINE_MARK_AS_PARTIAL,
|
type: TIMELINE_MARK_AS_PARTIAL,
|
||||||
timeline,
|
timeline,
|
||||||
|
|
20
app/javascript/mastodon/actions/timelines_typed.ts
Normal file
20
app/javascript/mastodon/actions/timelines_typed.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
import { usePendingItems as preferPendingItems } from 'mastodon/initial_state';
|
||||||
|
|
||||||
|
export const disconnectTimeline = createAction(
|
||||||
|
'timeline/disconnect',
|
||||||
|
({ timeline }: { timeline: string }) => ({
|
||||||
|
payload: {
|
||||||
|
timeline,
|
||||||
|
usePendingItems: preferPendingItems,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
export const timelineDelete = createAction<{
|
||||||
|
statusId: string;
|
||||||
|
accountId: string;
|
||||||
|
references: string[];
|
||||||
|
reblogOf: string | null;
|
||||||
|
}>('timelines/delete');
|
10
app/javascript/mastodon/api/notification_policies.ts
Normal file
10
app/javascript/mastodon/api/notification_policies.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { apiRequest } from 'mastodon/api';
|
||||||
|
import type { NotificationPolicyJSON } from 'mastodon/api_types/notification_policies';
|
||||||
|
|
||||||
|
export const apiGetNotificationPolicy = () =>
|
||||||
|
apiRequest<NotificationPolicyJSON>('GET', '/v1/notifications/policy');
|
||||||
|
|
||||||
|
export const apiUpdateNotificationsPolicy = (
|
||||||
|
policy: Partial<NotificationPolicyJSON>,
|
||||||
|
) =>
|
||||||
|
apiRequest<NotificationPolicyJSON>('PUT', '/v1/notifications/policy', policy);
|
12
app/javascript/mastodon/api_types/notification_policies.ts
Normal file
12
app/javascript/mastodon/api_types/notification_policies.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
// See app/serializers/rest/notification_policy_serializer.rb
|
||||||
|
|
||||||
|
export interface NotificationPolicyJSON {
|
||||||
|
filter_not_following: boolean;
|
||||||
|
filter_not_followers: boolean;
|
||||||
|
filter_new_accounts: boolean;
|
||||||
|
filter_private_mentions: boolean;
|
||||||
|
summary: {
|
||||||
|
pending_requests_count: number;
|
||||||
|
pending_notifications_count: number;
|
||||||
|
};
|
||||||
|
}
|
|
@ -133,7 +133,7 @@ class AccountTimeline extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prevProps.accountId === me && accountId !== me) {
|
if (prevProps.accountId === me && accountId !== me) {
|
||||||
dispatch(disconnectTimeline(`account:${me}`));
|
dispatch(disconnectTimeline({ timeline: `account:${me}` }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +141,7 @@ class AccountTimeline extends ImmutablePureComponent {
|
||||||
const { dispatch, accountId } = this.props;
|
const { dispatch, accountId } = this.props;
|
||||||
|
|
||||||
if (accountId === me) {
|
if (accountId === me) {
|
||||||
dispatch(disconnectTimeline(`account:${me}`));
|
dispatch(disconnectTimeline({ timeline: `account:${me}` }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ class ColumnSettings extends PureComponent {
|
||||||
alertsEnabled: PropTypes.bool,
|
alertsEnabled: PropTypes.bool,
|
||||||
browserSupport: PropTypes.bool,
|
browserSupport: PropTypes.bool,
|
||||||
browserPermission: PropTypes.string,
|
browserPermission: PropTypes.string,
|
||||||
notificationPolicy: ImmutablePropTypes.map,
|
notificationPolicy: PropTypes.object.isRequired,
|
||||||
onChangePolicy: PropTypes.func.isRequired,
|
onChangePolicy: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,22 +88,22 @@ class ColumnSettings extends PureComponent {
|
||||||
<h3><FormattedMessage id='notifications.policy.title' defaultMessage='Filter out notifications from…' /></h3>
|
<h3><FormattedMessage id='notifications.policy.title' defaultMessage='Filter out notifications from…' /></h3>
|
||||||
|
|
||||||
<div className='column-settings__row'>
|
<div className='column-settings__row'>
|
||||||
<CheckboxWithLabel checked={notificationPolicy.get('filter_not_following')} onChange={this.handleFilterNotFollowing}>
|
<CheckboxWithLabel checked={notificationPolicy.filter_not_following} onChange={this.handleFilterNotFollowing}>
|
||||||
<strong><FormattedMessage id='notifications.policy.filter_not_following_title' defaultMessage="People you don't follow" /></strong>
|
<strong><FormattedMessage id='notifications.policy.filter_not_following_title' defaultMessage="People you don't follow" /></strong>
|
||||||
<span className='hint'><FormattedMessage id='notifications.policy.filter_not_following_hint' defaultMessage='Until you manually approve them' /></span>
|
<span className='hint'><FormattedMessage id='notifications.policy.filter_not_following_hint' defaultMessage='Until you manually approve them' /></span>
|
||||||
</CheckboxWithLabel>
|
</CheckboxWithLabel>
|
||||||
|
|
||||||
<CheckboxWithLabel checked={notificationPolicy.get('filter_not_followers')} onChange={this.handleFilterNotFollowers}>
|
<CheckboxWithLabel checked={notificationPolicy.filter_not_followers} onChange={this.handleFilterNotFollowers}>
|
||||||
<strong><FormattedMessage id='notifications.policy.filter_not_followers_title' defaultMessage='People not following you' /></strong>
|
<strong><FormattedMessage id='notifications.policy.filter_not_followers_title' defaultMessage='People not following you' /></strong>
|
||||||
<span className='hint'><FormattedMessage id='notifications.policy.filter_not_followers_hint' defaultMessage='Including people who have been following you fewer than {days, plural, one {one day} other {# days}}' values={{ days: 3 }} /></span>
|
<span className='hint'><FormattedMessage id='notifications.policy.filter_not_followers_hint' defaultMessage='Including people who have been following you fewer than {days, plural, one {one day} other {# days}}' values={{ days: 3 }} /></span>
|
||||||
</CheckboxWithLabel>
|
</CheckboxWithLabel>
|
||||||
|
|
||||||
<CheckboxWithLabel checked={notificationPolicy.get('filter_new_accounts')} onChange={this.handleFilterNewAccounts}>
|
<CheckboxWithLabel checked={notificationPolicy.filter_new_accounts} onChange={this.handleFilterNewAccounts}>
|
||||||
<strong><FormattedMessage id='notifications.policy.filter_new_accounts_title' defaultMessage='New accounts' /></strong>
|
<strong><FormattedMessage id='notifications.policy.filter_new_accounts_title' defaultMessage='New accounts' /></strong>
|
||||||
<span className='hint'><FormattedMessage id='notifications.policy.filter_new_accounts.hint' defaultMessage='Created within the past {days, plural, one {one day} other {# days}}' values={{ days: 30 }} /></span>
|
<span className='hint'><FormattedMessage id='notifications.policy.filter_new_accounts.hint' defaultMessage='Created within the past {days, plural, one {one day} other {# days}}' values={{ days: 30 }} /></span>
|
||||||
</CheckboxWithLabel>
|
</CheckboxWithLabel>
|
||||||
|
|
||||||
<CheckboxWithLabel checked={notificationPolicy.get('filter_private_mentions')} onChange={this.handleFilterPrivateMentions}>
|
<CheckboxWithLabel checked={notificationPolicy.filter_private_mentions} onChange={this.handleFilterPrivateMentions}>
|
||||||
<strong><FormattedMessage id='notifications.policy.filter_private_mentions_title' defaultMessage='Unsolicited private mentions' /></strong>
|
<strong><FormattedMessage id='notifications.policy.filter_private_mentions_title' defaultMessage='Unsolicited private mentions' /></strong>
|
||||||
<span className='hint'><FormattedMessage id='notifications.policy.filter_private_mentions_hint' defaultMessage="Filtered unless it's in reply to your own mention or if you follow the sender" /></span>
|
<span className='hint'><FormattedMessage id='notifications.policy.filter_private_mentions_hint' defaultMessage="Filtered unless it's in reply to your own mention or if you follow the sender" /></span>
|
||||||
</CheckboxWithLabel>
|
</CheckboxWithLabel>
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
|
||||||
|
|
||||||
import { Link } from 'react-router-dom';
|
|
||||||
|
|
||||||
import { useDispatch, useSelector } from 'react-redux';
|
|
||||||
|
|
||||||
import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react';
|
|
||||||
import { fetchNotificationPolicy } from 'mastodon/actions/notifications';
|
|
||||||
import { Icon } from 'mastodon/components/icon';
|
|
||||||
import { toCappedNumber } from 'mastodon/utils/numbers';
|
|
||||||
|
|
||||||
export const FilteredNotificationsBanner = () => {
|
|
||||||
const dispatch = useDispatch();
|
|
||||||
const policy = useSelector(state => state.get('notificationPolicy'));
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
dispatch(fetchNotificationPolicy());
|
|
||||||
|
|
||||||
const interval = setInterval(() => {
|
|
||||||
dispatch(fetchNotificationPolicy());
|
|
||||||
}, 120000);
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
clearInterval(interval);
|
|
||||||
};
|
|
||||||
}, [dispatch]);
|
|
||||||
|
|
||||||
if (policy === null || policy.getIn(['summary', 'pending_notifications_count']) === 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Link className='filtered-notifications-banner' to='/notifications/requests'>
|
|
||||||
<Icon icon={InventoryIcon} />
|
|
||||||
|
|
||||||
<div className='filtered-notifications-banner__text'>
|
|
||||||
<strong><FormattedMessage id='filtered_notifications_banner.title' defaultMessage='Filtered notifications' /></strong>
|
|
||||||
<span><FormattedMessage id='filtered_notifications_banner.pending_requests' defaultMessage='Notifications from {count, plural, =0 {no one} one {one person} other {# people}} you may know' values={{ count: policy.getIn(['summary', 'pending_requests_count']) }} /></span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='filtered-notifications-banner__badge'>
|
|
||||||
<div className='filtered-notifications-banner__badge__badge'>{toCappedNumber(policy.getIn(['summary', 'pending_notifications_count']))}</div>
|
|
||||||
<FormattedMessage id='filtered_notifications_banner.mentions' defaultMessage='{count, plural, one {mention} other {mentions}}' values={{ count: policy.getIn(['summary', 'pending_notifications_count']) }} />
|
|
||||||
</div>
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
};
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
import InventoryIcon from '@/material-icons/400-24px/inventory_2.svg?react';
|
||||||
|
import { fetchNotificationPolicy } from 'mastodon/actions/notification_policies';
|
||||||
|
import { Icon } from 'mastodon/components/icon';
|
||||||
|
import { useAppSelector, useAppDispatch } from 'mastodon/store';
|
||||||
|
import { toCappedNumber } from 'mastodon/utils/numbers';
|
||||||
|
|
||||||
|
export const FilteredNotificationsBanner: React.FC = () => {
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const policy = useAppSelector((state) => state.notificationPolicy);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
void dispatch(fetchNotificationPolicy());
|
||||||
|
|
||||||
|
const interval = setInterval(() => {
|
||||||
|
void dispatch(fetchNotificationPolicy());
|
||||||
|
}, 120000);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
clearInterval(interval);
|
||||||
|
};
|
||||||
|
}, [dispatch]);
|
||||||
|
|
||||||
|
if (policy === null || policy.summary.pending_notifications_count === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Link
|
||||||
|
className='filtered-notifications-banner'
|
||||||
|
to='/notifications/requests'
|
||||||
|
>
|
||||||
|
<Icon icon={InventoryIcon} id='filtered-notifications' />
|
||||||
|
|
||||||
|
<div className='filtered-notifications-banner__text'>
|
||||||
|
<strong>
|
||||||
|
<FormattedMessage
|
||||||
|
id='filtered_notifications_banner.title'
|
||||||
|
defaultMessage='Filtered notifications'
|
||||||
|
/>
|
||||||
|
</strong>
|
||||||
|
<span>
|
||||||
|
<FormattedMessage
|
||||||
|
id='filtered_notifications_banner.pending_requests'
|
||||||
|
defaultMessage='Notifications from {count, plural, =0 {no one} one {one person} other {# people}} you may know'
|
||||||
|
values={{ count: policy.summary.pending_requests_count }}
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='filtered-notifications-banner__badge'>
|
||||||
|
<div className='filtered-notifications-banner__badge__badge'>
|
||||||
|
{toCappedNumber(policy.summary.pending_notifications_count)}
|
||||||
|
</div>
|
||||||
|
<FormattedMessage
|
||||||
|
id='filtered_notifications_banner.mentions'
|
||||||
|
defaultMessage='{count, plural, one {mention} other {mentions}}'
|
||||||
|
values={{ count: policy.summary.pending_notifications_count }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
};
|
|
@ -4,7 +4,8 @@ import { connect } from 'react-redux';
|
||||||
|
|
||||||
import { showAlert } from '../../../actions/alerts';
|
import { showAlert } from '../../../actions/alerts';
|
||||||
import { openModal } from '../../../actions/modal';
|
import { openModal } from '../../../actions/modal';
|
||||||
import { setFilter, clearNotifications, requestBrowserPermission, updateNotificationsPolicy } from '../../../actions/notifications';
|
import { updateNotificationsPolicy } from '../../../actions/notification_policies';
|
||||||
|
import { setFilter, clearNotifications, requestBrowserPermission } from '../../../actions/notifications';
|
||||||
import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications';
|
import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications';
|
||||||
import { changeSetting } from '../../../actions/settings';
|
import { changeSetting } from '../../../actions/settings';
|
||||||
import ColumnSettings from '../components/column_settings';
|
import ColumnSettings from '../components/column_settings';
|
||||||
|
@ -15,13 +16,16 @@ const messages = defineMessages({
|
||||||
permissionDenied: { id: 'notifications.permission_denied_alert', defaultMessage: 'Desktop notifications can\'t be enabled, as browser permission has been denied before' },
|
permissionDenied: { id: 'notifications.permission_denied_alert', defaultMessage: 'Desktop notifications can\'t be enabled, as browser permission has been denied before' },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {import('mastodon/store').RootState} state
|
||||||
|
*/
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
settings: state.getIn(['settings', 'notifications']),
|
settings: state.getIn(['settings', 'notifications']),
|
||||||
pushSettings: state.get('push_notifications'),
|
pushSettings: state.get('push_notifications'),
|
||||||
alertsEnabled: state.getIn(['settings', 'notifications', 'alerts']).includes(true),
|
alertsEnabled: state.getIn(['settings', 'notifications', 'alerts']).includes(true),
|
||||||
browserSupport: state.getIn(['notifications', 'browserSupport']),
|
browserSupport: state.getIn(['notifications', 'browserSupport']),
|
||||||
browserPermission: state.getIn(['notifications', 'browserPermission']),
|
browserPermission: state.getIn(['notifications', 'browserPermission']),
|
||||||
notificationPolicy: state.get('notificationPolicy'),
|
notificationPolicy: state.notificationPolicy,
|
||||||
});
|
});
|
||||||
|
|
||||||
const mapDispatchToProps = (dispatch, { intl }) => ({
|
const mapDispatchToProps = (dispatch, { intl }) => ({
|
||||||
|
|
|
@ -147,14 +147,14 @@
|
||||||
"compose.published.body": "Postitus avaldatud.",
|
"compose.published.body": "Postitus avaldatud.",
|
||||||
"compose.published.open": "Ava",
|
"compose.published.open": "Ava",
|
||||||
"compose.saved.body": "Postitus salvestatud.",
|
"compose.saved.body": "Postitus salvestatud.",
|
||||||
"compose_form.direct_message_warning_learn_more": "Vaata täpsemalt",
|
"compose_form.direct_message_warning_learn_more": "Vaata lisa",
|
||||||
"compose_form.encryption_warning": "Postitused Mastodonis ei ole otsast-otsani krüpteeritud. Ära jaga mingeid delikaatseid andmeid Mastodoni kaudu.",
|
"compose_form.encryption_warning": "Postitused Mastodonis ei ole otsast-otsani krüpteeritud. Ära jaga mingeid delikaatseid andmeid Mastodoni kaudu.",
|
||||||
"compose_form.hashtag_warning": "See postitus ei ilmu ühegi märksõna all, kuna pole avalik. Vaid avalikud postitused on märksõnade kaudu leitavad.",
|
"compose_form.hashtag_warning": "See postitus ei ilmu ühegi märksõna all, kuna pole avalik. Vaid avalikud postitused on märksõnade kaudu leitavad.",
|
||||||
"compose_form.lock_disclaimer": "Su konto ei ole {locked}. Igaüks saab sind jälgida, et näha su ainult-jälgijatele postitusi.",
|
"compose_form.lock_disclaimer": "Su konto ei ole {locked}. Igaüks saab sind jälgida, et näha su ainult-jälgijatele postitusi.",
|
||||||
"compose_form.lock_disclaimer.lock": "lukus",
|
"compose_form.lock_disclaimer.lock": "lukus",
|
||||||
"compose_form.placeholder": "Millest mõtled?",
|
"compose_form.placeholder": "Millest mõtled?",
|
||||||
"compose_form.poll.duration": "Küsitluse kestus",
|
"compose_form.poll.duration": "Küsitluse kestus",
|
||||||
"compose_form.poll.multiple": "Valikvastustega",
|
"compose_form.poll.multiple": "Mitu vastust",
|
||||||
"compose_form.poll.option_placeholder": "Valik {number}",
|
"compose_form.poll.option_placeholder": "Valik {number}",
|
||||||
"compose_form.poll.single": "Vali üks",
|
"compose_form.poll.single": "Vali üks",
|
||||||
"compose_form.poll.switch_to_multiple": "Muuda küsitlust mitmikvaliku lubamiseks",
|
"compose_form.poll.switch_to_multiple": "Muuda küsitlust mitmikvaliku lubamiseks",
|
||||||
|
@ -297,6 +297,7 @@
|
||||||
"filter_modal.select_filter.subtitle": "Kasuta olemasolevat kategooriat või loo uus",
|
"filter_modal.select_filter.subtitle": "Kasuta olemasolevat kategooriat või loo uus",
|
||||||
"filter_modal.select_filter.title": "Filtreeri seda postitust",
|
"filter_modal.select_filter.title": "Filtreeri seda postitust",
|
||||||
"filter_modal.title.status": "Postituse filtreerimine",
|
"filter_modal.title.status": "Postituse filtreerimine",
|
||||||
|
"filtered_notifications_banner.mentions": "{count, plural, one {mainimine} other {mainimist}}",
|
||||||
"filtered_notifications_banner.pending_requests": "Teateid {count, plural, =0 {mitte üheltki} one {ühelt} other {#}} inimeselt, keda võid teada",
|
"filtered_notifications_banner.pending_requests": "Teateid {count, plural, =0 {mitte üheltki} one {ühelt} other {#}} inimeselt, keda võid teada",
|
||||||
"filtered_notifications_banner.title": "Filtreeritud teavitused",
|
"filtered_notifications_banner.title": "Filtreeritud teavitused",
|
||||||
"firehose.all": "Kõik",
|
"firehose.all": "Kõik",
|
||||||
|
@ -305,15 +306,19 @@
|
||||||
"follow_request.authorize": "Autoriseeri",
|
"follow_request.authorize": "Autoriseeri",
|
||||||
"follow_request.reject": "Hülga",
|
"follow_request.reject": "Hülga",
|
||||||
"follow_requests.unlocked_explanation": "Kuigi su konto pole lukustatud, soovitab {domain} personal siiski nende kontode jälgimistaotlused käsitsi üle vaadata.",
|
"follow_requests.unlocked_explanation": "Kuigi su konto pole lukustatud, soovitab {domain} personal siiski nende kontode jälgimistaotlused käsitsi üle vaadata.",
|
||||||
"follow_suggestions.curated_suggestion": "Teiste valitud",
|
"follow_suggestions.curated_suggestion": "Meeskonna valitud",
|
||||||
"follow_suggestions.dismiss": "Ära enam näita",
|
"follow_suggestions.dismiss": "Ära enam näita",
|
||||||
"follow_suggestions.hints.featured": "Selle kasutajaprofiili on soovitanud {domain} kasutajad.",
|
"follow_suggestions.featured_longer": "Käsitsi valitud {domain} meeskonna poolt",
|
||||||
"follow_suggestions.hints.friends_of_friends": "See kasutajaprofiil on jälgitavate seas populaarne.",
|
"follow_suggestions.friends_of_friends_longer": "Populaarne inimeste hulgas, keda jälgid",
|
||||||
|
"follow_suggestions.hints.featured": "Selle kasutajaprofiili on soovitanud {domain} meeskond.",
|
||||||
|
"follow_suggestions.hints.friends_of_friends": "See kasutajaprofiil on sinu jälgitavate seas populaarne.",
|
||||||
"follow_suggestions.hints.most_followed": "See on {domain} enim jälgitud kasutajaprofiil.",
|
"follow_suggestions.hints.most_followed": "See on {domain} enim jälgitud kasutajaprofiil.",
|
||||||
"follow_suggestions.hints.most_interactions": "See on {domain} viimasel ajal enim tähelepanu saanud kasutajaprofiil.",
|
"follow_suggestions.hints.most_interactions": "See kasutajaprofiil on viimasel ajal {domain} saanud palju tähelepanu.",
|
||||||
"follow_suggestions.hints.similar_to_recently_followed": "See kasutajaprofiil sarnaneb neile, mida oled hiljuti jälgima asunud.",
|
"follow_suggestions.hints.similar_to_recently_followed": "See kasutajaprofiil sarnaneb neile, mida oled hiljuti jälgima asunud.",
|
||||||
"follow_suggestions.personalized_suggestion": "Isikupärastatud soovitus",
|
"follow_suggestions.personalized_suggestion": "Isikupärastatud soovitus",
|
||||||
"follow_suggestions.popular_suggestion": "Popuplaarne soovitus",
|
"follow_suggestions.popular_suggestion": "Popuplaarne soovitus",
|
||||||
|
"follow_suggestions.popular_suggestion_longer": "Populaarne kohas {domain}",
|
||||||
|
"follow_suggestions.similar_to_recently_followed_longer": "Sarnane profiilile, mida hiljuti jälgima hakkasid",
|
||||||
"follow_suggestions.view_all": "Vaata kõiki",
|
"follow_suggestions.view_all": "Vaata kõiki",
|
||||||
"follow_suggestions.who_to_follow": "Keda jälgida",
|
"follow_suggestions.who_to_follow": "Keda jälgida",
|
||||||
"followed_tags": "Jälgitavad märksõnad",
|
"followed_tags": "Jälgitavad märksõnad",
|
||||||
|
@ -409,6 +414,8 @@
|
||||||
"limited_account_hint.action": "Näita profilli sellegipoolest",
|
"limited_account_hint.action": "Näita profilli sellegipoolest",
|
||||||
"limited_account_hint.title": "See profiil on peidetud {domain} moderaatorite poolt.",
|
"limited_account_hint.title": "See profiil on peidetud {domain} moderaatorite poolt.",
|
||||||
"link_preview.author": "{name} poolt",
|
"link_preview.author": "{name} poolt",
|
||||||
|
"link_preview.more_from_author": "Veel kasutajalt {name}",
|
||||||
|
"link_preview.shares": "{count, plural, one {{counter} postitus} other {{counter} postitust}}",
|
||||||
"lists.account.add": "Lisa nimekirja",
|
"lists.account.add": "Lisa nimekirja",
|
||||||
"lists.account.remove": "Eemalda nimekirjast",
|
"lists.account.remove": "Eemalda nimekirjast",
|
||||||
"lists.delete": "Kustuta nimekiri",
|
"lists.delete": "Kustuta nimekiri",
|
||||||
|
@ -468,13 +475,22 @@
|
||||||
"notification.follow": "{name} alustas su jälgimist",
|
"notification.follow": "{name} alustas su jälgimist",
|
||||||
"notification.follow_request": "{name} soovib sind jälgida",
|
"notification.follow_request": "{name} soovib sind jälgida",
|
||||||
"notification.mention": "{name} mainis sind",
|
"notification.mention": "{name} mainis sind",
|
||||||
|
"notification.moderation-warning.learn_more": "Vaata lisa",
|
||||||
|
"notification.moderation_warning": "Said modereerimise hoiatuse",
|
||||||
|
"notification.moderation_warning.action_delete_statuses": "Mõni su postitus on eemaldatud.",
|
||||||
|
"notification.moderation_warning.action_disable": "Su konto on keelatud.",
|
||||||
|
"notification.moderation_warning.action_mark_statuses_as_sensitive": "Mõni su postitustest on märgitud kui tundlik.",
|
||||||
|
"notification.moderation_warning.action_none": "Su konto on saanud modereerimise hoiatuse.",
|
||||||
|
"notification.moderation_warning.action_sensitive": "Su postitused märgitakse nüüdsest tundlikuks.",
|
||||||
|
"notification.moderation_warning.action_silence": "Su kontole pandi piirang.",
|
||||||
|
"notification.moderation_warning.action_suspend": "Su konto on peatatud.",
|
||||||
"notification.own_poll": "Su küsitlus on lõppenud",
|
"notification.own_poll": "Su küsitlus on lõppenud",
|
||||||
"notification.poll": "Küsitlus, milles osalesid, on lõppenud",
|
"notification.poll": "Küsitlus, milles osalesid, on lõppenud",
|
||||||
"notification.reblog": "{name} jagas edasi postitust",
|
"notification.reblog": "{name} jagas edasi postitust",
|
||||||
"notification.relationships_severance_event": "Kadunud ühendus kasutajaga {name}",
|
"notification.relationships_severance_event": "Kadunud ühendus kasutajaga {name}",
|
||||||
"notification.relationships_severance_event.account_suspension": "{from} admin on kustutanud {target}, mis tähendab, et sa ei saa enam neilt uuendusi või suhelda nendega.",
|
"notification.relationships_severance_event.account_suspension": "{from} admin on kustutanud {target}, mis tähendab, et sa ei saa enam neilt uuendusi või suhelda nendega.",
|
||||||
"notification.relationships_severance_event.domain_block": "{from} admin on blokeerinud {target}, sealhulgas {followersCount} sinu jälgijat ja {followingCount, plural, one {# konto} other {# kontot}}, mida jälgid.",
|
"notification.relationships_severance_event.domain_block": "{from} admin on blokeerinud {target}, sealhulgas {followersCount} sinu jälgijat ja {followingCount, plural, one {# konto} other {# kontot}}, mida jälgid.",
|
||||||
"notification.relationships_severance_event.learn_more": "Saa rohkem teada",
|
"notification.relationships_severance_event.learn_more": "Vaata lisa",
|
||||||
"notification.relationships_severance_event.user_domain_block": "Blokeerisid {target}, eemaldades oma jälgijate hulgast {followersCount} ja jälgitavate hulgast {followingCount, plural, one {# konto} other {# kontot}}.",
|
"notification.relationships_severance_event.user_domain_block": "Blokeerisid {target}, eemaldades oma jälgijate hulgast {followersCount} ja jälgitavate hulgast {followingCount, plural, one {# konto} other {# kontot}}.",
|
||||||
"notification.status": "{name} just postitas",
|
"notification.status": "{name} just postitas",
|
||||||
"notification.update": "{name} muutis postitust",
|
"notification.update": "{name} muutis postitust",
|
||||||
|
@ -680,8 +696,11 @@
|
||||||
"server_banner.about_active_users": "Inimesed, kes kasutavad seda serverit viimase 30 päeva jooksul (kuu aktiivsed kasutajad)",
|
"server_banner.about_active_users": "Inimesed, kes kasutavad seda serverit viimase 30 päeva jooksul (kuu aktiivsed kasutajad)",
|
||||||
"server_banner.active_users": "aktiivsed kasutajad",
|
"server_banner.active_users": "aktiivsed kasutajad",
|
||||||
"server_banner.administered_by": "Administraator:",
|
"server_banner.administered_by": "Administraator:",
|
||||||
|
"server_banner.is_one_of_many": "{domain} on üks paljudest sõltumatutest Mastodoni serveritest, mida saab fediversumis osalemiseks kasutada.",
|
||||||
"server_banner.server_stats": "Serveri statistika:",
|
"server_banner.server_stats": "Serveri statistika:",
|
||||||
"sign_in_banner.create_account": "Loo konto",
|
"sign_in_banner.create_account": "Loo konto",
|
||||||
|
"sign_in_banner.follow_anyone": "Jälgi ükskõik keda kogu fediversumist ja näe kõike ajalises järjestuses. Ei mingeid algoritme, reklaame või klikipüüdjaid segamas.",
|
||||||
|
"sign_in_banner.mastodon_is": "Mastodon on parim viis olemaks kursis sellega, mis toimub.",
|
||||||
"sign_in_banner.sign_in": "Logi sisse",
|
"sign_in_banner.sign_in": "Logi sisse",
|
||||||
"sign_in_banner.sso_redirect": "Sisene või registreeru",
|
"sign_in_banner.sso_redirect": "Sisene või registreeru",
|
||||||
"status.admin_account": "Ava @{name} moderaatorivaates",
|
"status.admin_account": "Ava @{name} moderaatorivaates",
|
||||||
|
|
|
@ -80,6 +80,7 @@
|
||||||
"admin.dashboard.retention.cohort_size": "नये उपयोगकर्ता",
|
"admin.dashboard.retention.cohort_size": "नये उपयोगकर्ता",
|
||||||
"admin.impact_report.instance_accounts": "ये अकाउंट प्रोफाइल मिटा देगा",
|
"admin.impact_report.instance_accounts": "ये अकाउंट प्रोफाइल मिटा देगा",
|
||||||
"admin.impact_report.instance_followers": "हमारे यूजर्स इन फॉलोअर्स को खो देंगे",
|
"admin.impact_report.instance_followers": "हमारे यूजर्स इन फॉलोअर्स को खो देंगे",
|
||||||
|
"admin.impact_report.instance_follows": "उनके उपयोगकर्ता इतने फ़ॉलोअर खो देंगे",
|
||||||
"admin.impact_report.title": "प्रभावकां सारांश",
|
"admin.impact_report.title": "प्रभावकां सारांश",
|
||||||
"alert.rate_limited.message": "कृप्या {retry_time, time, medium} के बाद दुबारा कोशिश करें",
|
"alert.rate_limited.message": "कृप्या {retry_time, time, medium} के बाद दुबारा कोशिश करें",
|
||||||
"alert.rate_limited.title": "सीमित दर",
|
"alert.rate_limited.title": "सीमित दर",
|
||||||
|
@ -88,6 +89,7 @@
|
||||||
"announcement.announcement": "घोषणा",
|
"announcement.announcement": "घोषणा",
|
||||||
"attachments_list.unprocessed": "(असंसाधित)",
|
"attachments_list.unprocessed": "(असंसाधित)",
|
||||||
"audio.hide": "हाईड ऑडियो",
|
"audio.hide": "हाईड ऑडियो",
|
||||||
|
"block_modal.remote_users_caveat": "हम {domain} को आपके निर्णय का सम्मान करने को कहेंगे।हालाकि इसकी आपूर्ति कि प्रत्याभूति नहीं हे। क्योंकि कुछ सर्वर ब्लॉक को अलग तरह से निभा सकते हे। अभी भी सार्वजानिक पोस्ट लोग- इन बगैर के उपयोगकर्ताओं को दिख सकती हैं।",
|
||||||
"block_modal.show_less": "कम दिखाएं",
|
"block_modal.show_less": "कम दिखाएं",
|
||||||
"block_modal.show_more": "और दिखाएँ",
|
"block_modal.show_more": "और दिखाएँ",
|
||||||
"block_modal.they_cant_mention": "वे आपको मेंशन या फॉलो नहीं कर सकते",
|
"block_modal.they_cant_mention": "वे आपको मेंशन या फॉलो नहीं कर सकते",
|
||||||
|
@ -205,7 +207,12 @@
|
||||||
"dismissable_banner.dismiss": "डिसमिस",
|
"dismissable_banner.dismiss": "डिसमिस",
|
||||||
"dismissable_banner.explore_links": "इन समाचारों के बारे में लोगों द्वारा इस पर और डेसेंट्रलीसेड नेटवर्क के अन्य सर्वरों पर अभी बात की जा रही है।",
|
"dismissable_banner.explore_links": "इन समाचारों के बारे में लोगों द्वारा इस पर और डेसेंट्रलीसेड नेटवर्क के अन्य सर्वरों पर अभी बात की जा रही है।",
|
||||||
"dismissable_banner.explore_tags": "ये हैशटैग अभी इस पर और डेसेंट्रलीसेड नेटवर्क के अन्य सर्वरों पर लोगों के बीच कर्षण प्राप्त कर रहे हैं।",
|
"dismissable_banner.explore_tags": "ये हैशटैग अभी इस पर और डेसेंट्रलीसेड नेटवर्क के अन्य सर्वरों पर लोगों के बीच कर्षण प्राप्त कर रहे हैं।",
|
||||||
|
"dismissable_banner.public_timeline": "यह ताजा सार्वजनिक पोस्ट है जिसका सामाजिक वेब {domain} के लोगो द्वारा अनुसरण हो रहा हैं।",
|
||||||
"domain_block_modal.block": "सर्वर ब्लॉक करें",
|
"domain_block_modal.block": "सर्वर ब्लॉक करें",
|
||||||
|
"domain_block_modal.block_account_instead": "इसकी जगह यह @{name} रखें",
|
||||||
|
"domain_block_modal.they_can_interact_with_old_posts": "इस सर्वर की लोग आपकी पूरानी पोस्ट्स का अनुसरण किया जा sakta है।",
|
||||||
|
"domain_block_modal.they_cant_follow": "इस सर्वर मेसे कोई भी आपका अनुसरण नहीं कर सकता।",
|
||||||
|
"domain_block_modal.they_wont_know": "उनको पता नहीं चलेगा कि वे अवरोधित किए गए है।",
|
||||||
"domain_block_modal.title": "डोमेन ब्लॉक करें",
|
"domain_block_modal.title": "डोमेन ब्लॉक करें",
|
||||||
"domain_pill.server": "सर्वर",
|
"domain_pill.server": "सर्वर",
|
||||||
"domain_pill.username": "यूज़रनेम",
|
"domain_pill.username": "यूज़रनेम",
|
||||||
|
|
|
@ -696,8 +696,10 @@
|
||||||
"server_banner.about_active_users": "Personas que ha usate iste servitor in le ultime 30 dies (usatores active per mense)",
|
"server_banner.about_active_users": "Personas que ha usate iste servitor in le ultime 30 dies (usatores active per mense)",
|
||||||
"server_banner.active_users": "usatores active",
|
"server_banner.active_users": "usatores active",
|
||||||
"server_banner.administered_by": "Administrate per:",
|
"server_banner.administered_by": "Administrate per:",
|
||||||
|
"server_banner.is_one_of_many": "{domain} es un de multe servitores independente de Mastodon que tu pote usar pro participar in le fediverso.",
|
||||||
"server_banner.server_stats": "Statos del servitor:",
|
"server_banner.server_stats": "Statos del servitor:",
|
||||||
"sign_in_banner.create_account": "Crear un conto",
|
"sign_in_banner.create_account": "Crear un conto",
|
||||||
|
"sign_in_banner.mastodon_is": "Mastodon es le melior maniera de sequer lo que passa.",
|
||||||
"sign_in_banner.sign_in": "Aperir session",
|
"sign_in_banner.sign_in": "Aperir session",
|
||||||
"sign_in_banner.sso_redirect": "Aperir session o crear conto",
|
"sign_in_banner.sso_redirect": "Aperir session o crear conto",
|
||||||
"status.admin_account": "Aperir le interfacie de moderation pro @{name}",
|
"status.admin_account": "Aperir le interfacie de moderation pro @{name}",
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
"account.featured_tags.last_status_never": "게시물 없음",
|
"account.featured_tags.last_status_never": "게시물 없음",
|
||||||
"account.featured_tags.title": "{name} 님의 추천 해시태그",
|
"account.featured_tags.title": "{name} 님의 추천 해시태그",
|
||||||
"account.follow": "팔로우",
|
"account.follow": "팔로우",
|
||||||
"account.follow_back": "맞팔로우",
|
"account.follow_back": "맞팔로우 하기",
|
||||||
"account.followers": "팔로워",
|
"account.followers": "팔로워",
|
||||||
"account.followers.empty": "아직 아무도 이 사용자를 팔로우하고 있지 않습니다.",
|
"account.followers.empty": "아직 아무도 이 사용자를 팔로우하고 있지 않습니다.",
|
||||||
"account.followers_counter": "{counter} 팔로워",
|
"account.followers_counter": "{counter} 팔로워",
|
||||||
|
@ -53,7 +53,7 @@
|
||||||
"account.mute_notifications_short": "알림 뮤트",
|
"account.mute_notifications_short": "알림 뮤트",
|
||||||
"account.mute_short": "뮤트",
|
"account.mute_short": "뮤트",
|
||||||
"account.muted": "뮤트됨",
|
"account.muted": "뮤트됨",
|
||||||
"account.mutual": "상호 팔로우",
|
"account.mutual": "맞팔로우 중",
|
||||||
"account.no_bio": "제공된 설명이 없습니다.",
|
"account.no_bio": "제공된 설명이 없습니다.",
|
||||||
"account.open_original_page": "원본 페이지 열기",
|
"account.open_original_page": "원본 페이지 열기",
|
||||||
"account.posts": "게시물",
|
"account.posts": "게시물",
|
||||||
|
|
3
app/javascript/mastodon/models/notification_policy.ts
Normal file
3
app/javascript/mastodon/models/notification_policy.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
import type { NotificationPolicyJSON } from 'mastodon/api_types/notification_policies';
|
||||||
|
|
||||||
|
export type NotificationPolicy = NotificationPolicyJSON; // No changes from the API type
|
|
@ -1,5 +1,7 @@
|
||||||
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
|
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
|
||||||
|
|
||||||
|
import { timelineDelete } from 'mastodon/actions/timelines_typed';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
COMPOSE_MOUNT,
|
COMPOSE_MOUNT,
|
||||||
COMPOSE_UNMOUNT,
|
COMPOSE_UNMOUNT,
|
||||||
|
@ -57,7 +59,6 @@ import {
|
||||||
} from '../actions/compose';
|
} from '../actions/compose';
|
||||||
import { REDRAFT } from '../actions/statuses';
|
import { REDRAFT } from '../actions/statuses';
|
||||||
import { STORE_HYDRATE } from '../actions/store';
|
import { STORE_HYDRATE } from '../actions/store';
|
||||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
|
||||||
import { enabledVisibilites, me } from '../initial_state';
|
import { enabledVisibilites, me } from '../initial_state';
|
||||||
import { unescapeHTML } from '../utils/html';
|
import { unescapeHTML } from '../utils/html';
|
||||||
import { uuid } from '../uuid';
|
import { uuid } from '../uuid';
|
||||||
|
@ -565,14 +566,14 @@ export default function compose(state = initialState, action) {
|
||||||
return updateSuggestionTags(state, action.token);
|
return updateSuggestionTags(state, action.token);
|
||||||
case COMPOSE_TAG_HISTORY_UPDATE:
|
case COMPOSE_TAG_HISTORY_UPDATE:
|
||||||
return state.set('tagHistory', fromJS(action.tags));
|
return state.set('tagHistory', fromJS(action.tags));
|
||||||
case TIMELINE_DELETE:
|
case timelineDelete.type:
|
||||||
if (action.id === state.get('in_reply_to')) {
|
if (action.payload.statusId === state.get('in_reply_to')) {
|
||||||
if (state.get('privacy') === 'reply') {
|
if (state.get('privacy') === 'reply') {
|
||||||
return state.set('in_reply_to', null).set('privacy', 'circle');
|
return state.set('in_reply_to', null).set('privacy', 'circle');
|
||||||
} else {
|
} else {
|
||||||
return state.set('in_reply_to', null);
|
return state.set('in_reply_to', null);
|
||||||
}
|
}
|
||||||
} else if (action.id === state.get('id')) {
|
} else if (action.payload.statusId === state.get('id')) {
|
||||||
return state.set('id', null);
|
return state.set('id', null);
|
||||||
} else {
|
} else {
|
||||||
return state;
|
return state;
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
import { Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||||
|
|
||||||
|
import { timelineDelete } from 'mastodon/actions/timelines_typed';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
blockAccountSuccess,
|
blockAccountSuccess,
|
||||||
muteAccountSuccess,
|
muteAccountSuccess,
|
||||||
} from '../actions/accounts';
|
} from '../actions/accounts';
|
||||||
import { CONTEXT_FETCH_SUCCESS } from '../actions/statuses';
|
import { CONTEXT_FETCH_SUCCESS } from '../actions/statuses';
|
||||||
import { TIMELINE_DELETE, TIMELINE_UPDATE } from '../actions/timelines';
|
import { TIMELINE_UPDATE } from '../actions/timelines';
|
||||||
import { compareId } from '../compare_id';
|
import { compareId } from '../compare_id';
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const initialState = ImmutableMap({
|
||||||
|
@ -102,8 +104,8 @@ export default function replies(state = initialState, action) {
|
||||||
return filterContexts(state, action.payload.relationship, action.payload.statuses);
|
return filterContexts(state, action.payload.relationship, action.payload.statuses);
|
||||||
case CONTEXT_FETCH_SUCCESS:
|
case CONTEXT_FETCH_SUCCESS:
|
||||||
return normalizeContext(state, action.id, action.ancestors, action.descendants, action.references);
|
return normalizeContext(state, action.id, action.ancestors, action.descendants, action.references);
|
||||||
case TIMELINE_DELETE:
|
case timelineDelete.type:
|
||||||
return deleteFromContexts(state, [action.id]);
|
return deleteFromContexts(state, [action.payload.statusId]);
|
||||||
case TIMELINE_UPDATE:
|
case TIMELINE_UPDATE:
|
||||||
return updateContext(state, action.status);
|
return updateContext(state, action.status);
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import type { Reducer } from '@reduxjs/toolkit';
|
import type { Reducer } from '@reduxjs/toolkit';
|
||||||
import { Record as ImmutableRecord, Stack } from 'immutable';
|
import { Record as ImmutableRecord, Stack } from 'immutable';
|
||||||
|
|
||||||
|
import { timelineDelete } from 'mastodon/actions/timelines_typed';
|
||||||
|
|
||||||
import { COMPOSE_UPLOAD_CHANGE_SUCCESS } from '../actions/compose';
|
import { COMPOSE_UPLOAD_CHANGE_SUCCESS } from '../actions/compose';
|
||||||
import type { ModalType } from '../actions/modal';
|
import type { ModalType } from '../actions/modal';
|
||||||
import { openModal, closeModal } from '../actions/modal';
|
import { openModal, closeModal } from '../actions/modal';
|
||||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
|
||||||
|
|
||||||
export type ModalProps = Record<string, unknown>;
|
export type ModalProps = Record<string, unknown>;
|
||||||
interface Modal {
|
interface Modal {
|
||||||
|
@ -72,10 +73,10 @@ export const modalReducer: Reducer<State> = (state = initialState, action) => {
|
||||||
// TODO: type those actions
|
// TODO: type those actions
|
||||||
else if (action.type === COMPOSE_UPLOAD_CHANGE_SUCCESS)
|
else if (action.type === COMPOSE_UPLOAD_CHANGE_SUCCESS)
|
||||||
return popModal(state, { modalType: 'FOCAL_POINT', ignoreFocus: false });
|
return popModal(state, { modalType: 'FOCAL_POINT', ignoreFocus: false });
|
||||||
else if (action.type === TIMELINE_DELETE)
|
else if (timelineDelete.match(action))
|
||||||
return state.update('stack', (stack) =>
|
return state.update('stack', (stack) =>
|
||||||
stack.filterNot(
|
stack.filterNot(
|
||||||
(modal) => modal.get('modalProps').statusId === action.id,
|
(modal) => modal.get('modalProps').statusId === action.payload.statusId,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
else return state;
|
else return state;
|
||||||
|
|
|
@ -1,12 +0,0 @@
|
||||||
import { fromJS } from 'immutable';
|
|
||||||
|
|
||||||
import { NOTIFICATION_POLICY_FETCH_SUCCESS } from 'mastodon/actions/notifications';
|
|
||||||
|
|
||||||
export const notificationPolicyReducer = (state = null, action) => {
|
|
||||||
switch(action.type) {
|
|
||||||
case NOTIFICATION_POLICY_FETCH_SUCCESS:
|
|
||||||
return fromJS(action.policy);
|
|
||||||
default:
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
};
|
|
18
app/javascript/mastodon/reducers/notification_policy.ts
Normal file
18
app/javascript/mastodon/reducers/notification_policy.ts
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { createReducer, isAnyOf } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
import {
|
||||||
|
fetchNotificationPolicy,
|
||||||
|
updateNotificationsPolicy,
|
||||||
|
} from 'mastodon/actions/notification_policies';
|
||||||
|
import type { NotificationPolicy } from 'mastodon/models/notification_policy';
|
||||||
|
|
||||||
|
export const notificationPolicyReducer =
|
||||||
|
createReducer<NotificationPolicy | null>(null, (builder) => {
|
||||||
|
builder.addMatcher(
|
||||||
|
isAnyOf(
|
||||||
|
fetchNotificationPolicy.fulfilled,
|
||||||
|
updateNotificationsPolicy.fulfilled,
|
||||||
|
),
|
||||||
|
(_state, action) => action.payload,
|
||||||
|
);
|
||||||
|
});
|
|
@ -1,6 +1,7 @@
|
||||||
import { fromJS, Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
import { fromJS, Map as ImmutableMap, List as ImmutableList } from 'immutable';
|
||||||
|
|
||||||
import { blockDomainSuccess } from 'mastodon/actions/domain_blocks';
|
import { blockDomainSuccess } from 'mastodon/actions/domain_blocks';
|
||||||
|
import { timelineDelete } from 'mastodon/actions/timelines_typed';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
authorizeFollowRequestSuccess,
|
authorizeFollowRequestSuccess,
|
||||||
|
@ -30,7 +31,7 @@ import {
|
||||||
NOTIFICATIONS_SET_BROWSER_SUPPORT,
|
NOTIFICATIONS_SET_BROWSER_SUPPORT,
|
||||||
NOTIFICATIONS_SET_BROWSER_PERMISSION,
|
NOTIFICATIONS_SET_BROWSER_PERMISSION,
|
||||||
} from '../actions/notifications';
|
} from '../actions/notifications';
|
||||||
import { TIMELINE_DELETE, TIMELINE_DISCONNECT } from '../actions/timelines';
|
import { disconnectTimeline } from '../actions/timelines';
|
||||||
import { compareId } from '../compare_id';
|
import { compareId } from '../compare_id';
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const initialState = ImmutableMap({
|
||||||
|
@ -293,11 +294,11 @@ export default function notifications(state = initialState, action) {
|
||||||
return filterNotifications(state, [action.payload.id], 'follow_request');
|
return filterNotifications(state, [action.payload.id], 'follow_request');
|
||||||
case NOTIFICATIONS_CLEAR:
|
case NOTIFICATIONS_CLEAR:
|
||||||
return state.set('items', ImmutableList()).set('pendingItems', ImmutableList()).set('hasMore', false);
|
return state.set('items', ImmutableList()).set('pendingItems', ImmutableList()).set('hasMore', false);
|
||||||
case TIMELINE_DELETE:
|
case timelineDelete.type:
|
||||||
return deleteByStatus(state, action.id);
|
return deleteByStatus(state, action.payload.statusId);
|
||||||
case TIMELINE_DISCONNECT:
|
case disconnectTimeline.type:
|
||||||
return action.timeline === 'home' ?
|
return action.payload.timeline === 'home' ?
|
||||||
state.update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items) :
|
state.update(action.payload.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(null) : items) :
|
||||||
state;
|
state;
|
||||||
case NOTIFICATIONS_MARK_AS_READ:
|
case NOTIFICATIONS_MARK_AS_READ:
|
||||||
const lastNotification = state.get('items').find(item => item !== null);
|
const lastNotification = state.get('items').find(item => item !== null);
|
||||||
|
|
|
@ -4,8 +4,7 @@ import {
|
||||||
deployPictureInPictureAction,
|
deployPictureInPictureAction,
|
||||||
removePictureInPicture,
|
removePictureInPicture,
|
||||||
} from 'mastodon/actions/picture_in_picture';
|
} from 'mastodon/actions/picture_in_picture';
|
||||||
|
import { timelineDelete } from 'mastodon/actions/timelines_typed';
|
||||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
|
||||||
|
|
||||||
export interface PIPMediaProps {
|
export interface PIPMediaProps {
|
||||||
src: string;
|
src: string;
|
||||||
|
@ -49,8 +48,9 @@ export const pictureInPictureReducer: Reducer<PIPState> = (
|
||||||
...action.payload.props,
|
...action.payload.props,
|
||||||
};
|
};
|
||||||
else if (removePictureInPicture.match(action)) return initialState;
|
else if (removePictureInPicture.match(action)) return initialState;
|
||||||
else if (action.type === TIMELINE_DELETE)
|
else if (timelineDelete.match(action))
|
||||||
if (state.type && state.statusId === action.id) return initialState;
|
if (state.type && state.statusId === action.payload.statusId)
|
||||||
|
return initialState;
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
|
import { Map as ImmutableMap, List as ImmutableList, fromJS } from 'immutable';
|
||||||
|
|
||||||
|
import { timelineDelete } from 'mastodon/actions/timelines_typed';
|
||||||
import { me } from 'mastodon/initial_state';
|
import { me } from 'mastodon/initial_state';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -34,7 +35,6 @@ import {
|
||||||
STATUS_FETCH_FAIL,
|
STATUS_FETCH_FAIL,
|
||||||
STATUS_EMOJI_REACTION_UPDATE,
|
STATUS_EMOJI_REACTION_UPDATE,
|
||||||
} from '../actions/statuses';
|
} from '../actions/statuses';
|
||||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
|
||||||
|
|
||||||
const importStatus = (state, status) => state.set(status.id, fromJS(status));
|
const importStatus = (state, status) => state.set(status.id, fromJS(status));
|
||||||
|
|
||||||
|
@ -152,8 +152,8 @@ export default function statuses(state = initialState, action) {
|
||||||
});
|
});
|
||||||
case STATUS_COLLAPSE:
|
case STATUS_COLLAPSE:
|
||||||
return state.setIn([action.id, 'collapsed'], action.isCollapsed);
|
return state.setIn([action.id, 'collapsed'], action.isCollapsed);
|
||||||
case TIMELINE_DELETE:
|
case timelineDelete.type:
|
||||||
return deleteStatus(state, action.id, action.references);
|
return deleteStatus(state, action.payload.statusId, action.payload.references);
|
||||||
case STATUS_TRANSLATE_SUCCESS:
|
case STATUS_TRANSLATE_SUCCESS:
|
||||||
return statusTranslateSuccess(state, action.id, action.translation);
|
return statusTranslateSuccess(state, action.id, action.translation);
|
||||||
case STATUS_TRANSLATE_UNDO:
|
case STATUS_TRANSLATE_UNDO:
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
|
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, fromJS } from 'immutable';
|
||||||
|
|
||||||
|
import { timelineDelete } from 'mastodon/actions/timelines_typed';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
blockAccountSuccess,
|
blockAccountSuccess,
|
||||||
muteAccountSuccess,
|
muteAccountSuccess,
|
||||||
|
@ -7,19 +9,18 @@ import {
|
||||||
} from '../actions/accounts';
|
} from '../actions/accounts';
|
||||||
import {
|
import {
|
||||||
TIMELINE_UPDATE,
|
TIMELINE_UPDATE,
|
||||||
TIMELINE_DELETE,
|
|
||||||
TIMELINE_CLEAR,
|
TIMELINE_CLEAR,
|
||||||
TIMELINE_EXPAND_SUCCESS,
|
TIMELINE_EXPAND_SUCCESS,
|
||||||
TIMELINE_EXPAND_REQUEST,
|
TIMELINE_EXPAND_REQUEST,
|
||||||
TIMELINE_EXPAND_FAIL,
|
TIMELINE_EXPAND_FAIL,
|
||||||
TIMELINE_SCROLL_TOP,
|
TIMELINE_SCROLL_TOP,
|
||||||
TIMELINE_CONNECT,
|
TIMELINE_CONNECT,
|
||||||
TIMELINE_DISCONNECT,
|
|
||||||
TIMELINE_LOAD_PENDING,
|
TIMELINE_LOAD_PENDING,
|
||||||
TIMELINE_MARK_AS_PARTIAL,
|
TIMELINE_MARK_AS_PARTIAL,
|
||||||
TIMELINE_INSERT,
|
TIMELINE_INSERT,
|
||||||
TIMELINE_GAP,
|
TIMELINE_GAP,
|
||||||
TIMELINE_SUGGESTIONS,
|
TIMELINE_SUGGESTIONS,
|
||||||
|
disconnectTimeline,
|
||||||
} from '../actions/timelines';
|
} from '../actions/timelines';
|
||||||
import { compareId } from '../compare_id';
|
import { compareId } from '../compare_id';
|
||||||
|
|
||||||
|
@ -158,7 +159,7 @@ const filterTimelines = (state, relationship, statuses) => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
references = statuses.filter(item => item.get('reblog') === status.get('id')).map(item => item.get('id'));
|
references = statuses.filter(item => item.get('reblog') === status.get('id')).map(item => item.get('id')).valueSeq().toJSON();
|
||||||
state = deleteStatus(state, status.get('id'), references, relationship.id);
|
state = deleteStatus(state, status.get('id'), references, relationship.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -201,8 +202,8 @@ export default function timelines(state = initialState, action) {
|
||||||
return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial, action.isLoadingRecent, action.usePendingItems);
|
return expandNormalizedTimeline(state, action.timeline, fromJS(action.statuses), action.next, action.partial, action.isLoadingRecent, action.usePendingItems);
|
||||||
case TIMELINE_UPDATE:
|
case TIMELINE_UPDATE:
|
||||||
return updateTimeline(state, action.timeline, fromJS(action.status), action.usePendingItems);
|
return updateTimeline(state, action.timeline, fromJS(action.status), action.usePendingItems);
|
||||||
case TIMELINE_DELETE:
|
case timelineDelete.type:
|
||||||
return deleteStatus(state, action.id, action.references, action.reblogOf);
|
return deleteStatus(state, action.payload.statusId, action.payload.references, action.payload.reblogOf);
|
||||||
case TIMELINE_CLEAR:
|
case TIMELINE_CLEAR:
|
||||||
return clearTimeline(state, action.timeline);
|
return clearTimeline(state, action.timeline);
|
||||||
case blockAccountSuccess.type:
|
case blockAccountSuccess.type:
|
||||||
|
@ -214,11 +215,11 @@ export default function timelines(state = initialState, action) {
|
||||||
return updateTop(state, action.timeline, action.top);
|
return updateTop(state, action.timeline, action.top);
|
||||||
case TIMELINE_CONNECT:
|
case TIMELINE_CONNECT:
|
||||||
return state.update(action.timeline, initialTimeline, map => reconnectTimeline(map, action.usePendingItems));
|
return state.update(action.timeline, initialTimeline, map => reconnectTimeline(map, action.usePendingItems));
|
||||||
case TIMELINE_DISCONNECT:
|
case disconnectTimeline.type:
|
||||||
return state.update(
|
return state.update(
|
||||||
action.timeline,
|
action.payload.timeline,
|
||||||
initialTimeline,
|
initialTimeline,
|
||||||
map => map.set('online', false).update(action.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(TIMELINE_GAP) : items),
|
map => map.set('online', false).update(action.payload.usePendingItems ? 'pendingItems' : 'items', items => items.first() ? items.unshift(TIMELINE_GAP) : items),
|
||||||
);
|
);
|
||||||
case TIMELINE_MARK_AS_PARTIAL:
|
case TIMELINE_MARK_AS_PARTIAL:
|
||||||
return state.update(
|
return state.update(
|
||||||
|
|
|
@ -82,13 +82,19 @@ export function createThunk<Arg = void, Returned = void>(
|
||||||
const discardLoadDataInPayload = Symbol('discardLoadDataInPayload');
|
const discardLoadDataInPayload = Symbol('discardLoadDataInPayload');
|
||||||
type DiscardLoadData = typeof discardLoadDataInPayload;
|
type DiscardLoadData = typeof discardLoadDataInPayload;
|
||||||
|
|
||||||
type OnData<LoadDataResult, ReturnedData> = (
|
type OnData<ActionArg, LoadDataResult, ReturnedData> = (
|
||||||
data: LoadDataResult,
|
data: LoadDataResult,
|
||||||
api: AppThunkApi & {
|
api: AppThunkApi & {
|
||||||
|
actionArg: ActionArg;
|
||||||
discardLoadData: DiscardLoadData;
|
discardLoadData: DiscardLoadData;
|
||||||
},
|
},
|
||||||
) => ReturnedData | DiscardLoadData | Promise<ReturnedData | DiscardLoadData>;
|
) => ReturnedData | DiscardLoadData | Promise<ReturnedData | DiscardLoadData>;
|
||||||
|
|
||||||
|
type LoadData<Args, LoadDataResult> = (
|
||||||
|
args: Args,
|
||||||
|
api: AppThunkApi,
|
||||||
|
) => Promise<LoadDataResult>;
|
||||||
|
|
||||||
type ArgsType = Record<string, unknown> | undefined;
|
type ArgsType = Record<string, unknown> | undefined;
|
||||||
|
|
||||||
// Overload when there is no `onData` method, the payload is the `onData` result
|
// Overload when there is no `onData` method, the payload is the `onData` result
|
||||||
|
@ -101,18 +107,18 @@ export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
|
||||||
// Overload when the `onData` method returns discardLoadDataInPayload, then the payload is empty
|
// Overload when the `onData` method returns discardLoadDataInPayload, then the payload is empty
|
||||||
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
|
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
|
||||||
name: string,
|
name: string,
|
||||||
loadData: (args: Args) => Promise<LoadDataResult>,
|
loadData: LoadData<Args, LoadDataResult>,
|
||||||
onDataOrThunkOptions?:
|
onDataOrThunkOptions?:
|
||||||
| AppThunkOptions
|
| AppThunkOptions
|
||||||
| OnData<LoadDataResult, DiscardLoadData>,
|
| OnData<Args, LoadDataResult, DiscardLoadData>,
|
||||||
thunkOptions?: AppThunkOptions,
|
thunkOptions?: AppThunkOptions,
|
||||||
): ReturnType<typeof createThunk<Args, void>>;
|
): ReturnType<typeof createThunk<Args, void>>;
|
||||||
|
|
||||||
// Overload when the `onData` method returns nothing, then the mayload is the `onData` result
|
// Overload when the `onData` method returns nothing, then the mayload is the `onData` result
|
||||||
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
|
export function createDataLoadingThunk<LoadDataResult, Args extends ArgsType>(
|
||||||
name: string,
|
name: string,
|
||||||
loadData: (args: Args) => Promise<LoadDataResult>,
|
loadData: LoadData<Args, LoadDataResult>,
|
||||||
onDataOrThunkOptions?: AppThunkOptions | OnData<LoadDataResult, void>,
|
onDataOrThunkOptions?: AppThunkOptions | OnData<Args, LoadDataResult, void>,
|
||||||
thunkOptions?: AppThunkOptions,
|
thunkOptions?: AppThunkOptions,
|
||||||
): ReturnType<typeof createThunk<Args, LoadDataResult>>;
|
): ReturnType<typeof createThunk<Args, LoadDataResult>>;
|
||||||
|
|
||||||
|
@ -123,8 +129,10 @@ export function createDataLoadingThunk<
|
||||||
Returned,
|
Returned,
|
||||||
>(
|
>(
|
||||||
name: string,
|
name: string,
|
||||||
loadData: (args: Args) => Promise<LoadDataResult>,
|
loadData: LoadData<Args, LoadDataResult>,
|
||||||
onDataOrThunkOptions?: AppThunkOptions | OnData<LoadDataResult, Returned>,
|
onDataOrThunkOptions?:
|
||||||
|
| AppThunkOptions
|
||||||
|
| OnData<Args, LoadDataResult, Returned>,
|
||||||
thunkOptions?: AppThunkOptions,
|
thunkOptions?: AppThunkOptions,
|
||||||
): ReturnType<typeof createThunk<Args, Returned>>;
|
): ReturnType<typeof createThunk<Args, Returned>>;
|
||||||
|
|
||||||
|
@ -159,11 +167,13 @@ export function createDataLoadingThunk<
|
||||||
Returned,
|
Returned,
|
||||||
>(
|
>(
|
||||||
name: string,
|
name: string,
|
||||||
loadData: (args: Args) => Promise<LoadDataResult>,
|
loadData: LoadData<Args, LoadDataResult>,
|
||||||
onDataOrThunkOptions?: AppThunkOptions | OnData<LoadDataResult, Returned>,
|
onDataOrThunkOptions?:
|
||||||
|
| AppThunkOptions
|
||||||
|
| OnData<Args, LoadDataResult, Returned>,
|
||||||
maybeThunkOptions?: AppThunkOptions,
|
maybeThunkOptions?: AppThunkOptions,
|
||||||
) {
|
) {
|
||||||
let onData: OnData<LoadDataResult, Returned> | undefined;
|
let onData: OnData<Args, LoadDataResult, Returned> | undefined;
|
||||||
let thunkOptions: AppThunkOptions | undefined;
|
let thunkOptions: AppThunkOptions | undefined;
|
||||||
|
|
||||||
if (typeof onDataOrThunkOptions === 'function') onData = onDataOrThunkOptions;
|
if (typeof onDataOrThunkOptions === 'function') onData = onDataOrThunkOptions;
|
||||||
|
@ -177,7 +187,10 @@ export function createDataLoadingThunk<
|
||||||
return createThunk<Args, Returned>(
|
return createThunk<Args, Returned>(
|
||||||
name,
|
name,
|
||||||
async (arg, { getState, dispatch }) => {
|
async (arg, { getState, dispatch }) => {
|
||||||
const data = await loadData(arg);
|
const data = await loadData(arg, {
|
||||||
|
dispatch,
|
||||||
|
getState,
|
||||||
|
});
|
||||||
|
|
||||||
if (!onData) return data as Returned;
|
if (!onData) return data as Returned;
|
||||||
|
|
||||||
|
@ -185,6 +198,7 @@ export function createDataLoadingThunk<
|
||||||
dispatch,
|
dispatch,
|
||||||
getState,
|
getState,
|
||||||
discardLoadData: discardLoadDataInPayload,
|
discardLoadData: discardLoadDataInPayload,
|
||||||
|
actionArg: arg,
|
||||||
});
|
});
|
||||||
|
|
||||||
// if there is no return in `onData`, we return the `onData` result
|
// if there is no return in `onData`, we return the `onData` result
|
||||||
|
|
|
@ -22,12 +22,4 @@ class Admin::Metrics::Measure::ActiveUsersMeasure < Admin::Metrics::Measure::Bas
|
||||||
def activity_tracker
|
def activity_tracker
|
||||||
@activity_tracker ||= ActivityTracker.new('activity:logins', :unique)
|
@activity_tracker ||= ActivityTracker.new('activity:logins', :unique)
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_period
|
|
||||||
(@start_at.to_date..@end_at.to_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def previous_time_period
|
|
||||||
((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -86,11 +86,11 @@ class Admin::Metrics::Measure::BaseMeasure
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_period
|
def time_period
|
||||||
(@start_at..@end_at)
|
(@start_at.to_date..@end_at.to_date)
|
||||||
end
|
end
|
||||||
|
|
||||||
def previous_time_period
|
def previous_time_period
|
||||||
((@start_at - length_of_period)..(@end_at - length_of_period))
|
((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
|
||||||
end
|
end
|
||||||
|
|
||||||
def length_of_period
|
def length_of_period
|
||||||
|
|
|
@ -48,14 +48,6 @@ class Admin::Metrics::Measure::InstanceAccountsMeasure < Admin::Metrics::Measure
|
||||||
SQL
|
SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_period
|
|
||||||
(@start_at.to_date..@end_at.to_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def previous_time_period
|
|
||||||
((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
|
|
||||||
end
|
|
||||||
|
|
||||||
def params
|
def params
|
||||||
@params.permit(:domain, :include_subdomains)
|
@params.permit(:domain, :include_subdomains)
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,14 +49,6 @@ class Admin::Metrics::Measure::InstanceFollowersMeasure < Admin::Metrics::Measur
|
||||||
SQL
|
SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_period
|
|
||||||
(@start_at.to_date..@end_at.to_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def previous_time_period
|
|
||||||
((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
|
|
||||||
end
|
|
||||||
|
|
||||||
def params
|
def params
|
||||||
@params.permit(:domain, :include_subdomains)
|
@params.permit(:domain, :include_subdomains)
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,14 +49,6 @@ class Admin::Metrics::Measure::InstanceFollowsMeasure < Admin::Metrics::Measure:
|
||||||
SQL
|
SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_period
|
|
||||||
(@start_at.to_date..@end_at.to_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def previous_time_period
|
|
||||||
((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
|
|
||||||
end
|
|
||||||
|
|
||||||
def params
|
def params
|
||||||
@params.permit(:domain, :include_subdomains)
|
@params.permit(:domain, :include_subdomains)
|
||||||
end
|
end
|
||||||
|
|
|
@ -58,14 +58,6 @@ class Admin::Metrics::Measure::InstanceMediaAttachmentsMeasure < Admin::Metrics:
|
||||||
SQL
|
SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_period
|
|
||||||
(@start_at.to_date..@end_at.to_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def previous_time_period
|
|
||||||
((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
|
|
||||||
end
|
|
||||||
|
|
||||||
def params
|
def params
|
||||||
@params.permit(:domain, :include_subdomains)
|
@params.permit(:domain, :include_subdomains)
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,14 +49,6 @@ class Admin::Metrics::Measure::InstanceReportsMeasure < Admin::Metrics::Measure:
|
||||||
SQL
|
SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_period
|
|
||||||
(@start_at.to_date..@end_at.to_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def previous_time_period
|
|
||||||
((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
|
|
||||||
end
|
|
||||||
|
|
||||||
def params
|
def params
|
||||||
@params.permit(:domain, :include_subdomains)
|
@params.permit(:domain, :include_subdomains)
|
||||||
end
|
end
|
||||||
|
|
|
@ -58,14 +58,6 @@ class Admin::Metrics::Measure::InstanceStatusesMeasure < Admin::Metrics::Measure
|
||||||
Mastodon::Snowflake.id_at(@end_at.end_of_day, with_random: false)
|
Mastodon::Snowflake.id_at(@end_at.end_of_day, with_random: false)
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_period
|
|
||||||
(@start_at.to_date..@end_at.to_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def previous_time_period
|
|
||||||
((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
|
|
||||||
end
|
|
||||||
|
|
||||||
def params
|
def params
|
||||||
@params.permit(:domain, :include_subdomains)
|
@params.permit(:domain, :include_subdomains)
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,12 +22,4 @@ class Admin::Metrics::Measure::InteractionsMeasure < Admin::Metrics::Measure::Ba
|
||||||
def activity_tracker
|
def activity_tracker
|
||||||
@activity_tracker ||= ActivityTracker.new('activity:interactions', :basic)
|
@activity_tracker ||= ActivityTracker.new('activity:interactions', :basic)
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_period
|
|
||||||
(@start_at.to_date..@end_at.to_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def previous_time_period
|
|
||||||
((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -18,7 +18,7 @@ module Admin::Metrics::Measure::QueryHelper
|
||||||
def generated_series_days
|
def generated_series_days
|
||||||
Arel.sql(
|
Arel.sql(
|
||||||
<<~SQL.squish
|
<<~SQL.squish
|
||||||
SELECT generate_series(timestamp :start_at, :end_at, '1 day')::date AS period
|
SELECT generate_series(:start_at::timestamp, :end_at::timestamp, '1 day')::date AS period
|
||||||
SQL
|
SQL
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,14 +27,6 @@ class Admin::Metrics::Measure::TagAccountsMeasure < Admin::Metrics::Measure::Bas
|
||||||
@tag ||= Tag.find(params[:id])
|
@tag ||= Tag.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_period
|
|
||||||
(@start_at.to_date..@end_at.to_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def previous_time_period
|
|
||||||
((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
|
|
||||||
end
|
|
||||||
|
|
||||||
def params
|
def params
|
||||||
@params.permit(:id)
|
@params.permit(:id)
|
||||||
end
|
end
|
||||||
|
|
|
@ -27,14 +27,6 @@ class Admin::Metrics::Measure::TagUsesMeasure < Admin::Metrics::Measure::BaseMea
|
||||||
@tag ||= Tag.find(params[:id])
|
@tag ||= Tag.find(params[:id])
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_period
|
|
||||||
(@start_at.to_date..@end_at.to_date)
|
|
||||||
end
|
|
||||||
|
|
||||||
def previous_time_period
|
|
||||||
((@start_at.to_date - length_of_period)..(@end_at.to_date - length_of_period))
|
|
||||||
end
|
|
||||||
|
|
||||||
def params
|
def params
|
||||||
@params.permit(:id)
|
@params.permit(:id)
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,13 +2,8 @@
|
||||||
|
|
||||||
class CacheBuster
|
class CacheBuster
|
||||||
def initialize(options = {})
|
def initialize(options = {})
|
||||||
Rails.application.deprecators[:mastodon].warn('Default values for the cache buster secret header name and values will be removed in Mastodon 4.3. Please set them explicitely if you rely on those.') unless options[:http_method] || (options[:secret] && options[:secret_header])
|
@secret_header = options[:secret_header]
|
||||||
|
@secret = options[:secret]
|
||||||
@secret_header = options[:secret_header] ||
|
|
||||||
(options[:http_method] ? nil : 'Secret-Header')
|
|
||||||
@secret = options[:secret] ||
|
|
||||||
(options[:http_method] ? nil : 'True')
|
|
||||||
|
|
||||||
@http_method = options[:http_method] || 'GET'
|
@http_method = options[:http_method] || 'GET'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -86,10 +86,6 @@ module Extractor
|
||||||
possible_entries
|
possible_entries
|
||||||
end
|
end
|
||||||
|
|
||||||
def extract_cashtags_with_indices(_text)
|
|
||||||
[]
|
|
||||||
end
|
|
||||||
|
|
||||||
def extract_extra_uris_with_indices(text)
|
def extract_extra_uris_with_indices(text)
|
||||||
return [] unless text&.index(':')
|
return [] unless text&.index(':')
|
||||||
|
|
||||||
|
|
|
@ -269,16 +269,21 @@ class LinkDetailsExtractor
|
||||||
end
|
end
|
||||||
|
|
||||||
def document
|
def document
|
||||||
@document ||= Nokogiri::HTML(@html, nil, encoding)
|
@document ||= detect_encoding_and_parse_document
|
||||||
end
|
end
|
||||||
|
|
||||||
def encoding
|
def detect_encoding_and_parse_document
|
||||||
@encoding ||= begin
|
[detect_encoding, nil, @html_charset, 'UTF-8'].uniq.each do |encoding|
|
||||||
guess = detector.detect(@html, @html_charset)
|
document = Nokogiri::HTML(@html, nil, encoding)
|
||||||
guess&.fetch(:confidence, 0).to_i > 60 ? guess&.fetch(:encoding, nil) : nil
|
return document if document.to_s.valid_encoding?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def detect_encoding
|
||||||
|
guess = detector.detect(@html, @html_charset)
|
||||||
|
guess&.fetch(:confidence, 0).to_i > 60 ? guess&.fetch(:encoding, nil) : nil
|
||||||
|
end
|
||||||
|
|
||||||
def detector
|
def detector
|
||||||
@detector ||= CharlockHolmes::EncodingDetector.new.tap do |detector|
|
@detector ||= CharlockHolmes::EncodingDetector.new.tap do |detector|
|
||||||
detector.strip_tags = true
|
detector.strip_tags = true
|
||||||
|
|
|
@ -3,13 +3,16 @@
|
||||||
class NotificationGroup < ActiveModelSerializers::Model
|
class NotificationGroup < ActiveModelSerializers::Model
|
||||||
attributes :group_key, :sample_accounts, :notifications_count, :notification, :most_recent_notification_id
|
attributes :group_key, :sample_accounts, :notifications_count, :notification, :most_recent_notification_id
|
||||||
|
|
||||||
def self.from_notification(notification)
|
def self.from_notification(notification, max_id: nil)
|
||||||
if notification.group_key.present?
|
if notification.group_key.present?
|
||||||
# TODO: caching and preloading
|
# TODO: caching and preloading
|
||||||
most_recent_notifications = notification.account.notifications.where(group_key: notification.group_key).order(id: :desc).take(3)
|
scope = notification.account.notifications.where(group_key: notification.group_key)
|
||||||
|
scope = scope.where(id: ..max_id) if max_id.present?
|
||||||
|
|
||||||
|
most_recent_notifications = scope.order(id: :desc).take(3)
|
||||||
most_recent_id = most_recent_notifications.first.id
|
most_recent_id = most_recent_notifications.first.id
|
||||||
sample_accounts = most_recent_notifications.map(&:from_account)
|
sample_accounts = most_recent_notifications.map(&:from_account)
|
||||||
notifications_count = notification.account.notifications.where(group_key: notification.group_key).count
|
notifications_count = scope.count
|
||||||
else
|
else
|
||||||
most_recent_id = notification.id
|
most_recent_id = notification.id
|
||||||
sample_accounts = [notification.from_account]
|
sample_accounts = [notification.from_account]
|
||||||
|
@ -29,5 +32,6 @@ class NotificationGroup < ActiveModelSerializers::Model
|
||||||
:target_status,
|
:target_status,
|
||||||
:report,
|
:report,
|
||||||
:account_relationship_severance_event,
|
:account_relationship_severance_event,
|
||||||
|
:account_warning,
|
||||||
to: :notification, prefix: false
|
to: :notification, prefix: false
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
class ActivityPub::OutboxSerializer < ActivityPub::CollectionSerializer
|
class ActivityPub::OutboxSerializer < ActivityPub::CollectionSerializer
|
||||||
def self.serializer_for(model, options)
|
def self.serializer_for(model, options)
|
||||||
if model.class.name == 'ActivityPub::ActivityPresenter'
|
if model.instance_of?(::ActivityPub::ActivityPresenter)
|
||||||
ActivityPub::ActivitySerializer
|
ActivityPub::ActivitySerializer
|
||||||
else
|
else
|
||||||
super
|
super
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class REST::NotificationPolicySerializer < ActiveModel::Serializer
|
class REST::NotificationPolicySerializer < ActiveModel::Serializer
|
||||||
|
# Please update `app/javascript/mastodon/api_types/notification_policies.ts` when making changes to the attributes
|
||||||
|
|
||||||
attributes :filter_not_following,
|
attributes :filter_not_following,
|
||||||
:filter_not_followers,
|
:filter_not_followers,
|
||||||
:filter_new_accounts,
|
:filter_new_accounts,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class REST::NotificationSerializer < ActiveModel::Serializer
|
class REST::NotificationSerializer < ActiveModel::Serializer
|
||||||
attributes :id, :type, :created_at
|
attributes :id, :type, :created_at, :group_key
|
||||||
|
|
||||||
belongs_to :from_account, key: :account, serializer: REST::AccountSerializer
|
belongs_to :from_account, key: :account, serializer: REST::AccountSerializer
|
||||||
belongs_to :target_status, key: :status, if: :status_type?, serializer: REST::StatusSerializer
|
belongs_to :target_status, key: :status, if: :status_type?, serializer: REST::StatusSerializer
|
||||||
|
@ -15,6 +15,10 @@ class REST::NotificationSerializer < ActiveModel::Serializer
|
||||||
object.id.to_s
|
object.id.to_s
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def group_key
|
||||||
|
object.group_key || "ungrouped-#{object.id}"
|
||||||
|
end
|
||||||
|
|
||||||
def status_type?
|
def status_type?
|
||||||
[:favourite, :emoji_reaction, :reaction, :reblog, :status_reference, :status, :list_status, :mention, :poll, :update].include?(object.type)
|
[:favourite, :emoji_reaction, :reaction, :reblog, :status_reference, :status, :list_status, :mention, :poll, :update].include?(object.type)
|
||||||
end
|
end
|
||||||
|
|
|
@ -49,6 +49,7 @@ require_relative '../lib/webpacker/manifest_extensions'
|
||||||
require_relative '../lib/webpacker/helper_extensions'
|
require_relative '../lib/webpacker/helper_extensions'
|
||||||
require_relative '../lib/rails/engine_extensions'
|
require_relative '../lib/rails/engine_extensions'
|
||||||
require_relative '../lib/action_dispatch/remote_ip_extensions'
|
require_relative '../lib/action_dispatch/remote_ip_extensions'
|
||||||
|
require_relative '../lib/stoplight/redis_data_store_extensions'
|
||||||
require_relative '../lib/active_record/database_tasks_extensions'
|
require_relative '../lib/active_record/database_tasks_extensions'
|
||||||
require_relative '../lib/active_record/batches'
|
require_relative '../lib/active_record/batches'
|
||||||
require_relative '../lib/active_record/with_recursive'
|
require_relative '../lib/active_record/with_recursive'
|
||||||
|
|
|
@ -135,6 +135,7 @@ et:
|
||||||
media: Lisatud meedia
|
media: Lisatud meedia
|
||||||
mutes: Vaigistused
|
mutes: Vaigistused
|
||||||
notifications: Teavitused
|
notifications: Teavitused
|
||||||
|
profile: Sinu Mastodoni profiil
|
||||||
push: Tõuketeated
|
push: Tõuketeated
|
||||||
reports: Teavitused
|
reports: Teavitused
|
||||||
search: Otsing
|
search: Otsing
|
||||||
|
@ -165,6 +166,7 @@ et:
|
||||||
admin:write:reports: teostada moderaatori tegevusi teavitustel
|
admin:write:reports: teostada moderaatori tegevusi teavitustel
|
||||||
crypto: kasuta otspunktkrüpeerimist
|
crypto: kasuta otspunktkrüpeerimist
|
||||||
follow: muuta kontode suhteid
|
follow: muuta kontode suhteid
|
||||||
|
profile: loe vaid oma konto profiili infot
|
||||||
push: saab tõuketeateid
|
push: saab tõuketeateid
|
||||||
read: lugeda konto kõiki andmeid
|
read: lugeda konto kõiki andmeid
|
||||||
read:accounts: näha konto informatsiooni
|
read:accounts: näha konto informatsiooni
|
||||||
|
|
|
@ -285,6 +285,7 @@ et:
|
||||||
update_custom_emoji_html: "%{name} uuendas emotikoni %{target}"
|
update_custom_emoji_html: "%{name} uuendas emotikoni %{target}"
|
||||||
update_domain_block_html: "%{name} uuendas domeeni %{target} keeldu"
|
update_domain_block_html: "%{name} uuendas domeeni %{target} keeldu"
|
||||||
update_ip_block_html: "%{name} muutis IP-aadressi %{target} reeglit"
|
update_ip_block_html: "%{name} muutis IP-aadressi %{target} reeglit"
|
||||||
|
update_report_html: "%{name} uuendas raportit %{target}"
|
||||||
update_status_html: "%{name} muutis %{target} postitust"
|
update_status_html: "%{name} muutis %{target} postitust"
|
||||||
update_user_role_html: "%{name} muutis %{target} rolli"
|
update_user_role_html: "%{name} muutis %{target} rolli"
|
||||||
deleted_account: kustutatud konto
|
deleted_account: kustutatud konto
|
||||||
|
@ -292,6 +293,7 @@ et:
|
||||||
filter_by_action: Filtreeri tegevuse järgi
|
filter_by_action: Filtreeri tegevuse järgi
|
||||||
filter_by_user: Filtreeri kasutaja järgi
|
filter_by_user: Filtreeri kasutaja järgi
|
||||||
title: Auditilogi
|
title: Auditilogi
|
||||||
|
unavailable_instance: "(domeeni nimi pole saadaval)"
|
||||||
announcements:
|
announcements:
|
||||||
destroyed_msg: Teadaande kustutamine õnnestus!
|
destroyed_msg: Teadaande kustutamine õnnestus!
|
||||||
edit:
|
edit:
|
||||||
|
@ -751,6 +753,7 @@ et:
|
||||||
desc_html: See tugineb välistele hCaptcha skriptidele, mis võib olla turvalisuse ja privaatsuse probleem. Lisaks <strong>võib see muuta registreerimisprotsessi mõnede inimeste (eriti puudega inimeste) jaoks, oluliselt vähem ligipääsetavaks.</strong> Neil põhjustel kaalu palun teisi võimalusi, näiteks kinnitamis- või kutsepõhiseid registreerimislahendusi.
|
desc_html: See tugineb välistele hCaptcha skriptidele, mis võib olla turvalisuse ja privaatsuse probleem. Lisaks <strong>võib see muuta registreerimisprotsessi mõnede inimeste (eriti puudega inimeste) jaoks, oluliselt vähem ligipääsetavaks.</strong> Neil põhjustel kaalu palun teisi võimalusi, näiteks kinnitamis- või kutsepõhiseid registreerimislahendusi.
|
||||||
title: Nõua uutelt kasutajatelt konto kinnitamiseks CAPTCHA lahendamist
|
title: Nõua uutelt kasutajatelt konto kinnitamiseks CAPTCHA lahendamist
|
||||||
content_retention:
|
content_retention:
|
||||||
|
danger_zone: Ohutsoon
|
||||||
preamble: Määra, kuidas kasutajate loodud sisu Mastodonis talletatakse.
|
preamble: Määra, kuidas kasutajate loodud sisu Mastodonis talletatakse.
|
||||||
title: Sisu talletamine
|
title: Sisu talletamine
|
||||||
default_noindex:
|
default_noindex:
|
||||||
|
@ -770,7 +773,7 @@ et:
|
||||||
disabled: Mitte kellelegi
|
disabled: Mitte kellelegi
|
||||||
users: Sisseloginud kohalikele kasutajatele
|
users: Sisseloginud kohalikele kasutajatele
|
||||||
registrations:
|
registrations:
|
||||||
moderation_recommandation: Enne registreeringute avamist kõigile veendu, et oleks olemas adekvaatne ja reageerimisvalmis modereerijaskond!
|
moderation_recommandation: Enne kõigi jaoks registreerimise avamist veendu, et oleks olemas adekvaatne ja reageerimisvalmis modereerijaskond!
|
||||||
preamble: Kes saab serveril konto luua.
|
preamble: Kes saab serveril konto luua.
|
||||||
title: Registreerimised
|
title: Registreerimised
|
||||||
registrations_mode:
|
registrations_mode:
|
||||||
|
@ -791,7 +794,7 @@ et:
|
||||||
software_updates:
|
software_updates:
|
||||||
critical_update: Kriitiline — uuenda kiiresti
|
critical_update: Kriitiline — uuenda kiiresti
|
||||||
description: On soovitav hoida oma Mastodoni paigaldus kõige uuemal kujul, et saada kasu kõige värskematest parandustest ja oskustest. Lisaks, vahel on Mastodoni kiire uuendamine kriitiline, et vältida turvaprobleeme. Neil põhjustel kontrollib Mastodon uuendusi iga 30 minuti tagant ja teavitab sind vastavalt su e-posti teavituste eelistustele.
|
description: On soovitav hoida oma Mastodoni paigaldus kõige uuemal kujul, et saada kasu kõige värskematest parandustest ja oskustest. Lisaks, vahel on Mastodoni kiire uuendamine kriitiline, et vältida turvaprobleeme. Neil põhjustel kontrollib Mastodon uuendusi iga 30 minuti tagant ja teavitab sind vastavalt su e-posti teavituste eelistustele.
|
||||||
documentation_link: Saa rohkem teada
|
documentation_link: Vaata lisa
|
||||||
release_notes: Väljalaskemärkused
|
release_notes: Väljalaskemärkused
|
||||||
title: Saadaval uuendused
|
title: Saadaval uuendused
|
||||||
type: Tüüp
|
type: Tüüp
|
||||||
|
@ -949,6 +952,7 @@ et:
|
||||||
delete: Kustuta
|
delete: Kustuta
|
||||||
edit_preset: Hoiatuse eelseadistuse muutmine
|
edit_preset: Hoiatuse eelseadistuse muutmine
|
||||||
empty: Hoiatuste eelseadeid pole defineeritud.
|
empty: Hoiatuste eelseadeid pole defineeritud.
|
||||||
|
title: Hoiatuste eelhäälestused
|
||||||
webhooks:
|
webhooks:
|
||||||
add_new: Lisa lõpp-punkt
|
add_new: Lisa lõpp-punkt
|
||||||
delete: Kustuta
|
delete: Kustuta
|
||||||
|
@ -1814,8 +1818,8 @@ et:
|
||||||
title: Arhiivi väljavõte
|
title: Arhiivi väljavõte
|
||||||
failed_2fa:
|
failed_2fa:
|
||||||
details: 'Sisenemise üksikasjad:'
|
details: 'Sisenemise üksikasjad:'
|
||||||
explanation: Keegi püüdis Su kontole siseneda, ent sisestas vale teisese autentimisfaktori.
|
explanation: Keegi püüdis Su kontole siseneda, ent sisestas vale kaheastmelise autentimise faktori.
|
||||||
further_actions_html: Kui see polnud Sina, siis soovitame viivitamata %{action}, kuna see võib olla lekkinud.
|
further_actions_html: Kui see polnud Sina, siis soovitame viivitamata %{action}, kuna see võib olla ohus.
|
||||||
subject: Kaheastmelise autentimise nurjumine
|
subject: Kaheastmelise autentimise nurjumine
|
||||||
title: Kaheastmeline autentimine nurjus
|
title: Kaheastmeline autentimine nurjus
|
||||||
suspicious_sign_in:
|
suspicious_sign_in:
|
||||||
|
@ -1857,9 +1861,9 @@ et:
|
||||||
silence: Konto limiteeritud
|
silence: Konto limiteeritud
|
||||||
suspend: Konto kustutatud
|
suspend: Konto kustutatud
|
||||||
welcome:
|
welcome:
|
||||||
apps_android_action: Google Play poest
|
apps_android_action: Laadi see Google Playst
|
||||||
apps_ios_action: Allalaadimine App Store'ist
|
apps_ios_action: Allalaadimine App Store'ist
|
||||||
apps_step: Meie ametlikud rakendused.
|
apps_step: Laadi meie ametlikud rakendused.
|
||||||
apps_title: Mastodoni rakendused
|
apps_title: Mastodoni rakendused
|
||||||
checklist_subtitle: 'Kuidas sel uudsel sotsiaalmeediarindel pihta hakata:'
|
checklist_subtitle: 'Kuidas sel uudsel sotsiaalmeediarindel pihta hakata:'
|
||||||
checklist_title: Millest alustada
|
checklist_title: Millest alustada
|
||||||
|
@ -1872,7 +1876,7 @@ et:
|
||||||
feature_audience_title: Kogu enesekindlalt jälgijaid
|
feature_audience_title: Kogu enesekindlalt jälgijaid
|
||||||
feature_control: Tead ise kõige paremini, mida soovid oma koduvoos näha. Ei aega raiskavaid algoritme ega reklaame. Jälgi ühe kasutajakonto kaudu keda iganes mistahes Mastodoni serveris ja näe postitusi ajalises järjestuses, muutes oma nurgakese Internetist rohkem endale meelepärasemaks.
|
feature_control: Tead ise kõige paremini, mida soovid oma koduvoos näha. Ei aega raiskavaid algoritme ega reklaame. Jälgi ühe kasutajakonto kaudu keda iganes mistahes Mastodoni serveris ja näe postitusi ajalises järjestuses, muutes oma nurgakese Internetist rohkem endale meelepärasemaks.
|
||||||
feature_control_title: Säilita oma ajajoone üle kontroll
|
feature_control_title: Säilita oma ajajoone üle kontroll
|
||||||
feature_creativity: Mastodon toetab audiot, video- ja pildipostitusi, liigipääsetavuse kirjeldusi, küsitlusi, sisuhoiatusi, animeeritud avatare, kohandatud emotikone, pisipiltide lõikeeelistusi ja enamatki, et end võrgus väljendada. Kas avaldad kunsti, muusikat või taskuhäälingusaadet, Mastodon on mõeldud Sinu jaoks.
|
feature_creativity: Mastodon toetab audiot, video- ja pildipostitusi, ligipääsetavuse kirjeldusi, küsitlusi, sisuhoiatusi, animeeritud avatare, kohandatud emotikone, pisipiltide lõikeeelistusi ja enamatki, et end võrgus väljendada. Kas avaldad kunsti, muusikat või taskuhäälingut, Mastodon on mõeldud Sinu jaoks.
|
||||||
feature_creativity_title: Võrreldamatu loovus
|
feature_creativity_title: Võrreldamatu loovus
|
||||||
feature_moderation: Mastodon annab otsustusõiguse tagasi Sinu kätte. Igal serveril on oma reeglid ja regulatsioonid, mida hallatakse kohapeal, mitte nagu ülalt-alla korporatiivses sotsiaalmeedias, võimaldades enim paindlikku vastavust erinevate vajadustega gruppide ja inimeste eelistustele. Liitu sobivate reeglitega serveriga, või käivita oma server.
|
feature_moderation: Mastodon annab otsustusõiguse tagasi Sinu kätte. Igal serveril on oma reeglid ja regulatsioonid, mida hallatakse kohapeal, mitte nagu ülalt-alla korporatiivses sotsiaalmeedias, võimaldades enim paindlikku vastavust erinevate vajadustega gruppide ja inimeste eelistustele. Liitu sobivate reeglitega serveriga, või käivita oma server.
|
||||||
feature_moderation_title: Modereerimine, nagu see olema peab
|
feature_moderation_title: Modereerimine, nagu see olema peab
|
||||||
|
|
|
@ -77,10 +77,15 @@ et:
|
||||||
warn: Varja filtreeritud sisu hoiatusega, nimetades filtri pealkirja
|
warn: Varja filtreeritud sisu hoiatusega, nimetades filtri pealkirja
|
||||||
form_admin_settings:
|
form_admin_settings:
|
||||||
activity_api_enabled: Kohalike postituste, aktiivsete kasutajate ja uute registreerumistr arv nädala kaupa grupeeritult
|
activity_api_enabled: Kohalike postituste, aktiivsete kasutajate ja uute registreerumistr arv nädala kaupa grupeeritult
|
||||||
|
app_icon: WEBP, PNG, GIF või JPG. Asendab mobiilsel seadmel äpi vaikeikooni kohandatud ikooniga.
|
||||||
|
backups_retention_period: Kasutajatel on võimalus genereerida oma postitustest hiljem allalaaditav arhiiv. Kui määrata positiivne arv, kustutatakse serveri talletusruumist need arhiivid määratud arvu päevade järel automaatselt.
|
||||||
bootstrap_timeline_accounts: Need kasutajad kinnitatakse uute kasutajate jälgimissoovituste esiritta.
|
bootstrap_timeline_accounts: Need kasutajad kinnitatakse uute kasutajate jälgimissoovituste esiritta.
|
||||||
closed_registrations_message: Kuvatakse, kui liitumised pole võimalikud
|
closed_registrations_message: Kuvatakse, kui liitumised pole võimalikud
|
||||||
custom_css: Kohandatud stiile on võimalik kasutada Mastodoni veebiliideses.
|
content_cache_retention_period: Kõik teiste serverite postitused (sealhulgas jagamised ja vastused) kustutatakse pärast määratud arvu päevade möödumist, sõltumata, kuidas kohalik kasutaja on nende postitustega interakteerunud. Hõlmatud on ka postitused, mille kohalik kasutaja on märkinud järjehoidjaks või lemmikuks. Ka eri instantside kasutajate vahelised privaatsed mainimised kaovad ja neid on võimatu taastada. See seadistus on mõeldud eriotstarbeliste instantside jaoks ja rikub paljude kasutajate ootusi, kui seda rakendatakse üldotstarbelise kasutuse puhul.
|
||||||
|
custom_css: Mastodoni veebiliideses on võimalik kasutada kohandatud stiile.
|
||||||
|
favicon: WEBP, PNG, GIF või JPG. Asendab Mastodoni vaike- favicon ikooni kohandatud ikooniga.
|
||||||
mascot: Asendab kohandatud veebiliidese illustratsiooni.
|
mascot: Asendab kohandatud veebiliidese illustratsiooni.
|
||||||
|
media_cache_retention_period: Kaugkasutajate tehtud postituste meediafailid salvestatakse teie serveri vahemällu. Kui see seadistus on seatud positiivsele väärtusele, kustutatakse meediumifailid määratud päevade möödumisel. Kui meediaandmeid küsitakse pärast nende kustutamist, laaditakse need uuesti alla, kui lähtesisu on veel saadaval. Kuna on olemas piirangud, kui tihti tohivad lingikaardid kolmandatelt saitidelt andmeid pärida, on soovitatav määrata väärtuseks vähemalt 14. Vastasel juhul ei uuendata linkide eelvaatekaarte nõudmise korral enne seda aega.
|
||||||
peers_api_enabled: Domeeninimede loetelu, mida see server on Fediversumis kohanud. Mitte mingeid andmeid selle serveri födereerumise kohta antud serverite pole, vaid üksnes info, et sellest serverist ollakse teadlik. Seda kasutavad teenused, mis koguvad üldist födereerumise statistikat.
|
peers_api_enabled: Domeeninimede loetelu, mida see server on Fediversumis kohanud. Mitte mingeid andmeid selle serveri födereerumise kohta antud serverite pole, vaid üksnes info, et sellest serverist ollakse teadlik. Seda kasutavad teenused, mis koguvad üldist födereerumise statistikat.
|
||||||
profile_directory: Kasutajate kataloog kuvab nimekirja kasutajatest, kes on seda lubanud.
|
profile_directory: Kasutajate kataloog kuvab nimekirja kasutajatest, kes on seda lubanud.
|
||||||
require_invite_text: Kui liitumisi on tarvis kinnitada, oleks "Miks soovid liituda?" vastus vajalik
|
require_invite_text: Kui liitumisi on tarvis kinnitada, oleks "Miks soovid liituda?" vastus vajalik
|
||||||
|
@ -240,6 +245,7 @@ et:
|
||||||
backups_retention_period: Kasutajate arhiivi talletusperiood
|
backups_retention_period: Kasutajate arhiivi talletusperiood
|
||||||
bootstrap_timeline_accounts: Alati soovita neid kontosid uutele kasutajatele
|
bootstrap_timeline_accounts: Alati soovita neid kontosid uutele kasutajatele
|
||||||
closed_registrations_message: Kohandatud teade, kui liitumine pole võimalik
|
closed_registrations_message: Kohandatud teade, kui liitumine pole võimalik
|
||||||
|
content_cache_retention_period: Kaugsisu säilitamise aeg
|
||||||
custom_css: Kohandatud CSS
|
custom_css: Kohandatud CSS
|
||||||
mascot: Kohandatud maskott (kunagine)
|
mascot: Kohandatud maskott (kunagine)
|
||||||
media_cache_retention_period: Meediapuhvri talletusperiood
|
media_cache_retention_period: Meediapuhvri talletusperiood
|
||||||
|
|
|
@ -293,6 +293,7 @@ sv:
|
||||||
filter_by_action: Filtrera efter åtgärd
|
filter_by_action: Filtrera efter åtgärd
|
||||||
filter_by_user: Filtrera efter användare
|
filter_by_user: Filtrera efter användare
|
||||||
title: Revisionslogg
|
title: Revisionslogg
|
||||||
|
unavailable_instance: "(domännamn inte tillgängligt)"
|
||||||
announcements:
|
announcements:
|
||||||
destroyed_msg: Kungörelsen raderades!
|
destroyed_msg: Kungörelsen raderades!
|
||||||
edit:
|
edit:
|
||||||
|
|
|
@ -1791,8 +1791,8 @@ vi:
|
||||||
suspicious_sign_in:
|
suspicious_sign_in:
|
||||||
change_password: đổi mật khẩu của bạn
|
change_password: đổi mật khẩu của bạn
|
||||||
details: 'Chi tiết thông tin đăng nhập:'
|
details: 'Chi tiết thông tin đăng nhập:'
|
||||||
explanation: Chúng tôi phát hiện lần đăng nhập bất thường tài khoản của bạn từ một địa chỉ IP mới.
|
explanation: Chúng tôi phát hiện tài khoản của bạn đăng nhập bất thường từ một địa chỉ IP mới.
|
||||||
further_actions_html: Nếu đó không phải là bạn, chúng tôi khuyến nghị %{action} lập tức và bật xác minh hai bước để giữ tài khoản được an toàn.
|
further_actions_html: Nếu đây không phải là bạn, hãy %{action} lập tức và bật xác minh hai bước để giữ tài khoản được an toàn.
|
||||||
subject: Đăng nhập tài khoản từ địa chỉ IP mới
|
subject: Đăng nhập tài khoản từ địa chỉ IP mới
|
||||||
title: Lần đăng nhập mới
|
title: Lần đăng nhập mới
|
||||||
warning:
|
warning:
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
This privacy policy describes how %{domain}s ("%{domain}s", "we", "us")
|
This privacy policy describes how %{domain} ("%{domain}", "we", "us") collects,
|
||||||
collects, protects and uses the personally identifiable information you may
|
protects and uses the personally identifiable information you may provide
|
||||||
provide through the %{domain}s website or its API. The policy also
|
through the %{domain} website or its API. The policy also describes the choices
|
||||||
describes the choices available to you regarding our use of your personal
|
available to you regarding our use of your personal information and how you can
|
||||||
information and how you can access and update this information. This policy
|
access and update this information. This policy does not apply to the practices
|
||||||
does not apply to the practices of companies that %{domain}s does not own
|
of companies that %{domain} does not own or control, or to individuals that
|
||||||
or control, or to individuals that %{domain}s does not employ or manage.
|
%{domain} does not employ or manage.
|
||||||
|
|
||||||
# What information do we collect?
|
# What information do we collect?
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddAttachmentAvatarToAccounts < ActiveRecord::Migration[4.2]
|
class AddAttachmentAvatarToAccounts < ActiveRecord::Migration[4.2]
|
||||||
def self.up
|
def up
|
||||||
change_table :accounts do |t|
|
change_table :accounts do |t|
|
||||||
# The following corresponds to `t.attachment :avatar` in an older version of Paperclip
|
# The following corresponds to `t.attachment :avatar` in an older version of Paperclip
|
||||||
t.string :avatar_file_name
|
t.string :avatar_file_name
|
||||||
|
@ -11,7 +11,7 @@ class AddAttachmentAvatarToAccounts < ActiveRecord::Migration[4.2]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
def down
|
||||||
remove_attachment :accounts, :avatar
|
remove_attachment :accounts, :avatar
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddDeviseToUsers < ActiveRecord::Migration[4.2]
|
class AddDeviseToUsers < ActiveRecord::Migration[4.2]
|
||||||
def self.up
|
def up
|
||||||
change_table(:users, bulk: true) do |t|
|
change_table(:users, bulk: true) do |t|
|
||||||
## Database authenticatable
|
## Database authenticatable
|
||||||
t.string :encrypted_password, null: false, default: ''
|
t.string :encrypted_password, null: false, default: ''
|
||||||
|
@ -24,7 +24,7 @@ class AddDeviseToUsers < ActiveRecord::Migration[4.2]
|
||||||
add_index :users, :reset_password_token, unique: true
|
add_index :users, :reset_password_token, unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
def down
|
||||||
remove_index :users, :reset_password_token
|
remove_index :users, :reset_password_token
|
||||||
|
|
||||||
remove_column :users, :encrypted_password
|
remove_column :users, :encrypted_password
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddAttachmentHeaderToAccounts < ActiveRecord::Migration[4.2]
|
class AddAttachmentHeaderToAccounts < ActiveRecord::Migration[4.2]
|
||||||
def self.up
|
def up
|
||||||
change_table :accounts do |t|
|
change_table :accounts do |t|
|
||||||
# The following corresponds to `t.attachment :header` in an older version of Paperclip
|
# The following corresponds to `t.attachment :header` in an older version of Paperclip
|
||||||
t.string :header_file_name
|
t.string :header_file_name
|
||||||
|
@ -11,7 +11,7 @@ class AddAttachmentHeaderToAccounts < ActiveRecord::Migration[4.2]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
def down
|
||||||
remove_attachment :accounts, :header
|
remove_attachment :accounts, :header
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class RailsSettingsMigration < ActiveRecord::Migration[5.0]
|
class RailsSettingsMigration < ActiveRecord::Migration[5.0]
|
||||||
def self.up
|
def up
|
||||||
create_table :settings do |t|
|
create_table :settings do |t|
|
||||||
t.string :var, null: false
|
t.string :var, null: false
|
||||||
t.text :value
|
t.text :value
|
||||||
|
@ -11,7 +11,7 @@ class RailsSettingsMigration < ActiveRecord::Migration[5.0]
|
||||||
add_index :settings, [:target_type, :target_id, :var], unique: true
|
add_index :settings, [:target_type, :target_id, :var], unique: true
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
def down
|
||||||
drop_table :settings
|
drop_table :settings
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class AddAttachmentDataToImports < ActiveRecord::Migration[4.2]
|
class AddAttachmentDataToImports < ActiveRecord::Migration[4.2]
|
||||||
def self.up
|
def up
|
||||||
change_table :imports do |t|
|
change_table :imports do |t|
|
||||||
# The following corresponds to `t.attachment :data` in an older version of Paperclip
|
# The following corresponds to `t.attachment :data` in an older version of Paperclip
|
||||||
t.string :data_file_name
|
t.string :data_file_name
|
||||||
|
@ -11,7 +11,7 @@ class AddAttachmentDataToImports < ActiveRecord::Migration[4.2]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.down
|
def down
|
||||||
remove_attachment :imports, :data
|
remove_attachment :imports, :data
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
17
lib/stoplight/redis_data_store_extensions.rb
Normal file
17
lib/stoplight/redis_data_store_extensions.rb
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Restore compatibility with Redis < 6.2
|
||||||
|
|
||||||
|
module Stoplight
|
||||||
|
module DataStore
|
||||||
|
module RedisExtensions
|
||||||
|
def query_failures(light, transaction: @redis)
|
||||||
|
window_start = Time.now.to_i - light.window_size
|
||||||
|
|
||||||
|
transaction.zrevrangebyscore(failures_key(light), Float::INFINITY, window_start)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Stoplight::DataStore::Redis.prepend(Stoplight::DataStore::RedisExtensions)
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@mastodon/mastodon",
|
"name": "@mastodon/mastodon",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"packageManager": "yarn@4.3.0",
|
"packageManager": "yarn@4.3.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
|
|
17
spec/fixtures/requests/low_confidence_latin1.txt
vendored
Normal file
17
spec/fixtures/requests/low_confidence_latin1.txt
vendored
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
HTTP/1.1 200 OK
|
||||||
|
server: nginx
|
||||||
|
date: Thu, 13 Jun 2024 14:33:13 GMT
|
||||||
|
content-type: text/html; charset=ISO-8859-1
|
||||||
|
content-length: 158
|
||||||
|
accept-ranges: bytes
|
||||||
|
|
||||||
|
<!doctype html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>Tofu á l'orange</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h2>Tofu á l'orange</h2>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -28,14 +28,6 @@ describe CacheBuster do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when using default options' do
|
context 'when using default options' do
|
||||||
around do |example|
|
|
||||||
# Disables the CacheBuster.new deprecation warning about default arguments.
|
|
||||||
# Remove this `silence` block when default arg support is removed from CacheBuster
|
|
||||||
Rails.application.deprecators[:mastodon].silence do
|
|
||||||
example.run
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
include_examples 'makes_request'
|
include_examples 'makes_request'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -69,10 +69,10 @@ describe Extractor do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'extract_cashtags_with_indices' do
|
describe 'extract_entities_with_indices' do
|
||||||
it 'returns []' do
|
it 'returns empty array when cashtag present' do
|
||||||
text = '$cashtag'
|
text = '$cashtag'
|
||||||
extracted = described_class.extract_cashtags_with_indices(text)
|
extracted = described_class.extract_entities_with_indices(text)
|
||||||
expect(extracted).to eq []
|
expect(extracted).to eq []
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,11 +7,28 @@ describe 'Admin Measures' do
|
||||||
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
let(:token) { Fabricate(:accessible_access_token, resource_owner_id: user.id, scopes: scopes) }
|
||||||
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
let(:headers) { { 'Authorization' => "Bearer #{token.token}" } }
|
||||||
let(:account) { Fabricate(:account) }
|
let(:account) { Fabricate(:account) }
|
||||||
|
let(:params) do
|
||||||
|
{
|
||||||
|
keys: %w(instance_accounts instance_follows instance_followers),
|
||||||
|
instance_accounts: {
|
||||||
|
domain: 'mastodon.social',
|
||||||
|
include_subdomains: true,
|
||||||
|
},
|
||||||
|
instance_follows: {
|
||||||
|
domain: 'mastodon.social',
|
||||||
|
include_subdomains: true,
|
||||||
|
},
|
||||||
|
instance_followers: {
|
||||||
|
domain: 'mastodon.social',
|
||||||
|
include_subdomains: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
describe 'GET /api/v1/admin/measures' do
|
describe 'GET /api/v1/admin/measures' do
|
||||||
context 'when not authorized' do
|
context 'when not authorized' do
|
||||||
it 'returns http forbidden' do
|
it 'returns http forbidden' do
|
||||||
post '/api/v1/admin/measures', params: { account_id: account.id, limit: 2 }
|
post '/api/v1/admin/measures', params: params
|
||||||
|
|
||||||
expect(response)
|
expect(response)
|
||||||
.to have_http_status(403)
|
.to have_http_status(403)
|
||||||
|
@ -22,7 +39,7 @@ describe 'Admin Measures' do
|
||||||
let(:scopes) { 'admin:read' }
|
let(:scopes) { 'admin:read' }
|
||||||
|
|
||||||
it 'returns http success and status json' do
|
it 'returns http success and status json' do
|
||||||
post '/api/v1/admin/measures', params: { account_id: account.id, limit: 2 }, headers: headers
|
post '/api/v1/admin/measures', params: params, headers: headers
|
||||||
|
|
||||||
expect(response)
|
expect(response)
|
||||||
.to have_http_status(200)
|
.to have_http_status(200)
|
||||||
|
|
|
@ -28,6 +28,7 @@ RSpec.describe FetchLinkCardService do
|
||||||
stub_request(:get, 'http://example.com/sjis_with_wrong_charset').to_return(request_fixture('sjis_with_wrong_charset.txt'))
|
stub_request(:get, 'http://example.com/sjis_with_wrong_charset').to_return(request_fixture('sjis_with_wrong_charset.txt'))
|
||||||
stub_request(:get, 'http://example.com/koi8-r').to_return(request_fixture('koi8-r.txt'))
|
stub_request(:get, 'http://example.com/koi8-r').to_return(request_fixture('koi8-r.txt'))
|
||||||
stub_request(:get, 'http://example.com/windows-1251').to_return(request_fixture('windows-1251.txt'))
|
stub_request(:get, 'http://example.com/windows-1251').to_return(request_fixture('windows-1251.txt'))
|
||||||
|
stub_request(:get, 'http://example.com/low_confidence_latin1').to_return(request_fixture('low_confidence_latin1.txt'))
|
||||||
|
|
||||||
Rails.cache.write('oembed_endpoint:example.com', oembed_cache) if oembed_cache
|
Rails.cache.write('oembed_endpoint:example.com', oembed_cache) if oembed_cache
|
||||||
|
|
||||||
|
@ -150,6 +151,14 @@ RSpec.describe FetchLinkCardService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'with a URL of a page in ISO-8859-1 encoding, that charlock_holmes cannot detect' do
|
||||||
|
let(:status) { Fabricate(:status, text: 'Check out http://example.com/low_confidence_latin1') }
|
||||||
|
|
||||||
|
it 'decodes the HTML' do
|
||||||
|
expect(status.preview_card.title).to eq("Tofu á l'orange")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'with a Japanese path URL' do
|
context 'with a Japanese path URL' do
|
||||||
let(:status) { Fabricate(:status, text: 'テストhttp://example.com/日本語') }
|
let(:status) { Fabricate(:status, text: 'テストhttp://example.com/日本語') }
|
||||||
|
|
||||||
|
|
|
@ -6,3 +6,14 @@ RSpec::Matchers.define :match_json_schema do |schema|
|
||||||
JSON::Validator.validate(schema_path, input_json, validate_schema: true)
|
JSON::Validator.validate(schema_path, input_json, validate_schema: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
RSpec::Matchers.define :match_json_values do |values|
|
||||||
|
match do |string|
|
||||||
|
expect(json_str_to_hash(string))
|
||||||
|
.to include(values)
|
||||||
|
end
|
||||||
|
|
||||||
|
failure_message do |value|
|
||||||
|
"expected that #{value} would have the same values as #{values}."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -80,9 +80,6 @@ end
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
config.before :suite do
|
config.before :suite do
|
||||||
if streaming_examples_present?
|
if streaming_examples_present?
|
||||||
# Compile assets
|
|
||||||
Webpacker.compile
|
|
||||||
|
|
||||||
# Start the node streaming server
|
# Start the node streaming server
|
||||||
streaming_server_manager.start(port: STREAMING_PORT)
|
streaming_server_manager.start(port: STREAMING_PORT)
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,7 +16,7 @@ describe ActivityPub::DistributePollUpdateWorker do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'delivers to followers' do
|
it 'delivers to followers' do
|
||||||
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[kind_of(String), account.id, 'http://example.com']]) do
|
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[match_json_values(type: 'Update'), account.id, 'http://example.com']]) do
|
||||||
subject.perform(status.id)
|
subject.perform(status.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -19,7 +19,7 @@ describe ActivityPub::DistributionWorker do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'delivers to followers' do
|
it 'delivers to followers' do
|
||||||
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[kind_of(String), status.account.id, 'http://example.com', anything]]) do
|
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[match_json_values(type: 'Create'), status.account.id, 'http://example.com', anything]]) do
|
||||||
subject.perform(status.id)
|
subject.perform(status.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -43,7 +43,7 @@ describe ActivityPub::DistributionWorker do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'delivers to followers' do
|
it 'delivers to followers' do
|
||||||
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[kind_of(String), status.account.id, 'http://example.com', anything]]) do
|
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[match_json_values(type: 'Create'), status.account.id, 'http://example.com', anything]]) do
|
||||||
subject.perform(status.id)
|
subject.perform(status.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -104,7 +104,7 @@ describe ActivityPub::DistributionWorker do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'delivers to mentioned accounts' do
|
it 'delivers to mentioned accounts' do
|
||||||
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[kind_of(String), status.account.id, 'https://foo.bar/inbox', anything]]) do
|
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[match_json_values(type: 'Create'), status.account.id, 'https://foo.bar/inbox', anything]]) do
|
||||||
subject.perform(status.id)
|
subject.perform(status.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,12 +16,16 @@ describe ActivityPub::MoveDistributionWorker do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'delivers to followers and known blockers' do
|
it 'delivers to followers and known blockers' do
|
||||||
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [
|
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, expected_migration_deliveries) do
|
||||||
[kind_of(String), migration.account.id, 'http://example.com'],
|
|
||||||
[kind_of(String), migration.account.id, 'http://example2.com'],
|
|
||||||
]) do
|
|
||||||
subject.perform(migration.id)
|
subject.perform(migration.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def expected_migration_deliveries
|
||||||
|
[
|
||||||
|
[match_json_values(type: 'Move'), migration.account.id, 'http://example.com'],
|
||||||
|
[match_json_values(type: 'Move'), migration.account.id, 'http://example2.com'],
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,7 +25,7 @@ describe ActivityPub::StatusUpdateDistributionWorker do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'delivers to followers' do
|
it 'delivers to followers' do
|
||||||
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[kind_of(String), status.account.id, 'http://example.com', anything]]) do
|
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[match_json_values(type: 'Update'), status.account.id, 'http://example.com', anything]]) do
|
||||||
subject.perform(status.id)
|
subject.perform(status.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -49,7 +49,7 @@ describe ActivityPub::StatusUpdateDistributionWorker do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'delivers to followers' do
|
it 'delivers to followers' do
|
||||||
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[kind_of(String), status.account.id, 'http://example.com', anything]]) do
|
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[match_json_values(type: 'Update'), status.account.id, 'http://example.com', anything]]) do
|
||||||
subject.perform(status.id)
|
subject.perform(status.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,7 @@ describe ActivityPub::UpdateDistributionWorker do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'delivers to followers' do
|
it 'delivers to followers' do
|
||||||
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[kind_of(String), account.id, 'http://example.com', anything]]) do
|
expect_push_bulk_to_match(ActivityPub::DeliveryWorker, [[match_json_values(type: 'Update'), account.id, 'http://example.com', anything]]) do
|
||||||
subject.perform(account.id)
|
subject.perform(account.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# syntax=docker/dockerfile:1.7
|
# syntax=docker/dockerfile:1.8
|
||||||
|
|
||||||
# Please see https://docs.docker.com/engine/reference/builder for information about
|
# Please see https://docs.docker.com/engine/reference/builder for information about
|
||||||
# the extended buildx capabilities used in this file.
|
# the extended buildx capabilities used in this file.
|
||||||
|
@ -13,7 +13,14 @@ ARG NODE_MAJOR_VERSION="20"
|
||||||
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
# Debian image to use for base image, change with [--build-arg DEBIAN_VERSION="bookworm"]
|
||||||
ARG DEBIAN_VERSION="bookworm"
|
ARG DEBIAN_VERSION="bookworm"
|
||||||
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
|
# Node image to use for base image based on combined variables (ex: 20-bookworm-slim)
|
||||||
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim as streaming
|
FROM docker.io/node:${NODE_MAJOR_VERSION}-${DEBIAN_VERSION}-slim AS streaming
|
||||||
|
|
||||||
|
# Resulting version string is vX.X.X-MASTODON_VERSION_PRERELEASE+MASTODON_VERSION_METADATA
|
||||||
|
# Example: v4.3.0-nightly.2023.11.09+pr-123456
|
||||||
|
# Overwrite existence of 'alpha.X' in version.rb [--build-arg MASTODON_VERSION_PRERELEASE="nightly.2023.11.09"]
|
||||||
|
ARG MASTODON_VERSION_PRERELEASE=""
|
||||||
|
# Append build metadata or fork information to version.rb [--build-arg MASTODON_VERSION_METADATA="pr-123456"]
|
||||||
|
ARG MASTODON_VERSION_METADATA=""
|
||||||
|
|
||||||
# Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin]
|
# Timezone used by the Docker container and runtime, change with [--build-arg TZ=Europe/Berlin]
|
||||||
ARG TZ="Etc/UTC"
|
ARG TZ="Etc/UTC"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "@mastodon/streaming",
|
"name": "@mastodon/streaming",
|
||||||
"license": "AGPL-3.0-or-later",
|
"license": "AGPL-3.0-or-later",
|
||||||
"packageManager": "yarn@4.3.0",
|
"packageManager": "yarn@4.3.1",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18"
|
"node": ">=18"
|
||||||
},
|
},
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
"@types/cors": "^2.8.16",
|
"@types/cors": "^2.8.16",
|
||||||
"@types/express": "^4.17.17",
|
"@types/express": "^4.17.17",
|
||||||
"@types/pg": "^8.6.6",
|
"@types/pg": "^8.6.6",
|
||||||
"@types/uuid": "^9.0.0",
|
"@types/uuid": "^10.0.0",
|
||||||
"@types/ws": "^8.5.9",
|
"@types/ws": "^8.5.9",
|
||||||
"eslint-define-config": "^2.0.0",
|
"eslint-define-config": "^2.0.0",
|
||||||
"pino-pretty": "^11.0.0",
|
"pino-pretty": "^11.0.0",
|
||||||
|
|
235
yarn.lock
235
yarn.lock
|
@ -2944,7 +2944,7 @@ __metadata:
|
||||||
"@types/cors": "npm:^2.8.16"
|
"@types/cors": "npm:^2.8.16"
|
||||||
"@types/express": "npm:^4.17.17"
|
"@types/express": "npm:^4.17.17"
|
||||||
"@types/pg": "npm:^8.6.6"
|
"@types/pg": "npm:^8.6.6"
|
||||||
"@types/uuid": "npm:^9.0.0"
|
"@types/uuid": "npm:^10.0.0"
|
||||||
"@types/ws": "npm:^8.5.9"
|
"@types/ws": "npm:^8.5.9"
|
||||||
bufferutil: "npm:^4.0.7"
|
bufferutil: "npm:^4.0.7"
|
||||||
cors: "npm:^2.8.5"
|
cors: "npm:^2.8.5"
|
||||||
|
@ -4064,10 +4064,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@types/uuid@npm:^9.0.0":
|
"@types/uuid@npm:^10.0.0":
|
||||||
version: 9.0.8
|
version: 10.0.0
|
||||||
resolution: "@types/uuid@npm:9.0.8"
|
resolution: "@types/uuid@npm:10.0.0"
|
||||||
checksum: 10c0/b411b93054cb1d4361919579ef3508a1f12bf15b5fdd97337d3d351bece6c921b52b6daeef89b62340fd73fd60da407878432a1af777f40648cbe53a01723489
|
checksum: 10c0/9a1404bf287164481cb9b97f6bb638f78f955be57c40c6513b7655160beb29df6f84c915aaf4089a1559c216557dc4d2f79b48d978742d3ae10b937420ddac60
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -5662,17 +5662,17 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"browserslist@npm:^4.0.0, browserslist@npm:^4.22.2, browserslist@npm:^4.22.3, browserslist@npm:^4.23.0":
|
"browserslist@npm:^4.0.0, browserslist@npm:^4.22.2, browserslist@npm:^4.22.3, browserslist@npm:^4.23.0, browserslist@npm:^4.23.1":
|
||||||
version: 4.23.0
|
version: 4.23.1
|
||||||
resolution: "browserslist@npm:4.23.0"
|
resolution: "browserslist@npm:4.23.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
caniuse-lite: "npm:^1.0.30001587"
|
caniuse-lite: "npm:^1.0.30001629"
|
||||||
electron-to-chromium: "npm:^1.4.668"
|
electron-to-chromium: "npm:^1.4.796"
|
||||||
node-releases: "npm:^2.0.14"
|
node-releases: "npm:^2.0.14"
|
||||||
update-browserslist-db: "npm:^1.0.13"
|
update-browserslist-db: "npm:^1.0.16"
|
||||||
bin:
|
bin:
|
||||||
browserslist: cli.js
|
browserslist: cli.js
|
||||||
checksum: 10c0/8e9cc154529062128d02a7af4d8adeead83ca1df8cd9ee65a88e2161039f3d68a4d40fea7353cab6bae4c16182dec2fdd9a1cf7dc2a2935498cee1af0e998943
|
checksum: 10c0/eb47c7ab9d60db25ce2faca70efeb278faa7282a2f62b7f2fa2f92e5f5251cf65144244566c86559419ff4f6d78f59ea50e39911321ad91f3b27788901f1f5e9
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -5874,10 +5874,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001587, caniuse-lite@npm:^1.0.30001599":
|
"caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001599, caniuse-lite@npm:^1.0.30001629":
|
||||||
version: 1.0.30001599
|
version: 1.0.30001636
|
||||||
resolution: "caniuse-lite@npm:1.0.30001599"
|
resolution: "caniuse-lite@npm:1.0.30001636"
|
||||||
checksum: 10c0/8b3b9610b5be88533a3c8d0770d6896f7b1a9fee3dbeb7339e4ee119a514c81e5e07a628a5a289a6541ca291ac78a9402f5a99cf6012139e91f379083488a8eb
|
checksum: 10c0/e5f965b4da7bae1531fd9f93477d015729ff9e3fa12670ead39a9e6cdc4c43e62c272d47857c5cc332e7b02d697cb3f2f965a1030870ac7476da60c2fc81ee94
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -6751,43 +6751,43 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"cssnano-preset-default@npm:^7.0.2":
|
"cssnano-preset-default@npm:^7.0.3":
|
||||||
version: 7.0.2
|
version: 7.0.3
|
||||||
resolution: "cssnano-preset-default@npm:7.0.2"
|
resolution: "cssnano-preset-default@npm:7.0.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: "npm:^4.23.0"
|
browserslist: "npm:^4.23.1"
|
||||||
css-declaration-sorter: "npm:^7.2.0"
|
css-declaration-sorter: "npm:^7.2.0"
|
||||||
cssnano-utils: "npm:^5.0.0"
|
cssnano-utils: "npm:^5.0.0"
|
||||||
postcss-calc: "npm:^10.0.0"
|
postcss-calc: "npm:^10.0.0"
|
||||||
postcss-colormin: "npm:^7.0.0"
|
postcss-colormin: "npm:^7.0.1"
|
||||||
postcss-convert-values: "npm:^7.0.0"
|
postcss-convert-values: "npm:^7.0.1"
|
||||||
postcss-discard-comments: "npm:^7.0.0"
|
postcss-discard-comments: "npm:^7.0.1"
|
||||||
postcss-discard-duplicates: "npm:^7.0.0"
|
postcss-discard-duplicates: "npm:^7.0.0"
|
||||||
postcss-discard-empty: "npm:^7.0.0"
|
postcss-discard-empty: "npm:^7.0.0"
|
||||||
postcss-discard-overridden: "npm:^7.0.0"
|
postcss-discard-overridden: "npm:^7.0.0"
|
||||||
postcss-merge-longhand: "npm:^7.0.1"
|
postcss-merge-longhand: "npm:^7.0.2"
|
||||||
postcss-merge-rules: "npm:^7.0.1"
|
postcss-merge-rules: "npm:^7.0.2"
|
||||||
postcss-minify-font-values: "npm:^7.0.0"
|
postcss-minify-font-values: "npm:^7.0.0"
|
||||||
postcss-minify-gradients: "npm:^7.0.0"
|
postcss-minify-gradients: "npm:^7.0.0"
|
||||||
postcss-minify-params: "npm:^7.0.0"
|
postcss-minify-params: "npm:^7.0.1"
|
||||||
postcss-minify-selectors: "npm:^7.0.1"
|
postcss-minify-selectors: "npm:^7.0.2"
|
||||||
postcss-normalize-charset: "npm:^7.0.0"
|
postcss-normalize-charset: "npm:^7.0.0"
|
||||||
postcss-normalize-display-values: "npm:^7.0.0"
|
postcss-normalize-display-values: "npm:^7.0.0"
|
||||||
postcss-normalize-positions: "npm:^7.0.0"
|
postcss-normalize-positions: "npm:^7.0.0"
|
||||||
postcss-normalize-repeat-style: "npm:^7.0.0"
|
postcss-normalize-repeat-style: "npm:^7.0.0"
|
||||||
postcss-normalize-string: "npm:^7.0.0"
|
postcss-normalize-string: "npm:^7.0.0"
|
||||||
postcss-normalize-timing-functions: "npm:^7.0.0"
|
postcss-normalize-timing-functions: "npm:^7.0.0"
|
||||||
postcss-normalize-unicode: "npm:^7.0.0"
|
postcss-normalize-unicode: "npm:^7.0.1"
|
||||||
postcss-normalize-url: "npm:^7.0.0"
|
postcss-normalize-url: "npm:^7.0.0"
|
||||||
postcss-normalize-whitespace: "npm:^7.0.0"
|
postcss-normalize-whitespace: "npm:^7.0.0"
|
||||||
postcss-ordered-values: "npm:^7.0.0"
|
postcss-ordered-values: "npm:^7.0.1"
|
||||||
postcss-reduce-initial: "npm:^7.0.0"
|
postcss-reduce-initial: "npm:^7.0.1"
|
||||||
postcss-reduce-transforms: "npm:^7.0.0"
|
postcss-reduce-transforms: "npm:^7.0.0"
|
||||||
postcss-svgo: "npm:^7.0.1"
|
postcss-svgo: "npm:^7.0.1"
|
||||||
postcss-unique-selectors: "npm:^7.0.1"
|
postcss-unique-selectors: "npm:^7.0.1"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/7c66240594c1d7a0cc761e755236228b17251455aa57abc45be0631f7de0fde070c23b0e41ffa200d39cd8351718514217d8c7a8cc4f06b54289dc1d555dfeb2
|
checksum: 10c0/ab3e51003efed6542a12d43c10ca693ab26138a1d035697b9be8f07e084e37a78617cbb8028b0a7e7841302ec151f4ecf35cbd763efe291846b62c35ea4c0bb4
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -6801,14 +6801,14 @@ __metadata:
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"cssnano@npm:^7.0.0":
|
"cssnano@npm:^7.0.0":
|
||||||
version: 7.0.2
|
version: 7.0.3
|
||||||
resolution: "cssnano@npm:7.0.2"
|
resolution: "cssnano@npm:7.0.3"
|
||||||
dependencies:
|
dependencies:
|
||||||
cssnano-preset-default: "npm:^7.0.2"
|
cssnano-preset-default: "npm:^7.0.3"
|
||||||
lilconfig: "npm:^3.1.1"
|
lilconfig: "npm:^3.1.2"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/ad43d8c2e96fa1022fc5103064e4f08da3fdc5501a946d455edf0b81981b58cd06ad2d3f0c68d666e2b687c10c02ffbb383252aa34da0ddc3bd4d075f4a922c7
|
checksum: 10c0/4cbcd1e0ebe0bd83196cc5b16b3a60d3ebc98326c79b2f71df597bb73c8e3ee1f42b89159d7a038acc398251184d648d9dd516f4194e46746f3af6fa74b4aec7
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -7423,10 +7423,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"electron-to-chromium@npm:^1.4.668":
|
"electron-to-chromium@npm:^1.4.796":
|
||||||
version: 1.4.681
|
version: 1.4.806
|
||||||
resolution: "electron-to-chromium@npm:1.4.681"
|
resolution: "electron-to-chromium@npm:1.4.806"
|
||||||
checksum: 10c0/5b2558dfb8bb82c20fb5fa1d9bbe06a3add47431dc3e1e4815e997be6ad387787047d9e534ed96839a9e7012520a5281c865158b09db41d10c029af003f05f94
|
checksum: 10c0/44f925ba64bb623d0482cd2f14fcfb27017cec1f11ee642e0d49cb128cd714ba5e074c2cd8756dfc18010aa66d3c64039cdea891905f7c17160a8963db574fab
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -7742,10 +7742,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"escalade@npm:^3.1.1":
|
"escalade@npm:^3.1.1, escalade@npm:^3.1.2":
|
||||||
version: 3.1.1
|
version: 3.1.2
|
||||||
resolution: "escalade@npm:3.1.1"
|
resolution: "escalade@npm:3.1.2"
|
||||||
checksum: 10c0/afd02e6ca91ffa813e1108b5e7756566173d6bc0d1eb951cb44d6b21702ec17c1cf116cfe75d4a2b02e05acb0b808a7a9387d0d1ca5cf9c04ad03a8445c3e46d
|
checksum: 10c0/6b4adafecd0682f3aa1cd1106b8fff30e492c7015b178bc81b2d2f75106dabea6c6d6e8508fc491bd58e597c74abb0e8e2368f943ecb9393d4162e3c2f3cf287
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -8952,17 +8952,18 @@ __metadata:
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"glob@npm:^10.2.2, glob@npm:^10.2.6, glob@npm:^10.3.10":
|
"glob@npm:^10.2.2, glob@npm:^10.2.6, glob@npm:^10.3.10":
|
||||||
version: 10.4.1
|
version: 10.4.2
|
||||||
resolution: "glob@npm:10.4.1"
|
resolution: "glob@npm:10.4.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
foreground-child: "npm:^3.1.0"
|
foreground-child: "npm:^3.1.0"
|
||||||
jackspeak: "npm:^3.1.2"
|
jackspeak: "npm:^3.1.2"
|
||||||
minimatch: "npm:^9.0.4"
|
minimatch: "npm:^9.0.4"
|
||||||
minipass: "npm:^7.1.2"
|
minipass: "npm:^7.1.2"
|
||||||
|
package-json-from-dist: "npm:^1.0.0"
|
||||||
path-scurry: "npm:^1.11.1"
|
path-scurry: "npm:^1.11.1"
|
||||||
bin:
|
bin:
|
||||||
glob: dist/esm/bin.mjs
|
glob: dist/esm/bin.mjs
|
||||||
checksum: 10c0/77f2900ed98b9cc2a0e1901ee5e476d664dae3cd0f1b662b8bfd4ccf00d0edc31a11595807706a274ca10e1e251411bbf2e8e976c82bed0d879a9b89343ed379
|
checksum: 10c0/2c7296695fa75a935f3ad17dc62e4e170a8bb8752cf64d328be8992dd6ad40777939003754e10e9741ff8fbe43aa52fba32d6930d0ffa0e3b74bc3fb5eebaa2f
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -11295,10 +11296,10 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"lilconfig@npm:^3.1.1, lilconfig@npm:~3.1.1":
|
"lilconfig@npm:^3.1.2, lilconfig@npm:~3.1.1":
|
||||||
version: 3.1.1
|
version: 3.1.2
|
||||||
resolution: "lilconfig@npm:3.1.1"
|
resolution: "lilconfig@npm:3.1.2"
|
||||||
checksum: 10c0/311b559794546894e3fe176663427326026c1c644145be9e8041c58e268aa9328799b8dfe7e4dd8c6a4ae305feae95a1c9e007db3569f35b42b6e1bc8274754c
|
checksum: 10c0/f059630b1a9bddaeba83059db00c672b64dc14074e9f232adce32b38ca1b5686ab737eb665c5ba3c32f147f0002b4bee7311ad0386a9b98547b5623e87071fbe
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -12696,6 +12697,13 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"package-json-from-dist@npm:^1.0.0":
|
||||||
|
version: 1.0.0
|
||||||
|
resolution: "package-json-from-dist@npm:1.0.0"
|
||||||
|
checksum: 10c0/e3ffaf6ac1040ab6082a658230c041ad14e72fabe99076a2081bb1d5d41210f11872403fc09082daf4387fc0baa6577f96c9c0e94c90c394fd57794b66aa4033
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"pako@npm:~1.0.5":
|
"pako@npm:~1.0.5":
|
||||||
version: 1.0.11
|
version: 1.0.11
|
||||||
resolution: "pako@npm:1.0.11"
|
resolution: "pako@npm:1.0.11"
|
||||||
|
@ -13264,29 +13272,29 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"postcss-colormin@npm:^7.0.0":
|
"postcss-colormin@npm:^7.0.1":
|
||||||
version: 7.0.0
|
version: 7.0.1
|
||||||
resolution: "postcss-colormin@npm:7.0.0"
|
resolution: "postcss-colormin@npm:7.0.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: "npm:^4.23.0"
|
browserslist: "npm:^4.23.1"
|
||||||
caniuse-api: "npm:^3.0.0"
|
caniuse-api: "npm:^3.0.0"
|
||||||
colord: "npm:^2.9.3"
|
colord: "npm:^2.9.3"
|
||||||
postcss-value-parser: "npm:^4.2.0"
|
postcss-value-parser: "npm:^4.2.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/d365a5365e0a94748309d32c7208cd06249bc53eb82cc32c771de4073b109fa8552e58d60dbe84d7e69e68081ed8a01fbf645d38a650e90cb2e13b21043cd796
|
checksum: 10c0/e01e9e129ce39320cf10bb09ee2a3ab5b44b77805d3f7827eea07297644838b85c33b78996eeae0a1aba327ffd72a6ab1d24949ebc831523e310e916d5500371
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"postcss-convert-values@npm:^7.0.0":
|
"postcss-convert-values@npm:^7.0.1":
|
||||||
version: 7.0.0
|
version: 7.0.1
|
||||||
resolution: "postcss-convert-values@npm:7.0.0"
|
resolution: "postcss-convert-values@npm:7.0.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: "npm:^4.23.0"
|
browserslist: "npm:^4.23.1"
|
||||||
postcss-value-parser: "npm:^4.2.0"
|
postcss-value-parser: "npm:^4.2.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/5d7cfa06f307e024574a1842016f006691e0c1932352f53a99ce8f2f9930c64c3c1ae17518e9e4e5176630b99f1beaab37bc339bc779fb07dc543670ae66bb21
|
checksum: 10c0/612f025f179f0f2ad7365db8c0b423614dcb8e1e4061875a4691a39dede0bca758d1a8f9f5c8b08e12af053e9e884f65ca5626ccc723d5b3f420650d67fe3046
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -13344,12 +13352,14 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"postcss-discard-comments@npm:^7.0.0":
|
"postcss-discard-comments@npm:^7.0.1":
|
||||||
version: 7.0.0
|
version: 7.0.1
|
||||||
resolution: "postcss-discard-comments@npm:7.0.0"
|
resolution: "postcss-discard-comments@npm:7.0.1"
|
||||||
|
dependencies:
|
||||||
|
postcss-selector-parser: "npm:^6.1.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/7fef7deea85c1e68161f69057be19a3aedd54d23c9b464c9b1531faa7a115f0c96a4f0ee3a560ce300578599dbc8114fe0fb744208b20b9d2fd8df1b4b39c58a
|
checksum: 10c0/64de3fced7e0e49dfea6aede8a5ca495b81dcd01c3c47734a5fbc86a3cb2b1ae39e1958e34e9bea64ecabd5fb4d8c287ec1d6189cf175c2434c6b6582da79948
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -13494,29 +13504,29 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"postcss-merge-longhand@npm:^7.0.1":
|
"postcss-merge-longhand@npm:^7.0.2":
|
||||||
version: 7.0.1
|
version: 7.0.2
|
||||||
resolution: "postcss-merge-longhand@npm:7.0.1"
|
resolution: "postcss-merge-longhand@npm:7.0.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
postcss-value-parser: "npm:^4.2.0"
|
postcss-value-parser: "npm:^4.2.0"
|
||||||
stylehacks: "npm:^7.0.1"
|
stylehacks: "npm:^7.0.2"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/e3d20502e65c82c9c4ba2e400bd093ee6b9c1b0019618ccd50eb40ef0e496206dd518c7e655a6986d780d5a52576e32e8f310d00484b15f67c77664a148df6eb
|
checksum: 10c0/71d22418e5850e134bfcf2038acb1c91eeb48d9b6f9e4c0252fee757e11dc4ae351097a855c327fbc38dc7658fa6edc7cc7f458c08bb4044b82c6005dc565fcb
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"postcss-merge-rules@npm:^7.0.1":
|
"postcss-merge-rules@npm:^7.0.2":
|
||||||
version: 7.0.1
|
version: 7.0.2
|
||||||
resolution: "postcss-merge-rules@npm:7.0.1"
|
resolution: "postcss-merge-rules@npm:7.0.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: "npm:^4.23.0"
|
browserslist: "npm:^4.23.1"
|
||||||
caniuse-api: "npm:^3.0.0"
|
caniuse-api: "npm:^3.0.0"
|
||||||
cssnano-utils: "npm:^5.0.0"
|
cssnano-utils: "npm:^5.0.0"
|
||||||
postcss-selector-parser: "npm:^6.1.0"
|
postcss-selector-parser: "npm:^6.1.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/d380c162327e7aad59efb55cfddc5ec4e3bf51d18b07b832fdd876505279bac3cb44511ada8e1e1992428dcec4f64c7ec457b6ff9109063c5a61abf4b59b7176
|
checksum: 10c0/fbad20382ca45f1b3b5ff704c075f899cc9ba8418ae6effbdeb9e7c1f9b5c24996d1941ad36cd0936d60cbf127a72f235b2cbb0c44d9239a8a61042406d95b4a
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -13544,27 +13554,28 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"postcss-minify-params@npm:^7.0.0":
|
"postcss-minify-params@npm:^7.0.1":
|
||||||
version: 7.0.0
|
version: 7.0.1
|
||||||
resolution: "postcss-minify-params@npm:7.0.0"
|
resolution: "postcss-minify-params@npm:7.0.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: "npm:^4.23.0"
|
browserslist: "npm:^4.23.1"
|
||||||
cssnano-utils: "npm:^5.0.0"
|
cssnano-utils: "npm:^5.0.0"
|
||||||
postcss-value-parser: "npm:^4.2.0"
|
postcss-value-parser: "npm:^4.2.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/28a7ae313a197aeaff8b3fa1e695a6443b11a74258374a05adee6a1b05f5849ef52037b7a5069d6910614b03b4610acdaf4a76f38b89cb42e813a8cb5ec2fc01
|
checksum: 10c0/84e1c4de5af47178c1f48e10ce16341560f32bb2becf5ec9b014103f6c706174bc70885e2e13ced4de9b4f1959fb970193261cbd4751c8b87d5159e859e8c5ec
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"postcss-minify-selectors@npm:^7.0.1":
|
"postcss-minify-selectors@npm:^7.0.2":
|
||||||
version: 7.0.1
|
version: 7.0.2
|
||||||
resolution: "postcss-minify-selectors@npm:7.0.1"
|
resolution: "postcss-minify-selectors@npm:7.0.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
cssesc: "npm:^3.0.0"
|
||||||
postcss-selector-parser: "npm:^6.1.0"
|
postcss-selector-parser: "npm:^6.1.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/a8ff69657fb1808d8f0f105b13a416426902d6f498a4b7ebb3b96b4b9149e97ee2e2ad6cd98108e2f0b8f781701724e6c51e120e215cee3e40c2d7a2afac755a
|
checksum: 10c0/87e0c21a0135b6c61b58d62c4c1e0cbd3cfb516ff8105db714c6a33a5edc477846ae220399d368e4ef6518529c711aa2dee9ff49e9befd93e83d5c939f3084a1
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -13689,15 +13700,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"postcss-normalize-unicode@npm:^7.0.0":
|
"postcss-normalize-unicode@npm:^7.0.1":
|
||||||
version: 7.0.0
|
version: 7.0.1
|
||||||
resolution: "postcss-normalize-unicode@npm:7.0.0"
|
resolution: "postcss-normalize-unicode@npm:7.0.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: "npm:^4.23.0"
|
browserslist: "npm:^4.23.1"
|
||||||
postcss-value-parser: "npm:^4.2.0"
|
postcss-value-parser: "npm:^4.2.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/f2d6ab0076c006dcf3ed33ba30686f2d29e81a408c66acced22e2c942df6d613697ea786137833dd258aafab5fda4d3eb27df13a82df830357dbad9b79154881
|
checksum: 10c0/fcabac738765f608cb211ac01a19f9a7d784f99d223ef6f31352f37b9bcf008e0ca7849414c9e77116be8660d78b01dba6fc4a87cee7c9a977d3c2741d6a222d
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -13732,15 +13743,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"postcss-ordered-values@npm:^7.0.0":
|
"postcss-ordered-values@npm:^7.0.1":
|
||||||
version: 7.0.0
|
version: 7.0.1
|
||||||
resolution: "postcss-ordered-values@npm:7.0.0"
|
resolution: "postcss-ordered-values@npm:7.0.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
cssnano-utils: "npm:^5.0.0"
|
cssnano-utils: "npm:^5.0.0"
|
||||||
postcss-value-parser: "npm:^4.2.0"
|
postcss-value-parser: "npm:^4.2.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/42b14f9518b573318594c2aeb2f13fd1fbe44936d14f1b28a438e7a82644ace9a2946699bebfe7a2d383534dc24e7203c35308d749f3c585a86daa238ad920a4
|
checksum: 10c0/9fc62e9039c7d4fa417d165678b065fc577a7232aa41a94a4e9208ad7db2268e1ce003aaad7c6a569afdf890a43416b0bf21047461505b4e3a16eec311a6eb63
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -13856,15 +13867,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"postcss-reduce-initial@npm:^7.0.0":
|
"postcss-reduce-initial@npm:^7.0.1":
|
||||||
version: 7.0.0
|
version: 7.0.1
|
||||||
resolution: "postcss-reduce-initial@npm:7.0.0"
|
resolution: "postcss-reduce-initial@npm:7.0.1"
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: "npm:^4.23.0"
|
browserslist: "npm:^4.23.1"
|
||||||
caniuse-api: "npm:^3.0.0"
|
caniuse-api: "npm:^3.0.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/ed50cd680ce258df953b82ce9b3fb52564d08548724577810800e236d017d80430cbccb4b1ad38b0f4d521663598e44ab93136b20064231181ef49e1e113ae10
|
checksum: 10c0/3e7c6c1d0cc4ace38f44971f02d0dd98131af678cf114aa05cfa0c066420019d5329c221ef8507644b8a79d0e76534303f747c97860ac777fe17f57110edefe1
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -15422,15 +15433,15 @@ __metadata:
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"sass@npm:^1.62.1":
|
"sass@npm:^1.62.1":
|
||||||
version: 1.77.5
|
version: 1.77.6
|
||||||
resolution: "sass@npm:1.77.5"
|
resolution: "sass@npm:1.77.6"
|
||||||
dependencies:
|
dependencies:
|
||||||
chokidar: "npm:>=3.0.0 <4.0.0"
|
chokidar: "npm:>=3.0.0 <4.0.0"
|
||||||
immutable: "npm:^4.0.0"
|
immutable: "npm:^4.0.0"
|
||||||
source-map-js: "npm:>=0.6.2 <2.0.0"
|
source-map-js: "npm:>=0.6.2 <2.0.0"
|
||||||
bin:
|
bin:
|
||||||
sass: sass.js
|
sass: sass.js
|
||||||
checksum: 10c0/9da049b0a3fadab419084d6becdf471e107cf6e3c8ac87cabea2feb845afac75e86c99e06ee721a5aa4f6a2d833ec5380137c4e540ab2f760edf1e4eb6139e69
|
checksum: 10c0/fe5a393c0aa29eda9f83c06be9b94788b61fe8bad0616ee6e3a25d21ab504f430d40c0064fdca89b02b8e426411ae6dcd906c91f2e48c263575c3d392b6daeb1
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -16474,15 +16485,15 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"stylehacks@npm:^7.0.1":
|
"stylehacks@npm:^7.0.2":
|
||||||
version: 7.0.1
|
version: 7.0.2
|
||||||
resolution: "stylehacks@npm:7.0.1"
|
resolution: "stylehacks@npm:7.0.2"
|
||||||
dependencies:
|
dependencies:
|
||||||
browserslist: "npm:^4.23.0"
|
browserslist: "npm:^4.23.1"
|
||||||
postcss-selector-parser: "npm:^6.1.0"
|
postcss-selector-parser: "npm:^6.1.0"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
postcss: ^8.4.31
|
postcss: ^8.4.31
|
||||||
checksum: 10c0/538d5d9c6d84906efad3706f0873b85b67fa224f17759b122bad3d60f2928c31204fd658dd16ec952bf54858a3aeaef4643e040c04030459285ce1b13c4cae91
|
checksum: 10c0/552299e869ac430e1076c025ace6c80bdfd5b672632435625eb1bd45ff5611aad7f3ee810e72edc04dc0fc3761e08dec40d27b72c50b95690eea2de43238b8d8
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
@ -17408,17 +17419,17 @@ __metadata:
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"update-browserslist-db@npm:^1.0.13":
|
"update-browserslist-db@npm:^1.0.16":
|
||||||
version: 1.0.13
|
version: 1.0.16
|
||||||
resolution: "update-browserslist-db@npm:1.0.13"
|
resolution: "update-browserslist-db@npm:1.0.16"
|
||||||
dependencies:
|
dependencies:
|
||||||
escalade: "npm:^3.1.1"
|
escalade: "npm:^3.1.2"
|
||||||
picocolors: "npm:^1.0.0"
|
picocolors: "npm:^1.0.1"
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
browserslist: ">= 4.21.0"
|
browserslist: ">= 4.21.0"
|
||||||
bin:
|
bin:
|
||||||
update-browserslist-db: cli.js
|
update-browserslist-db: cli.js
|
||||||
checksum: 10c0/e52b8b521c78ce1e0c775f356cd16a9c22c70d25f3e01180839c407a5dc787fb05a13f67560cbaf316770d26fa99f78f1acd711b1b54a4f35d4820d4ea7136e6
|
checksum: 10c0/5995399fc202adbb51567e4810e146cdf7af630a92cc969365a099150cb00597e425cc14987ca7080b09a4d0cfd2a3de53fbe72eebff171aed7f9bb81f9bf405
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue