Merge branch 'main' into glitch-soc/merge-upstream
Conflicts: - `.github/workflows/build-image.yml`: Upstream updated `docker/build-push-action`, and we a different config for `docker/metadata-action` so the lines directly above were different, but it's not a real conflict. Upgraded `docker/build-push-action` as upstream did. - `app/javascript/mastodon/features/compose/components/compose_form.js`: Upstream changed the codestyle near a line we had modified to accommodate configurable character count. Kept our change.
This commit is contained in:
commit
aeacebb3d7
249 changed files with 4854 additions and 3174 deletions
87
.eslintrc.js
87
.eslintrc.js
|
@ -3,6 +3,8 @@ module.exports = {
|
||||||
|
|
||||||
extends: [
|
extends: [
|
||||||
'eslint:recommended',
|
'eslint:recommended',
|
||||||
|
'plugin:react/recommended',
|
||||||
|
'plugin:jsx-a11y/recommended',
|
||||||
],
|
],
|
||||||
|
|
||||||
env: {
|
env: {
|
||||||
|
@ -80,8 +82,6 @@ module.exports = {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'no-empty': 'off',
|
'no-empty': 'off',
|
||||||
'no-nested-ternary': 'warn',
|
|
||||||
'no-prototype-builtins': 'off',
|
|
||||||
'no-restricted-properties': [
|
'no-restricted-properties': [
|
||||||
'error',
|
'error',
|
||||||
{ property: 'substring', message: 'Use .slice instead of .substring.' },
|
{ property: 'substring', message: 'Use .slice instead of .substring.' },
|
||||||
|
@ -113,55 +113,42 @@ module.exports = {
|
||||||
'react/jsx-boolean-value': 'error',
|
'react/jsx-boolean-value': 'error',
|
||||||
'react/jsx-closing-bracket-location': ['error', 'line-aligned'],
|
'react/jsx-closing-bracket-location': ['error', 'line-aligned'],
|
||||||
'react/jsx-curly-spacing': 'error',
|
'react/jsx-curly-spacing': 'error',
|
||||||
|
'react/display-name': 'off',
|
||||||
'react/jsx-equals-spacing': 'error',
|
'react/jsx-equals-spacing': 'error',
|
||||||
'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'],
|
'react/jsx-first-prop-new-line': ['error', 'multiline-multiprop'],
|
||||||
'react/jsx-indent': ['error', 2],
|
'react/jsx-indent': ['error', 2],
|
||||||
'react/jsx-no-bind': 'error',
|
'react/jsx-no-bind': 'error',
|
||||||
'react/jsx-no-duplicate-props': 'error',
|
'react/jsx-no-target-blank': 'off',
|
||||||
'react/jsx-no-undef': 'error',
|
|
||||||
'react/jsx-tag-spacing': 'error',
|
'react/jsx-tag-spacing': 'error',
|
||||||
'react/jsx-uses-react': 'error',
|
|
||||||
'react/jsx-uses-vars': 'error',
|
|
||||||
'react/jsx-wrap-multilines': 'error',
|
'react/jsx-wrap-multilines': 'error',
|
||||||
'react/no-multi-comp': 'off',
|
'react/no-deprecated': 'off',
|
||||||
'react/no-string-refs': 'error',
|
'react/no-unknown-property': 'off',
|
||||||
'react/prop-types': 'error',
|
|
||||||
'react/self-closing-comp': 'error',
|
'react/self-closing-comp': 'error',
|
||||||
|
|
||||||
|
// recommended values found in https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/src/index.js
|
||||||
'jsx-a11y/accessible-emoji': 'warn',
|
'jsx-a11y/accessible-emoji': 'warn',
|
||||||
'jsx-a11y/alt-text': 'warn',
|
'jsx-a11y/click-events-have-key-events': 'off',
|
||||||
'jsx-a11y/anchor-has-content': 'warn',
|
'jsx-a11y/label-has-associated-control': 'off',
|
||||||
'jsx-a11y/anchor-is-valid': [
|
'jsx-a11y/media-has-caption': 'off',
|
||||||
'warn',
|
'jsx-a11y/no-autofocus': 'off',
|
||||||
{
|
// recommended rule is:
|
||||||
components: [
|
// 'jsx-a11y/no-interactive-element-to-noninteractive-role': [
|
||||||
'Link',
|
// 'error',
|
||||||
'NavLink',
|
// {
|
||||||
],
|
// tr: ['none', 'presentation'],
|
||||||
specialLink: [
|
// canvas: ['img'],
|
||||||
'to',
|
// },
|
||||||
],
|
// ],
|
||||||
aspect: [
|
'jsx-a11y/no-interactive-element-to-noninteractive-role': 'off',
|
||||||
'noHref',
|
// recommended rule is:
|
||||||
'invalidHref',
|
// 'jsx-a11y/no-noninteractive-element-interactions': [
|
||||||
'preferButton',
|
// 'error',
|
||||||
],
|
// {
|
||||||
},
|
// body: ['onError', 'onLoad'],
|
||||||
],
|
// iframe: ['onError', 'onLoad'],
|
||||||
'jsx-a11y/aria-activedescendant-has-tabindex': 'warn',
|
// img: ['onError', 'onLoad'],
|
||||||
'jsx-a11y/aria-props': 'warn',
|
// },
|
||||||
'jsx-a11y/aria-proptypes': 'warn',
|
// ],
|
||||||
'jsx-a11y/aria-role': 'warn',
|
|
||||||
'jsx-a11y/aria-unsupported-elements': 'warn',
|
|
||||||
'jsx-a11y/heading-has-content': 'warn',
|
|
||||||
'jsx-a11y/html-has-lang': 'warn',
|
|
||||||
'jsx-a11y/iframe-has-title': 'warn',
|
|
||||||
'jsx-a11y/img-redundant-alt': 'warn',
|
|
||||||
'jsx-a11y/interactive-supports-focus': 'warn',
|
|
||||||
'jsx-a11y/label-has-for': 'off',
|
|
||||||
'jsx-a11y/mouse-events-have-key-events': 'warn',
|
|
||||||
'jsx-a11y/no-access-key': 'warn',
|
|
||||||
'jsx-a11y/no-distracting-elements': 'warn',
|
|
||||||
'jsx-a11y/no-noninteractive-element-interactions': [
|
'jsx-a11y/no-noninteractive-element-interactions': [
|
||||||
'warn',
|
'warn',
|
||||||
{
|
{
|
||||||
|
@ -170,8 +157,18 @@ module.exports = {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
// recommended rule is:
|
||||||
|
// 'jsx-a11y/no-noninteractive-tabindex': [
|
||||||
|
// 'error',
|
||||||
|
// {
|
||||||
|
// tags: [],
|
||||||
|
// roles: ['tabpanel'],
|
||||||
|
// allowExpressionValues: true,
|
||||||
|
// },
|
||||||
|
// ],
|
||||||
|
'jsx-a11y/no-noninteractive-tabindex': 'off',
|
||||||
'jsx-a11y/no-onchange': 'warn',
|
'jsx-a11y/no-onchange': 'warn',
|
||||||
'jsx-a11y/no-redundant-roles': 'warn',
|
// recommended is full 'error'
|
||||||
'jsx-a11y/no-static-element-interactions': [
|
'jsx-a11y/no-static-element-interactions': [
|
||||||
'warn',
|
'warn',
|
||||||
{
|
{
|
||||||
|
@ -180,10 +177,6 @@ module.exports = {
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'jsx-a11y/role-has-required-aria-props': 'warn',
|
|
||||||
'jsx-a11y/role-supports-aria-props': 'off',
|
|
||||||
'jsx-a11y/scope': 'warn',
|
|
||||||
'jsx-a11y/tabindex-no-positive': 'warn',
|
|
||||||
|
|
||||||
'import/extensions': [
|
'import/extensions': [
|
||||||
'error',
|
'error',
|
||||||
|
|
8
.github/workflows/build-image.yml
vendored
8
.github/workflows/build-image.yml
vendored
|
@ -15,6 +15,11 @@ permissions:
|
||||||
jobs:
|
jobs:
|
||||||
build-image:
|
build-image:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.ref }}
|
||||||
|
cancel-in-progress: true
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: hadolint/hadolint-action@v3.1.0
|
- uses: hadolint/hadolint-action@v3.1.0
|
||||||
|
@ -34,10 +39,11 @@ jobs:
|
||||||
type=raw,value=latest,enable={{is_default_branch}}
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
type=edge,branch=main
|
type=edge,branch=main
|
||||||
type=sha,prefix=,format=long
|
type=sha,prefix=,format=long
|
||||||
- uses: docker/build-push-action@v3
|
- uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
|
provenance: false
|
||||||
builder: ${{ steps.buildx.outputs.name }}
|
builder: ${{ steps.buildx.outputs.name }}
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
|
48
.github/workflows/lint-css.yml
vendored
Normal file
48
.github/workflows/lint-css.yml
vendored
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
name: CSS Linting
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'dependabot/**'
|
||||||
|
paths:
|
||||||
|
- 'package.json'
|
||||||
|
- 'yarn.lock'
|
||||||
|
- '.prettier*'
|
||||||
|
- 'stylelint.config.js'
|
||||||
|
- '**/*.css'
|
||||||
|
- '**/*.scss'
|
||||||
|
- '.github/workflows/lint-css.yml'
|
||||||
|
- '.github/stylelint-matcher.json'
|
||||||
|
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'package.json'
|
||||||
|
- 'yarn.lock'
|
||||||
|
- '.prettier*'
|
||||||
|
- 'stylelint.config.js'
|
||||||
|
- '**/*.css'
|
||||||
|
- '**/*.scss'
|
||||||
|
- '.github/workflows/lint-css.yml'
|
||||||
|
- '.github/stylelint-matcher.json'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
cache: yarn
|
||||||
|
|
||||||
|
- name: Install all yarn packages
|
||||||
|
run: yarn --frozen-lockfile
|
||||||
|
|
||||||
|
- uses: xt0rted/stylelint-problem-matcher@v1
|
||||||
|
|
||||||
|
- run: echo "::add-matcher::.github/stylelint-matcher.json"
|
||||||
|
|
||||||
|
- name: Stylelint
|
||||||
|
run: yarn test:lint:sass
|
40
.github/workflows/lint-js.yml
vendored
Normal file
40
.github/workflows/lint-js.yml
vendored
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
name: JavaScript Linting
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'dependabot/**'
|
||||||
|
paths:
|
||||||
|
- 'package.json'
|
||||||
|
- 'yarn.lock'
|
||||||
|
- '.prettier*'
|
||||||
|
- '.eslint*'
|
||||||
|
- '**/*.js'
|
||||||
|
- '.github/workflows/lint-js.yml'
|
||||||
|
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'package.json'
|
||||||
|
- 'yarn.lock'
|
||||||
|
- '.prettier*'
|
||||||
|
- '.eslint*'
|
||||||
|
- '**/*.js'
|
||||||
|
- '.github/workflows/lint-js.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Clone repository
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
- name: Set up Node.js
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
cache: yarn
|
||||||
|
|
||||||
|
- name: Install all yarn packages
|
||||||
|
run: yarn --frozen-lockfile
|
||||||
|
|
||||||
|
- name: ESLint
|
||||||
|
run: yarn test:lint:js
|
2
.github/workflows/lint-json.yml
vendored
2
.github/workflows/lint-json.yml
vendored
|
@ -9,6 +9,7 @@ on:
|
||||||
- '.prettier*'
|
- '.prettier*'
|
||||||
- '**/*.json'
|
- '**/*.json'
|
||||||
- '.github/workflows/lint-json.yml'
|
- '.github/workflows/lint-json.yml'
|
||||||
|
- '!app/javascript/mastodon/locales/*.json'
|
||||||
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
|
@ -17,6 +18,7 @@ on:
|
||||||
- '.prettier*'
|
- '.prettier*'
|
||||||
- '**/*.json'
|
- '**/*.json'
|
||||||
- '.github/workflows/lint-json.yml'
|
- '.github/workflows/lint-json.yml'
|
||||||
|
- '!app/javascript/mastodon/locales/*.json'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
|
|
41
.github/workflows/lint-ruby.yml
vendored
Normal file
41
.github/workflows/lint-ruby.yml
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
name: Ruby Linting
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches-ignore:
|
||||||
|
- 'dependabot/**'
|
||||||
|
paths:
|
||||||
|
- 'Gemfile*'
|
||||||
|
- '.rubocop.yml'
|
||||||
|
- '**/*.rb'
|
||||||
|
- '**/*.rake'
|
||||||
|
- '.github/workflows/lint-ruby.yml'
|
||||||
|
|
||||||
|
pull_request:
|
||||||
|
paths:
|
||||||
|
- 'Gemfile*'
|
||||||
|
- '.rubocop.yml'
|
||||||
|
- '**/*.rb'
|
||||||
|
- '**/*.rake'
|
||||||
|
- '.github/workflows/lint-ruby.yml'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
lint:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Set-up RuboCop Problem Mathcher
|
||||||
|
uses: r7kamura/rubocop-problem-matchers-action@v1
|
||||||
|
|
||||||
|
- name: Run rubocop
|
||||||
|
uses: github/super-linter@v4
|
||||||
|
env:
|
||||||
|
DEFAULT_BRANCH: main
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
LINTER_RULES_PATH: .
|
||||||
|
RUBY_CONFIG_FILE: .rubocop.yml
|
||||||
|
VALIDATE_ALL_CODEBASE: false
|
||||||
|
VALIDATE_RUBY: true
|
2
.github/workflows/lint-yml.yml
vendored
2
.github/workflows/lint-yml.yml
vendored
|
@ -10,6 +10,7 @@ on:
|
||||||
- '**/*.yaml'
|
- '**/*.yaml'
|
||||||
- '**/*.yml'
|
- '**/*.yml'
|
||||||
- '.github/workflows/lint-yml.yml'
|
- '.github/workflows/lint-yml.yml'
|
||||||
|
- '!config/locales/*.yml'
|
||||||
|
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
|
@ -19,6 +20,7 @@ on:
|
||||||
- '**/*.yaml'
|
- '**/*.yaml'
|
||||||
- '**/*.yml'
|
- '**/*.yml'
|
||||||
- '.github/workflows/lint-yml.yml'
|
- '.github/workflows/lint-yml.yml'
|
||||||
|
- '!config/locales/*.yml'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lint:
|
lint:
|
||||||
|
|
83
.github/workflows/linter.yml
vendored
83
.github/workflows/linter.yml
vendored
|
@ -1,83 +0,0 @@
|
||||||
---
|
|
||||||
#################################
|
|
||||||
#################################
|
|
||||||
## Super Linter GitHub Actions ##
|
|
||||||
#################################
|
|
||||||
#################################
|
|
||||||
name: Lint Code Base
|
|
||||||
|
|
||||||
#
|
|
||||||
# Documentation:
|
|
||||||
# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
|
|
||||||
#
|
|
||||||
|
|
||||||
#############################
|
|
||||||
# Start the job on all push #
|
|
||||||
#############################
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches-ignore: [main]
|
|
||||||
# Remove the line above to run when pushing to master
|
|
||||||
pull_request:
|
|
||||||
branches: [main]
|
|
||||||
|
|
||||||
###############
|
|
||||||
# Set the Job #
|
|
||||||
###############
|
|
||||||
permissions:
|
|
||||||
checks: write
|
|
||||||
contents: read
|
|
||||||
pull-requests: write
|
|
||||||
statuses: write
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
# Name the Job
|
|
||||||
name: Lint Code Base
|
|
||||||
# Set the agent to run on
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
##################
|
|
||||||
# Load all steps #
|
|
||||||
##################
|
|
||||||
steps:
|
|
||||||
##########################
|
|
||||||
# Checkout the code base #
|
|
||||||
##########################
|
|
||||||
- name: Checkout Code
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
# Full git history is needed to get a proper list of changed files within `super-linter`
|
|
||||||
fetch-depth: 0
|
|
||||||
|
|
||||||
- name: Set-up Node.js
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version-file: .nvmrc
|
|
||||||
cache: yarn
|
|
||||||
- name: Install dependencies
|
|
||||||
run: yarn install --frozen-lockfile
|
|
||||||
- name: Set-up RuboCop Problem Mathcher
|
|
||||||
uses: r7kamura/rubocop-problem-matchers-action@v1
|
|
||||||
- name: Set-up Stylelint Problem Matcher
|
|
||||||
uses: xt0rted/stylelint-problem-matcher@v1
|
|
||||||
# https://github.com/xt0rted/stylelint-problem-matcher/issues/360
|
|
||||||
- run: echo "::add-matcher::.github/stylelint-matcher.json"
|
|
||||||
|
|
||||||
################################
|
|
||||||
# Run Linter against code base #
|
|
||||||
################################
|
|
||||||
- name: Lint Code Base
|
|
||||||
uses: github/super-linter@v4
|
|
||||||
env:
|
|
||||||
CSS_FILE_NAME: stylelint.config.js
|
|
||||||
DEFAULT_BRANCH: main
|
|
||||||
NO_COLOR: 1 # https://github.com/xt0rted/stylelint-problem-matcher/issues/360
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
JAVASCRIPT_ES_CONFIG_FILE: .eslintrc.js
|
|
||||||
LINTER_RULES_PATH: .
|
|
||||||
RUBY_CONFIG_FILE: .rubocop.yml
|
|
||||||
VALIDATE_ALL_CODEBASE: false
|
|
||||||
VALIDATE_CSS: true
|
|
||||||
VALIDATE_JAVASCRIPT_ES: true
|
|
||||||
VALIDATE_RUBY: true
|
|
13
CHANGELOG.md
13
CHANGELOG.md
|
@ -38,8 +38,10 @@ All notable changes to this project will be documented in this file.
|
||||||
- Add brotli compression to `assets:precompile` ([Izorkin](https://github.com/mastodon/mastodon/pull/19025))
|
- Add brotli compression to `assets:precompile` ([Izorkin](https://github.com/mastodon/mastodon/pull/19025))
|
||||||
- Add “disabled” account filter to the `/admin/accounts` UI ([tribela](https://github.com/mastodon/mastodon/pull/21282))
|
- Add “disabled” account filter to the `/admin/accounts` UI ([tribela](https://github.com/mastodon/mastodon/pull/21282))
|
||||||
- Add transparency to modal background for accessibility ([edent](https://github.com/mastodon/mastodon/pull/18081))
|
- Add transparency to modal background for accessibility ([edent](https://github.com/mastodon/mastodon/pull/18081))
|
||||||
|
- Add `lang` attribute to image description textarea and poll option field ([c960657](https://github.com/mastodon/mastodon/pull/23293))
|
||||||
- Add `title` attribute to video elements in media attachments ([bramus](https://github.com/mastodon/mastodon/pull/21420))
|
- Add `title` attribute to video elements in media attachments ([bramus](https://github.com/mastodon/mastodon/pull/21420))
|
||||||
- Add left and right margins to emojis ([dsblank](https://github.com/mastodon/mastodon/pull/20464))
|
- Add left and right margins to emojis ([dsblank](https://github.com/mastodon/mastodon/pull/20464))
|
||||||
|
- Add `roles` attribute to `Account` entities in REST API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23255))
|
||||||
- Add `reading:autoplay:gifs` to `/api/v1/preferences` ([j-f1](https://github.com/mastodon/mastodon/pull/22706))
|
- Add `reading:autoplay:gifs` to `/api/v1/preferences` ([j-f1](https://github.com/mastodon/mastodon/pull/22706))
|
||||||
- Add `hide_collections` parameter to `/api/v1/accounts/credentials` ([CarlSchwan](https://github.com/mastodon/mastodon/pull/22790))
|
- Add `hide_collections` parameter to `/api/v1/accounts/credentials` ([CarlSchwan](https://github.com/mastodon/mastodon/pull/22790))
|
||||||
- Add `policy` attribute to web push subscription objects in `/api/v1/push/subscriptions` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23210))
|
- Add `policy` attribute to web push subscription objects in `/api/v1/push/subscriptions` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23210))
|
||||||
|
@ -67,8 +69,13 @@ All notable changes to this project will be documented in this file.
|
||||||
- Change confirm prompts for relationships management ([tribela](https://github.com/mastodon/mastodon/pull/19411))
|
- Change confirm prompts for relationships management ([tribela](https://github.com/mastodon/mastodon/pull/19411))
|
||||||
- Change language surrounding disability in prompts for media descriptions ([hs4man21](https://github.com/mastodon/mastodon/pull/20923))
|
- Change language surrounding disability in prompts for media descriptions ([hs4man21](https://github.com/mastodon/mastodon/pull/20923))
|
||||||
- Change confusing wording in the sign in banner ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22490))
|
- Change confusing wording in the sign in banner ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22490))
|
||||||
|
- Change `POST /settings/applications/:id` to regenerate token on scopes change ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23359))
|
||||||
- Change account moderation notes to make links clickable ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22553))
|
- Change account moderation notes to make links clickable ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22553))
|
||||||
|
- Change link previews for statuses to never use avatar as fallback ([Gargron](https://github.com/mastodon/mastodon/pull/23376))
|
||||||
- Change email address input to be read-only for logged-in users when requesting a new confirmation e-mail ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23247))
|
- Change email address input to be read-only for logged-in users when requesting a new confirmation e-mail ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23247))
|
||||||
|
- Change notifications per page from 15 to 40 in REST API ([Gargron](https://github.com/mastodon/mastodon/pull/23348))
|
||||||
|
- Change number of stored items in home feed from 400 to 800 ([Gargron](https://github.com/mastodon/mastodon/pull/23349))
|
||||||
|
- Change API rate limits from 300/5min per user to 1500/5min per user, 300/5min per app ([Gargron](https://github.com/mastodon/mastodon/pull/23347))
|
||||||
- Save avatar or header correctly even if the other one fails ([tribela](https://github.com/mastodon/mastodon/pull/18465))
|
- Save avatar or header correctly even if the other one fails ([tribela](https://github.com/mastodon/mastodon/pull/18465))
|
||||||
- Change `referrer-policy` to `same-origin` application-wide ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23014), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23037))
|
- Change `referrer-policy` to `same-origin` application-wide ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23014), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23037))
|
||||||
- Add 'private' to `Cache-Control`, match Rails expectations ([daxtens](https://github.com/mastodon/mastodon/pull/20608))
|
- Add 'private' to `Cache-Control`, match Rails expectations ([daxtens](https://github.com/mastodon/mastodon/pull/20608))
|
||||||
|
@ -88,7 +95,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- Allow adding relays in secure mode and limited federation mode ([ineffyble](https://github.com/mastodon/mastodon/pull/22324))
|
- Allow adding relays in secure mode and limited federation mode ([ineffyble](https://github.com/mastodon/mastodon/pull/22324))
|
||||||
- Change timestamps to be displayed using the user's timezone throughout the moderation interface ([FrancisMurillo](https://github.com/mastodon/mastodon/pull/21878), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/22555))
|
- Change timestamps to be displayed using the user's timezone throughout the moderation interface ([FrancisMurillo](https://github.com/mastodon/mastodon/pull/21878), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/22555))
|
||||||
- Change CSP directives on API to be tight and concise ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20960))
|
- Change CSP directives on API to be tight and concise ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20960))
|
||||||
- Change web UI to not autofocus the compose form ([raboof](https://github.com/mastodon/mastodon/pull/16517))
|
- Change web UI to not autofocus the compose form ([raboof](https://github.com/mastodon/mastodon/pull/16517), [Akkiesoft](https://github.com/mastodon/mastodon/pull/23094))
|
||||||
- Change idempotency key handling for posting when database access is slow ([lambda](https://github.com/mastodon/mastodon/pull/21840))
|
- Change idempotency key handling for posting when database access is slow ([lambda](https://github.com/mastodon/mastodon/pull/21840))
|
||||||
- Change remote media files to be downloaded outside of transactions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21796))
|
- Change remote media files to be downloaded outside of transactions ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21796))
|
||||||
- Improve contrast of charts in “poll has ended” notifications ([j-f1](https://github.com/mastodon/mastodon/pull/22575))
|
- Improve contrast of charts in “poll has ended” notifications ([j-f1](https://github.com/mastodon/mastodon/pull/22575))
|
||||||
|
@ -101,6 +108,7 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
- Officially remove support for Ruby 2.6 ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21477))
|
- Officially remove support for Ruby 2.6 ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21477))
|
||||||
- Remove `object-fit` polyfill used for old versions of Microsoft Edge ([shuuji3](https://github.com/mastodon/mastodon/pull/22693))
|
- Remove `object-fit` polyfill used for old versions of Microsoft Edge ([shuuji3](https://github.com/mastodon/mastodon/pull/22693))
|
||||||
|
- Remove `intersection-observer` polyfill for old Safari support ([shuuji3](https://github.com/mastodon/mastodon/pull/23284))
|
||||||
- Remove empty `title` tag from mailer layout ([nametoolong](https://github.com/mastodon/mastodon/pull/23078))
|
- Remove empty `title` tag from mailer layout ([nametoolong](https://github.com/mastodon/mastodon/pull/23078))
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
@ -110,6 +118,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- Fix possible race conditions when suspending/unsuspending accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22363))
|
- Fix possible race conditions when suspending/unsuspending accounts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22363))
|
||||||
- Fix being stuck in edit mode when deleting the edited status ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22126))
|
- Fix being stuck in edit mode when deleting the edited status ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22126))
|
||||||
- Fix filters not being applied to some notification types ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23211))
|
- Fix filters not being applied to some notification types ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23211))
|
||||||
|
- Fix incorrect link in push notifications for some event types ([elizabeth-dev](https://github.com/mastodon/mastodon/pull/23286))
|
||||||
- Fix some performance issues with `/admin/instances` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21907))
|
- Fix some performance issues with `/admin/instances` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/21907))
|
||||||
- Fix some pre-4.0 admin audit logs ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22091))
|
- Fix some pre-4.0 admin audit logs ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22091))
|
||||||
- Fix moderation audit log items for warnings having incorrect links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23242))
|
- Fix moderation audit log items for warnings having incorrect links ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23242))
|
||||||
|
@ -126,6 +135,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- Fix wrong padding in RTL layout ([Gargron](https://github.com/mastodon/mastodon/pull/23157))
|
- Fix wrong padding in RTL layout ([Gargron](https://github.com/mastodon/mastodon/pull/23157))
|
||||||
- Fix drag & drop upload area display in single-column mode ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23217))
|
- Fix drag & drop upload area display in single-column mode ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23217))
|
||||||
- Fix being unable to get a single EmailDomainBlock from the admin API ([trwnh](https://github.com/mastodon/mastodon/pull/20846))
|
- Fix being unable to get a single EmailDomainBlock from the admin API ([trwnh](https://github.com/mastodon/mastodon/pull/20846))
|
||||||
|
- Fix unserialized `role` on account entities in admin API ([Gargron](https://github.com/mastodon/mastodon/pull/23290))
|
||||||
- Fix pagination of followed tags ([trwnh](https://github.com/mastodon/mastodon/pull/20861))
|
- Fix pagination of followed tags ([trwnh](https://github.com/mastodon/mastodon/pull/20861))
|
||||||
- Fix dropdown menu positions when scrolling ([sidp](https://github.com/mastodon/mastodon/pull/22916), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23062))
|
- Fix dropdown menu positions when scrolling ([sidp](https://github.com/mastodon/mastodon/pull/22916), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/23062))
|
||||||
- Fix email with empty domain name labels passing validation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23246))
|
- Fix email with empty domain name labels passing validation ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23246))
|
||||||
|
@ -150,6 +160,7 @@ All notable changes to this project will be documented in this file.
|
||||||
- Fix crash when trying to fetch unobtainable avatar of user using external authentication ([lochiiconnectivity](https://github.com/mastodon/mastodon/pull/22462))
|
- Fix crash when trying to fetch unobtainable avatar of user using external authentication ([lochiiconnectivity](https://github.com/mastodon/mastodon/pull/22462))
|
||||||
- Fix potential duplicate statuses in Explore tab ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22121))
|
- Fix potential duplicate statuses in Explore tab ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22121))
|
||||||
- Fix deprecation warning in `tootctl accounts rotate` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22120))
|
- Fix deprecation warning in `tootctl accounts rotate` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22120))
|
||||||
|
- Fix styling of featured tags in light theme ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/23252))
|
||||||
- Fix missing style in warning and strike cards ([AtelierSnek](https://github.com/mastodon/mastodon/pull/22177), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/22302))
|
- Fix missing style in warning and strike cards ([AtelierSnek](https://github.com/mastodon/mastodon/pull/22177), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/22302))
|
||||||
- Fix wasteful request to `/api/v1/custom_emojis` when not logged in ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22326))
|
- Fix wasteful request to `/api/v1/custom_emojis` when not logged in ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/22326))
|
||||||
- Fix replies sometimes being delivered to user-blocked domains ([tribela](https://github.com/mastodon/mastodon/pull/22117))
|
- Fix replies sometimes being delivered to user-blocked domains ([tribela](https://github.com/mastodon/mastodon/pull/22117))
|
||||||
|
|
8
Gemfile
8
Gemfile
|
@ -18,7 +18,7 @@ gem 'makara', '~> 0.5'
|
||||||
gem 'pghero'
|
gem 'pghero'
|
||||||
gem 'dotenv-rails', '~> 2.8'
|
gem 'dotenv-rails', '~> 2.8'
|
||||||
|
|
||||||
gem 'aws-sdk-s3', '~> 1.117', require: false
|
gem 'aws-sdk-s3', '~> 1.119', require: false
|
||||||
gem 'fog-core', '<= 2.4.0'
|
gem 'fog-core', '<= 2.4.0'
|
||||||
gem 'fog-openstack', '~> 0.3', require: false
|
gem 'fog-openstack', '~> 0.3', require: false
|
||||||
gem 'kt-paperclip', '~> 7.1'
|
gem 'kt-paperclip', '~> 7.1'
|
||||||
|
@ -40,7 +40,7 @@ end
|
||||||
gem 'net-ldap', '~> 0.17'
|
gem 'net-ldap', '~> 0.17'
|
||||||
gem 'omniauth-cas', '~> 2.0'
|
gem 'omniauth-cas', '~> 2.0'
|
||||||
gem 'omniauth-saml', '~> 1.10'
|
gem 'omniauth-saml', '~> 1.10'
|
||||||
gem 'gitlab-omniauth-openid-connect', '~>0.10.0', require: 'omniauth_openid_connect'
|
gem 'gitlab-omniauth-openid-connect', '~>0.10.1', require: 'omniauth_openid_connect'
|
||||||
gem 'omniauth', '~> 1.9'
|
gem 'omniauth', '~> 1.9'
|
||||||
gem 'omniauth-rails_csrf_protection', '~> 0.1'
|
gem 'omniauth-rails_csrf_protection', '~> 0.1'
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ gem 'rack-attack', '~> 6.6'
|
||||||
gem 'rack-cors', '~> 1.1', require: 'rack/cors'
|
gem 'rack-cors', '~> 1.1', require: 'rack/cors'
|
||||||
gem 'rails-i18n', '~> 6.0'
|
gem 'rails-i18n', '~> 6.0'
|
||||||
gem 'rails-settings-cached', '~> 0.6'
|
gem 'rails-settings-cached', '~> 0.6'
|
||||||
gem 'redcarpet', '~> 3.5'
|
gem 'redcarpet', '~> 3.6'
|
||||||
gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis']
|
gem 'redis', '~> 4.5', require: ['redis', 'redis/connection/hiredis']
|
||||||
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
gem 'mario-redis-lock', '~> 1.2', require: 'redis_lock'
|
||||||
gem 'rqrcode', '~> 2.1'
|
gem 'rqrcode', '~> 2.1'
|
||||||
|
@ -85,7 +85,7 @@ gem 'sidekiq-scheduler', '~> 4.0'
|
||||||
gem 'sidekiq-unique-jobs', '~> 7.1'
|
gem 'sidekiq-unique-jobs', '~> 7.1'
|
||||||
gem 'sidekiq-bulk', '~> 0.2.0'
|
gem 'sidekiq-bulk', '~> 0.2.0'
|
||||||
gem 'simple-navigation', '~> 4.4'
|
gem 'simple-navigation', '~> 4.4'
|
||||||
gem 'simple_form', '~> 5.1'
|
gem 'simple_form', '~> 5.2'
|
||||||
gem 'sprockets-rails', '~> 3.4', require: 'sprockets/railtie'
|
gem 'sprockets-rails', '~> 3.4', require: 'sprockets/railtie'
|
||||||
gem 'stoplight', '~> 3.0.1'
|
gem 'stoplight', '~> 3.0.1'
|
||||||
gem 'strong_migrations', '~> 0.7'
|
gem 'strong_migrations', '~> 0.7'
|
||||||
|
|
166
Gemfile.lock
166
Gemfile.lock
|
@ -10,40 +10,40 @@ GIT
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (6.1.7.1)
|
actioncable (6.1.7.2)
|
||||||
actionpack (= 6.1.7.1)
|
actionpack (= 6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
nio4r (~> 2.0)
|
nio4r (~> 2.0)
|
||||||
websocket-driver (>= 0.6.1)
|
websocket-driver (>= 0.6.1)
|
||||||
actionmailbox (6.1.7.1)
|
actionmailbox (6.1.7.2)
|
||||||
actionpack (= 6.1.7.1)
|
actionpack (= 6.1.7.2)
|
||||||
activejob (= 6.1.7.1)
|
activejob (= 6.1.7.2)
|
||||||
activerecord (= 6.1.7.1)
|
activerecord (= 6.1.7.2)
|
||||||
activestorage (= 6.1.7.1)
|
activestorage (= 6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
mail (>= 2.7.1)
|
mail (>= 2.7.1)
|
||||||
actionmailer (6.1.7.1)
|
actionmailer (6.1.7.2)
|
||||||
actionpack (= 6.1.7.1)
|
actionpack (= 6.1.7.2)
|
||||||
actionview (= 6.1.7.1)
|
actionview (= 6.1.7.2)
|
||||||
activejob (= 6.1.7.1)
|
activejob (= 6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
actionpack (6.1.7.1)
|
actionpack (6.1.7.2)
|
||||||
actionview (= 6.1.7.1)
|
actionview (= 6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
rack (~> 2.0, >= 2.0.9)
|
rack (~> 2.0, >= 2.0.9)
|
||||||
rack-test (>= 0.6.3)
|
rack-test (>= 0.6.3)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||||
actiontext (6.1.7.1)
|
actiontext (6.1.7.2)
|
||||||
actionpack (= 6.1.7.1)
|
actionpack (= 6.1.7.2)
|
||||||
activerecord (= 6.1.7.1)
|
activerecord (= 6.1.7.2)
|
||||||
activestorage (= 6.1.7.1)
|
activestorage (= 6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
nokogiri (>= 1.8.5)
|
nokogiri (>= 1.8.5)
|
||||||
actionview (6.1.7.1)
|
actionview (6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
|
@ -54,22 +54,22 @@ GEM
|
||||||
case_transform (>= 0.2)
|
case_transform (>= 0.2)
|
||||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
jsonapi-renderer (>= 0.1.1.beta1, < 0.3)
|
||||||
active_record_query_trace (1.8)
|
active_record_query_trace (1.8)
|
||||||
activejob (6.1.7.1)
|
activejob (6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (6.1.7.1)
|
activemodel (6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
activerecord (6.1.7.1)
|
activerecord (6.1.7.2)
|
||||||
activemodel (= 6.1.7.1)
|
activemodel (= 6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
activestorage (6.1.7.1)
|
activestorage (6.1.7.2)
|
||||||
actionpack (= 6.1.7.1)
|
actionpack (= 6.1.7.2)
|
||||||
activejob (= 6.1.7.1)
|
activejob (= 6.1.7.2)
|
||||||
activerecord (= 6.1.7.1)
|
activerecord (= 6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
marcel (~> 1.0)
|
marcel (~> 1.0)
|
||||||
mini_mime (>= 1.1.0)
|
mini_mime (>= 1.1.0)
|
||||||
activesupport (6.1.7.1)
|
activesupport (6.1.7.2)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 1.6, < 2)
|
i18n (>= 1.6, < 2)
|
||||||
minitest (>= 5.1)
|
minitest (>= 5.1)
|
||||||
|
@ -90,16 +90,16 @@ GEM
|
||||||
attr_required (1.0.1)
|
attr_required (1.0.1)
|
||||||
awrence (1.2.1)
|
awrence (1.2.1)
|
||||||
aws-eventstream (1.2.0)
|
aws-eventstream (1.2.0)
|
||||||
aws-partitions (1.670.0)
|
aws-partitions (1.701.0)
|
||||||
aws-sdk-core (3.168.2)
|
aws-sdk-core (3.170.0)
|
||||||
aws-eventstream (~> 1, >= 1.0.2)
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
aws-partitions (~> 1, >= 1.651.0)
|
aws-partitions (~> 1, >= 1.651.0)
|
||||||
aws-sigv4 (~> 1.5)
|
aws-sigv4 (~> 1.5)
|
||||||
jmespath (~> 1, >= 1.6.1)
|
jmespath (~> 1, >= 1.6.1)
|
||||||
aws-sdk-kms (1.60.0)
|
aws-sdk-kms (1.62.0)
|
||||||
aws-sdk-core (~> 3, >= 3.165.0)
|
aws-sdk-core (~> 3, >= 3.165.0)
|
||||||
aws-sigv4 (~> 1.1)
|
aws-sigv4 (~> 1.1)
|
||||||
aws-sdk-s3 (1.117.2)
|
aws-sdk-s3 (1.119.0)
|
||||||
aws-sdk-core (~> 3, >= 3.165.0)
|
aws-sdk-core (~> 3, >= 3.165.0)
|
||||||
aws-sdk-kms (~> 1)
|
aws-sdk-kms (~> 1)
|
||||||
aws-sigv4 (~> 1.4)
|
aws-sigv4 (~> 1.4)
|
||||||
|
@ -117,7 +117,7 @@ GEM
|
||||||
erubi (~> 1.4)
|
erubi (~> 1.4)
|
||||||
parser (>= 2.4)
|
parser (>= 2.4)
|
||||||
smart_properties
|
smart_properties
|
||||||
bindata (2.4.10)
|
bindata (2.4.14)
|
||||||
binding_of_caller (1.0.0)
|
binding_of_caller (1.0.0)
|
||||||
debug_inspector (>= 0.0.1)
|
debug_inspector (>= 0.0.1)
|
||||||
blurhash (0.1.6)
|
blurhash (0.1.6)
|
||||||
|
@ -207,7 +207,7 @@ GEM
|
||||||
docile (1.4.0)
|
docile (1.4.0)
|
||||||
domain_name (0.5.20190701)
|
domain_name (0.5.20190701)
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
doorkeeper (5.6.2)
|
doorkeeper (5.6.3)
|
||||||
railties (>= 5)
|
railties (>= 5)
|
||||||
dotenv (2.8.1)
|
dotenv (2.8.1)
|
||||||
dotenv-rails (2.8.1)
|
dotenv-rails (2.8.1)
|
||||||
|
@ -279,11 +279,11 @@ GEM
|
||||||
fuubar (2.5.1)
|
fuubar (2.5.1)
|
||||||
rspec-core (~> 3.0)
|
rspec-core (~> 3.0)
|
||||||
ruby-progressbar (~> 1.4)
|
ruby-progressbar (~> 1.4)
|
||||||
gitlab-omniauth-openid-connect (0.10.0)
|
gitlab-omniauth-openid-connect (0.10.1)
|
||||||
addressable (~> 2.7)
|
addressable (~> 2.7)
|
||||||
omniauth (>= 1.9, < 3)
|
omniauth (>= 1.9, < 3)
|
||||||
openid_connect (~> 1.2)
|
openid_connect (~> 1.2)
|
||||||
globalid (1.0.1)
|
globalid (1.1.0)
|
||||||
activesupport (>= 5.0)
|
activesupport (>= 5.0)
|
||||||
hamlit (2.13.0)
|
hamlit (2.13.0)
|
||||||
temple (>= 0.8.2)
|
temple (>= 0.8.2)
|
||||||
|
@ -333,10 +333,11 @@ GEM
|
||||||
jmespath (1.6.2)
|
jmespath (1.6.2)
|
||||||
json (2.6.3)
|
json (2.6.3)
|
||||||
json-canonicalization (0.3.0)
|
json-canonicalization (0.3.0)
|
||||||
json-jwt (1.14.0)
|
json-jwt (1.15.3)
|
||||||
activesupport (>= 4.2)
|
activesupport (>= 4.2)
|
||||||
aes_key_wrap
|
aes_key_wrap
|
||||||
bindata
|
bindata
|
||||||
|
httpclient
|
||||||
json-ld (3.2.3)
|
json-ld (3.2.3)
|
||||||
htmlentities (~> 4.3)
|
htmlentities (~> 4.3)
|
||||||
json-canonicalization (~> 0.3)
|
json-canonicalization (~> 0.3)
|
||||||
|
@ -418,7 +419,7 @@ GEM
|
||||||
net-ldap (0.17.1)
|
net-ldap (0.17.1)
|
||||||
net-pop (0.1.2)
|
net-pop (0.1.2)
|
||||||
net-protocol
|
net-protocol
|
||||||
net-protocol (0.1.3)
|
net-protocol (0.2.1)
|
||||||
timeout
|
timeout
|
||||||
net-scp (4.0.0.rc1)
|
net-scp (4.0.0.rc1)
|
||||||
net-ssh (>= 2.6.5, < 8.0.0)
|
net-ssh (>= 2.6.5, < 8.0.0)
|
||||||
|
@ -426,7 +427,7 @@ GEM
|
||||||
net-protocol
|
net-protocol
|
||||||
net-ssh (7.0.1)
|
net-ssh (7.0.1)
|
||||||
nio4r (2.5.8)
|
nio4r (2.5.8)
|
||||||
nokogiri (1.14.0)
|
nokogiri (1.14.1)
|
||||||
mini_portile2 (~> 2.8.0)
|
mini_portile2 (~> 2.8.0)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
nsa (0.2.8)
|
nsa (0.2.8)
|
||||||
|
@ -448,21 +449,22 @@ GEM
|
||||||
omniauth-saml (1.10.3)
|
omniauth-saml (1.10.3)
|
||||||
omniauth (~> 1.3, >= 1.3.2)
|
omniauth (~> 1.3, >= 1.3.2)
|
||||||
ruby-saml (~> 1.9)
|
ruby-saml (~> 1.9)
|
||||||
openid_connect (1.3.0)
|
openid_connect (1.4.2)
|
||||||
activemodel
|
activemodel
|
||||||
attr_required (>= 1.0.0)
|
attr_required (>= 1.0.0)
|
||||||
json-jwt (>= 1.5.0)
|
json-jwt (>= 1.15.0)
|
||||||
rack-oauth2 (>= 1.6.1)
|
net-smtp
|
||||||
swd (>= 1.0.0)
|
rack-oauth2 (~> 1.21)
|
||||||
|
swd (~> 1.3)
|
||||||
tzinfo
|
tzinfo
|
||||||
validate_email
|
validate_email
|
||||||
validate_url
|
validate_url
|
||||||
webfinger (>= 1.0.1)
|
webfinger (~> 1.2)
|
||||||
openssl (3.0.0)
|
openssl (3.0.0)
|
||||||
openssl-signature_algorithm (1.2.1)
|
openssl-signature_algorithm (1.2.1)
|
||||||
openssl (> 2.0, < 3.1)
|
openssl (> 2.0, < 3.1)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
ox (2.14.13)
|
ox (2.14.14)
|
||||||
parallel (1.22.1)
|
parallel (1.22.1)
|
||||||
parser (3.2.0.0)
|
parser (3.2.0.0)
|
||||||
ast (~> 2.4.1)
|
ast (~> 2.4.1)
|
||||||
|
@ -503,7 +505,7 @@ GEM
|
||||||
rack (>= 1.0, < 3)
|
rack (>= 1.0, < 3)
|
||||||
rack-cors (1.1.1)
|
rack-cors (1.1.1)
|
||||||
rack (>= 2.0.0)
|
rack (>= 2.0.0)
|
||||||
rack-oauth2 (1.19.0)
|
rack-oauth2 (1.21.3)
|
||||||
activesupport
|
activesupport
|
||||||
attr_required
|
attr_required
|
||||||
httpclient
|
httpclient
|
||||||
|
@ -513,20 +515,20 @@ GEM
|
||||||
rack
|
rack
|
||||||
rack-test (2.0.2)
|
rack-test (2.0.2)
|
||||||
rack (>= 1.3)
|
rack (>= 1.3)
|
||||||
rails (6.1.7.1)
|
rails (6.1.7.2)
|
||||||
actioncable (= 6.1.7.1)
|
actioncable (= 6.1.7.2)
|
||||||
actionmailbox (= 6.1.7.1)
|
actionmailbox (= 6.1.7.2)
|
||||||
actionmailer (= 6.1.7.1)
|
actionmailer (= 6.1.7.2)
|
||||||
actionpack (= 6.1.7.1)
|
actionpack (= 6.1.7.2)
|
||||||
actiontext (= 6.1.7.1)
|
actiontext (= 6.1.7.2)
|
||||||
actionview (= 6.1.7.1)
|
actionview (= 6.1.7.2)
|
||||||
activejob (= 6.1.7.1)
|
activejob (= 6.1.7.2)
|
||||||
activemodel (= 6.1.7.1)
|
activemodel (= 6.1.7.2)
|
||||||
activerecord (= 6.1.7.1)
|
activerecord (= 6.1.7.2)
|
||||||
activestorage (= 6.1.7.1)
|
activestorage (= 6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
bundler (>= 1.15.0)
|
bundler (>= 1.15.0)
|
||||||
railties (= 6.1.7.1)
|
railties (= 6.1.7.2)
|
||||||
sprockets-rails (>= 2.0.0)
|
sprockets-rails (>= 2.0.0)
|
||||||
rails-controller-testing (1.0.5)
|
rails-controller-testing (1.0.5)
|
||||||
actionpack (>= 5.0.1.rc1)
|
actionpack (>= 5.0.1.rc1)
|
||||||
|
@ -535,16 +537,16 @@ GEM
|
||||||
rails-dom-testing (2.0.3)
|
rails-dom-testing (2.0.3)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
nokogiri (>= 1.6)
|
nokogiri (>= 1.6)
|
||||||
rails-html-sanitizer (1.4.4)
|
rails-html-sanitizer (1.5.0)
|
||||||
loofah (~> 2.19, >= 2.19.1)
|
loofah (~> 2.19, >= 2.19.1)
|
||||||
rails-i18n (6.0.0)
|
rails-i18n (6.0.0)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
railties (>= 6.0.0, < 7)
|
railties (>= 6.0.0, < 7)
|
||||||
rails-settings-cached (0.6.6)
|
rails-settings-cached (0.6.6)
|
||||||
rails (>= 4.2.0)
|
rails (>= 4.2.0)
|
||||||
railties (6.1.7.1)
|
railties (6.1.7.2)
|
||||||
actionpack (= 6.1.7.1)
|
actionpack (= 6.1.7.2)
|
||||||
activesupport (= 6.1.7.1)
|
activesupport (= 6.1.7.2)
|
||||||
method_source
|
method_source
|
||||||
rake (>= 12.2)
|
rake (>= 12.2)
|
||||||
thor (~> 1.0)
|
thor (~> 1.0)
|
||||||
|
@ -554,7 +556,7 @@ GEM
|
||||||
link_header (~> 0.0, >= 0.0.8)
|
link_header (~> 0.0, >= 0.0.8)
|
||||||
rdf-normalize (0.5.1)
|
rdf-normalize (0.5.1)
|
||||||
rdf (~> 3.2)
|
rdf (~> 3.2)
|
||||||
redcarpet (3.5.1)
|
redcarpet (3.6.0)
|
||||||
redis (4.5.1)
|
redis (4.5.1)
|
||||||
redis-namespace (1.10.0)
|
redis-namespace (1.10.0)
|
||||||
redis (>= 4)
|
redis (>= 4)
|
||||||
|
@ -595,7 +597,7 @@ GEM
|
||||||
rspec-support (3.11.1)
|
rspec-support (3.11.1)
|
||||||
rspec_junit_formatter (0.6.0)
|
rspec_junit_formatter (0.6.0)
|
||||||
rspec-core (>= 2, < 4, != 2.12.0)
|
rspec-core (>= 2, < 4, != 2.12.0)
|
||||||
rubocop (1.44.0)
|
rubocop (1.44.1)
|
||||||
json (~> 2.3)
|
json (~> 2.3)
|
||||||
parallel (~> 1.10)
|
parallel (~> 1.10)
|
||||||
parser (>= 3.2.0.0)
|
parser (>= 3.2.0.0)
|
||||||
|
@ -628,7 +630,7 @@ GEM
|
||||||
fugit (~> 1.1, >= 1.1.6)
|
fugit (~> 1.1, >= 1.1.6)
|
||||||
safety_net_attestation (0.4.0)
|
safety_net_attestation (0.4.0)
|
||||||
jwt (~> 2.0)
|
jwt (~> 2.0)
|
||||||
sanitize (6.0.0)
|
sanitize (6.0.1)
|
||||||
crass (~> 1.0.2)
|
crass (~> 1.0.2)
|
||||||
nokogiri (>= 1.12.0)
|
nokogiri (>= 1.12.0)
|
||||||
scenic (1.7.0)
|
scenic (1.7.0)
|
||||||
|
@ -654,7 +656,7 @@ GEM
|
||||||
thor (>= 0.20, < 3.0)
|
thor (>= 0.20, < 3.0)
|
||||||
simple-navigation (4.4.0)
|
simple-navigation (4.4.0)
|
||||||
activesupport (>= 2.3.2)
|
activesupport (>= 2.3.2)
|
||||||
simple_form (5.1.0)
|
simple_form (5.2.0)
|
||||||
actionpack (>= 5.2)
|
actionpack (>= 5.2)
|
||||||
activemodel (>= 5.2)
|
activemodel (>= 5.2)
|
||||||
simplecov (0.22.0)
|
simplecov (0.22.0)
|
||||||
|
@ -691,7 +693,7 @@ GEM
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
thor (1.2.1)
|
thor (1.2.1)
|
||||||
tilt (2.0.11)
|
tilt (2.0.11)
|
||||||
timeout (0.3.0)
|
timeout (0.3.1)
|
||||||
tpm-key_attestation (0.11.0)
|
tpm-key_attestation (0.11.0)
|
||||||
bindata (~> 2.4)
|
bindata (~> 2.4)
|
||||||
openssl (> 2.0, < 3.1)
|
openssl (> 2.0, < 3.1)
|
||||||
|
@ -709,7 +711,7 @@ GEM
|
||||||
twitter-text (3.1.0)
|
twitter-text (3.1.0)
|
||||||
idn-ruby
|
idn-ruby
|
||||||
unf (~> 0.1.0)
|
unf (~> 0.1.0)
|
||||||
tzinfo (2.0.5)
|
tzinfo (2.0.6)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
tzinfo-data (1.2022.7)
|
tzinfo-data (1.2022.7)
|
||||||
tzinfo (>= 1.0.0)
|
tzinfo (>= 1.0.0)
|
||||||
|
@ -764,7 +766,7 @@ DEPENDENCIES
|
||||||
active_record_query_trace (~> 1.8)
|
active_record_query_trace (~> 1.8)
|
||||||
addressable (~> 2.8)
|
addressable (~> 2.8)
|
||||||
annotate (~> 3.2)
|
annotate (~> 3.2)
|
||||||
aws-sdk-s3 (~> 1.117)
|
aws-sdk-s3 (~> 1.119)
|
||||||
better_errors (~> 2.9)
|
better_errors (~> 2.9)
|
||||||
binding_of_caller (~> 1.0)
|
binding_of_caller (~> 1.0)
|
||||||
blurhash (~> 0.1)
|
blurhash (~> 0.1)
|
||||||
|
@ -799,7 +801,7 @@ DEPENDENCIES
|
||||||
fog-core (<= 2.4.0)
|
fog-core (<= 2.4.0)
|
||||||
fog-openstack (~> 0.3)
|
fog-openstack (~> 0.3)
|
||||||
fuubar (~> 2.5)
|
fuubar (~> 2.5)
|
||||||
gitlab-omniauth-openid-connect (~> 0.10.0)
|
gitlab-omniauth-openid-connect (~> 0.10.1)
|
||||||
hamlit-rails (~> 0.2)
|
hamlit-rails (~> 0.2)
|
||||||
hcaptcha (~> 7.1)
|
hcaptcha (~> 7.1)
|
||||||
hiredis (~> 0.6)
|
hiredis (~> 0.6)
|
||||||
|
@ -852,7 +854,7 @@ DEPENDENCIES
|
||||||
rails-i18n (~> 6.0)
|
rails-i18n (~> 6.0)
|
||||||
rails-settings-cached (~> 0.6)
|
rails-settings-cached (~> 0.6)
|
||||||
rdf-normalize (~> 0.5)
|
rdf-normalize (~> 0.5)
|
||||||
redcarpet (~> 3.5)
|
redcarpet (~> 3.6)
|
||||||
redis (~> 4.5)
|
redis (~> 4.5)
|
||||||
redis-namespace (~> 1.10)
|
redis-namespace (~> 1.10)
|
||||||
rexml (~> 3.2)
|
rexml (~> 3.2)
|
||||||
|
@ -872,7 +874,7 @@ DEPENDENCIES
|
||||||
sidekiq-scheduler (~> 4.0)
|
sidekiq-scheduler (~> 4.0)
|
||||||
sidekiq-unique-jobs (~> 7.1)
|
sidekiq-unique-jobs (~> 7.1)
|
||||||
simple-navigation (~> 4.4)
|
simple-navigation (~> 4.4)
|
||||||
simple_form (~> 5.1)
|
simple_form (~> 5.2)
|
||||||
simplecov (~> 0.22)
|
simplecov (~> 0.22)
|
||||||
sprockets (~> 3.7.2)
|
sprockets (~> 3.7.2)
|
||||||
sprockets-rails (~> 3.4)
|
sprockets-rails (~> 3.4)
|
||||||
|
|
|
@ -6,7 +6,7 @@ class Api::V1::NotificationsController < Api::BaseController
|
||||||
before_action :require_user!
|
before_action :require_user!
|
||||||
after_action :insert_pagination_headers, only: :index
|
after_action :insert_pagination_headers, only: :index
|
||||||
|
|
||||||
DEFAULT_NOTIFICATIONS_LIMIT = 15
|
DEFAULT_NOTIFICATIONS_LIMIT = 40
|
||||||
|
|
||||||
def index
|
def index
|
||||||
@notifications = load_notifications
|
@notifications = load_notifications
|
||||||
|
|
|
@ -29,7 +29,13 @@ class Settings::ApplicationsController < Settings::BaseController
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if @application.update(application_params)
|
if @application.update(application_params)
|
||||||
redirect_to settings_applications_path, notice: I18n.t('generic.changes_saved_msg')
|
if @application.scopes_previously_changed?
|
||||||
|
@access_token = current_user.token_for_app(@application)
|
||||||
|
@access_token.destroy
|
||||||
|
redirect_to settings_application_path(@application), notice: I18n.t('applications.token_regenerated')
|
||||||
|
else
|
||||||
|
redirect_to settings_application_path(@application), notice: I18n.t('generic.changes_saved_msg')
|
||||||
|
end
|
||||||
else
|
else
|
||||||
render :show
|
render :show
|
||||||
end
|
end
|
||||||
|
|
|
@ -199,6 +199,8 @@ module LanguagesHelper
|
||||||
sco: ['Scots', 'Scots'].freeze,
|
sco: ['Scots', 'Scots'].freeze,
|
||||||
sma: ['Southern Sami', 'Åarjelsaemien Gïele'].freeze,
|
sma: ['Southern Sami', 'Åarjelsaemien Gïele'].freeze,
|
||||||
smj: ['Lule Sami', 'Julevsámegiella'].freeze,
|
smj: ['Lule Sami', 'Julevsámegiella'].freeze,
|
||||||
|
szl: ['Silesian', 'ślůnsko godka'].freeze,
|
||||||
|
tai: ['Tai', 'ภาษาไท or ภาษาไต'].freeze,
|
||||||
tok: ['Toki Pona', 'toki pona'].freeze,
|
tok: ['Toki Pona', 'toki pona'].freeze,
|
||||||
zba: ['Balaibalan', 'باليبلن'].freeze,
|
zba: ['Balaibalan', 'باليبلن'].freeze,
|
||||||
zgh: ['Standard Moroccan Tamazight', 'ⵜⴰⵎⴰⵣⵉⵖⵜ'].freeze,
|
zgh: ['Standard Moroccan Tamazight', 'ⵜⴰⵎⴰⵣⵉⵖⵜ'].freeze,
|
||||||
|
@ -210,8 +212,10 @@ module LanguagesHelper
|
||||||
# names, but for some translations, we need the names of the
|
# names, but for some translations, we need the names of the
|
||||||
# regional variants specifically
|
# regional variants specifically
|
||||||
REGIONAL_LOCALE_NAMES = {
|
REGIONAL_LOCALE_NAMES = {
|
||||||
|
'en-GB': 'English (British)',
|
||||||
'es-AR': 'Español (Argentina)',
|
'es-AR': 'Español (Argentina)',
|
||||||
'es-MX': 'Español (México)',
|
'es-MX': 'Español (México)',
|
||||||
|
'fr-QC': 'Français (Canadien)',
|
||||||
'pt-BR': 'Português (Brasil)',
|
'pt-BR': 'Português (Brasil)',
|
||||||
'pt-PT': 'Português (Portugal)',
|
'pt-PT': 'Português (Portugal)',
|
||||||
'sr-Latn': 'Srpski (latinica)',
|
'sr-Latn': 'Srpski (latinica)',
|
||||||
|
|
|
@ -60,7 +60,7 @@ export function fetchFollowedHashtagsRequest() {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWED_HASHTAGS_FETCH_REQUEST,
|
type: FOLLOWED_HASHTAGS_FETCH_REQUEST,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowedHashtagsSuccess(followed_tags, next) {
|
export function fetchFollowedHashtagsSuccess(followed_tags, next) {
|
||||||
return {
|
return {
|
||||||
|
@ -68,14 +68,14 @@ export function fetchFollowedHashtagsSuccess(followed_tags, next) {
|
||||||
followed_tags,
|
followed_tags,
|
||||||
next,
|
next,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function fetchFollowedHashtagsFail(error) {
|
export function fetchFollowedHashtagsFail(error) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWED_HASHTAGS_FETCH_FAIL,
|
type: FOLLOWED_HASHTAGS_FETCH_FAIL,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowedHashtags() {
|
export function expandFollowedHashtags() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
|
@ -94,13 +94,13 @@ export function expandFollowedHashtags() {
|
||||||
dispatch(expandFollowedHashtagsFail(error));
|
dispatch(expandFollowedHashtagsFail(error));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowedHashtagsRequest() {
|
export function expandFollowedHashtagsRequest() {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWED_HASHTAGS_EXPAND_REQUEST,
|
type: FOLLOWED_HASHTAGS_EXPAND_REQUEST,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowedHashtagsSuccess(followed_tags, next) {
|
export function expandFollowedHashtagsSuccess(followed_tags, next) {
|
||||||
return {
|
return {
|
||||||
|
@ -108,14 +108,14 @@ export function expandFollowedHashtagsSuccess(followed_tags, next) {
|
||||||
followed_tags,
|
followed_tags,
|
||||||
next,
|
next,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export function expandFollowedHashtagsFail(error) {
|
export function expandFollowedHashtagsFail(error) {
|
||||||
return {
|
return {
|
||||||
type: FOLLOWED_HASHTAGS_EXPAND_FAIL,
|
type: FOLLOWED_HASHTAGS_EXPAND_FAIL,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
};
|
}
|
||||||
|
|
||||||
export const followHashtag = name => (dispatch, getState) => {
|
export const followHashtag = name => (dispatch, getState) => {
|
||||||
dispatch(followHashtagRequest(name));
|
dispatch(followHashtagRequest(name));
|
||||||
|
|
|
@ -47,27 +47,27 @@ class Account extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleFollow = () => {
|
handleFollow = () => {
|
||||||
this.props.onFollow(this.props.account);
|
this.props.onFollow(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBlock = () => {
|
handleBlock = () => {
|
||||||
this.props.onBlock(this.props.account);
|
this.props.onBlock(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMute = () => {
|
handleMute = () => {
|
||||||
this.props.onMute(this.props.account);
|
this.props.onMute(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMuteNotifications = () => {
|
handleMuteNotifications = () => {
|
||||||
this.props.onMuteNotifications(this.props.account, true);
|
this.props.onMuteNotifications(this.props.account, true);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleUnmuteNotifications = () => {
|
handleUnmuteNotifications = () => {
|
||||||
this.props.onMuteNotifications(this.props.account, false);
|
this.props.onMuteNotifications(this.props.account, false);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleAction = () => {
|
handleAction = () => {
|
||||||
this.props.onActionClick(this.props.account);
|
this.props.onActionClick(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { account, intl, hidden, onActionClick, actionIcon, actionTitle, defaultAction, size } = this.props;
|
const { account, intl, hidden, onActionClick, actionIcon, actionTitle, defaultAction, size } = this.props;
|
||||||
|
|
|
@ -38,13 +38,13 @@ export default class AnimatedNumber extends React.PureComponent {
|
||||||
const { direction } = this.state;
|
const { direction } = this.state;
|
||||||
|
|
||||||
return { y: -1 * direction };
|
return { y: -1 * direction };
|
||||||
}
|
};
|
||||||
|
|
||||||
willLeave = () => {
|
willLeave = () => {
|
||||||
const { direction } = this.state;
|
const { direction } = this.state;
|
||||||
|
|
||||||
return { y: spring(1 * direction, { damping: 35, stiffness: 400 }) };
|
return { y: spring(1 * direction, { damping: 35, stiffness: 400 }) };
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { value, obfuscate } = this.props;
|
const { value, obfuscate } = this.props;
|
||||||
|
|
|
@ -78,7 +78,7 @@ export default class AutosuggestInput extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.onChange(e);
|
this.props.onChange(e);
|
||||||
}
|
};
|
||||||
|
|
||||||
onKeyDown = (e) => {
|
onKeyDown = (e) => {
|
||||||
const { suggestions, disabled } = this.props;
|
const { suggestions, disabled } = this.props;
|
||||||
|
@ -136,22 +136,22 @@ export default class AutosuggestInput extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.onKeyDown(e);
|
this.props.onKeyDown(e);
|
||||||
}
|
};
|
||||||
|
|
||||||
onBlur = () => {
|
onBlur = () => {
|
||||||
this.setState({ suggestionsHidden: true, focused: false });
|
this.setState({ suggestionsHidden: true, focused: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
onFocus = () => {
|
onFocus = () => {
|
||||||
this.setState({ focused: true });
|
this.setState({ focused: true });
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionClick = (e) => {
|
onSuggestionClick = (e) => {
|
||||||
const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index'));
|
const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index'));
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
|
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
|
||||||
this.input.focus();
|
this.input.focus();
|
||||||
}
|
};
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
componentWillReceiveProps (nextProps) {
|
||||||
if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) {
|
if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) {
|
||||||
|
@ -161,7 +161,7 @@ export default class AutosuggestInput extends ImmutablePureComponent {
|
||||||
|
|
||||||
setInput = (c) => {
|
setInput = (c) => {
|
||||||
this.input = c;
|
this.input = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
renderSuggestion = (suggestion, i) => {
|
renderSuggestion = (suggestion, i) => {
|
||||||
const { selectedSuggestion } = this.state;
|
const { selectedSuggestion } = this.state;
|
||||||
|
@ -183,7 +183,7 @@ export default class AutosuggestInput extends ImmutablePureComponent {
|
||||||
{inner}
|
{inner}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, className, id, maxLength, lang } = this.props;
|
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, className, id, maxLength, lang } = this.props;
|
||||||
|
|
|
@ -75,7 +75,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.onChange(e);
|
this.props.onChange(e);
|
||||||
}
|
};
|
||||||
|
|
||||||
onKeyDown = (e) => {
|
onKeyDown = (e) => {
|
||||||
const { suggestions, disabled } = this.props;
|
const { suggestions, disabled } = this.props;
|
||||||
|
@ -133,25 +133,25 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.onKeyDown(e);
|
this.props.onKeyDown(e);
|
||||||
}
|
};
|
||||||
|
|
||||||
onBlur = () => {
|
onBlur = () => {
|
||||||
this.setState({ suggestionsHidden: true, focused: false });
|
this.setState({ suggestionsHidden: true, focused: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
onFocus = (e) => {
|
onFocus = (e) => {
|
||||||
this.setState({ focused: true });
|
this.setState({ focused: true });
|
||||||
if (this.props.onFocus) {
|
if (this.props.onFocus) {
|
||||||
this.props.onFocus(e);
|
this.props.onFocus(e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionClick = (e) => {
|
onSuggestionClick = (e) => {
|
||||||
const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index'));
|
const suggestion = this.props.suggestions.get(e.currentTarget.getAttribute('data-index'));
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
|
this.props.onSuggestionSelected(this.state.tokenStart, this.state.lastToken, suggestion);
|
||||||
this.textarea.focus();
|
this.textarea.focus();
|
||||||
}
|
};
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
componentWillReceiveProps (nextProps) {
|
||||||
if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) {
|
if (nextProps.suggestions !== this.props.suggestions && nextProps.suggestions.size > 0 && this.state.suggestionsHidden && this.state.focused) {
|
||||||
|
@ -161,14 +161,14 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
||||||
|
|
||||||
setTextarea = (c) => {
|
setTextarea = (c) => {
|
||||||
this.textarea = c;
|
this.textarea = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
onPaste = (e) => {
|
onPaste = (e) => {
|
||||||
if (e.clipboardData && e.clipboardData.files.length === 1) {
|
if (e.clipboardData && e.clipboardData.files.length === 1) {
|
||||||
this.props.onPaste(e.clipboardData.files);
|
this.props.onPaste(e.clipboardData.files);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
renderSuggestion = (suggestion, i) => {
|
renderSuggestion = (suggestion, i) => {
|
||||||
const { selectedSuggestion } = this.state;
|
const { selectedSuggestion } = this.state;
|
||||||
|
@ -190,7 +190,7 @@ export default class AutosuggestTextarea extends ImmutablePureComponent {
|
||||||
{inner}
|
{inner}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, lang, children } = this.props;
|
const { value, suggestions, disabled, placeholder, onKeyUp, autoFocus, lang, children } = this.props;
|
||||||
|
|
|
@ -27,12 +27,12 @@ export default class Avatar extends React.PureComponent {
|
||||||
handleMouseEnter = () => {
|
handleMouseEnter = () => {
|
||||||
if (this.props.animate) return;
|
if (this.props.animate) return;
|
||||||
this.setState({ hovering: true });
|
this.setState({ hovering: true });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseLeave = () => {
|
handleMouseLeave = () => {
|
||||||
if (this.props.animate) return;
|
if (this.props.animate) return;
|
||||||
this.setState({ hovering: false });
|
this.setState({ hovering: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { account, size, animate, inline } = this.props;
|
const { account, size, animate, inline } = this.props;
|
||||||
|
|
|
@ -29,12 +29,12 @@ export default class AvatarOverlay extends React.PureComponent {
|
||||||
handleMouseEnter = () => {
|
handleMouseEnter = () => {
|
||||||
if (this.props.animate) return;
|
if (this.props.animate) return;
|
||||||
this.setState({ hovering: true });
|
this.setState({ hovering: true });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseLeave = () => {
|
handleMouseLeave = () => {
|
||||||
if (this.props.animate) return;
|
if (this.props.animate) return;
|
||||||
this.setState({ hovering: false });
|
this.setState({ hovering: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { account, friend, animate, size, baseSize, overlaySize } = this.props;
|
const { account, friend, animate, size, baseSize, overlaySize } = this.props;
|
||||||
|
|
|
@ -24,11 +24,11 @@ export default class Button extends React.PureComponent {
|
||||||
if (!this.props.disabled && this.props.onClick) {
|
if (!this.props.disabled && this.props.onClick) {
|
||||||
this.props.onClick(e);
|
this.props.onClick(e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = (c) => {
|
setRef = (c) => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
focus() {
|
focus() {
|
||||||
this.node.focus();
|
this.node.focus();
|
||||||
|
|
|
@ -27,11 +27,11 @@ export default class Column extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this._interruptScrollAnimation();
|
this._interruptScrollAnimation();
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
if (this.props.bindToDocument) {
|
if (this.props.bindToDocument) {
|
||||||
|
|
|
@ -20,7 +20,7 @@ export default class ColumnBackButton extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.context.router.history.goBack();
|
this.context.router.history.goBack();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { multiColumn } = this.props;
|
const { multiColumn } = this.props;
|
||||||
|
|
|
@ -49,32 +49,32 @@ class ColumnHeader extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.context.router.history.goBack();
|
this.context.router.history.goBack();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleToggleClick = (e) => {
|
handleToggleClick = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this.setState({ collapsed: !this.state.collapsed, animating: true });
|
this.setState({ collapsed: !this.state.collapsed, animating: true });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleTitleClick = () => {
|
handleTitleClick = () => {
|
||||||
this.props.onClick?.();
|
this.props.onClick?.();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMoveLeft = () => {
|
handleMoveLeft = () => {
|
||||||
this.props.onMove(-1);
|
this.props.onMove(-1);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMoveRight = () => {
|
handleMoveRight = () => {
|
||||||
this.props.onMove(1);
|
this.props.onMove(1);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBackClick = () => {
|
handleBackClick = () => {
|
||||||
this.historyBack();
|
this.historyBack();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleTransitionEnd = () => {
|
handleTransitionEnd = () => {
|
||||||
this.setState({ animating: false });
|
this.setState({ animating: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
handlePin = () => {
|
handlePin = () => {
|
||||||
if (!this.props.pinned) {
|
if (!this.props.pinned) {
|
||||||
|
@ -82,7 +82,7 @@ class ColumnHeader extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.props.onPin();
|
this.props.onPin();
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { title, icon, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues } = this.props;
|
const { title, icon, active, children, pinned, multiColumn, extraButton, showBackButton, intl: { formatMessage }, placeholder, appendContent, collapseIssues } = this.props;
|
||||||
|
|
|
@ -24,7 +24,7 @@ class DismissableBanner extends React.PureComponent {
|
||||||
handleDismiss = () => {
|
handleDismiss = () => {
|
||||||
const { id } = this.props;
|
const { id } = this.props;
|
||||||
this.setState({ visible: false }, () => bannerSettings.set(id, true));
|
this.setState({ visible: false }, () => bannerSettings.set(id, true));
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { visible } = this.state;
|
const { visible } = this.state;
|
||||||
|
|
|
@ -23,7 +23,7 @@ export default class DisplayName extends React.PureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-original');
|
emoji.src = emoji.getAttribute('data-original');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseLeave = ({ currentTarget }) => {
|
handleMouseLeave = ({ currentTarget }) => {
|
||||||
if (autoPlayGif) {
|
if (autoPlayGif) {
|
||||||
|
@ -36,7 +36,7 @@ export default class DisplayName extends React.PureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-static');
|
emoji.src = emoji.getAttribute('data-static');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { others, localDomain } = this.props;
|
const { others, localDomain } = this.props;
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Account extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleDomainUnblock = () => {
|
handleDomainUnblock = () => {
|
||||||
this.props.onUnblockDomain(this.props.domain);
|
this.props.onUnblockDomain(this.props.domain);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { domain, intl } = this.props;
|
const { domain, intl } = this.props;
|
||||||
|
|
|
@ -36,7 +36,7 @@ class DropdownMenu extends React.PureComponent {
|
||||||
if (this.node && !this.node.contains(e.target)) {
|
if (this.node && !this.node.contains(e.target)) {
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
document.addEventListener('click', this.handleDocumentClick, false);
|
document.addEventListener('click', this.handleDocumentClick, false);
|
||||||
|
@ -56,11 +56,11 @@ class DropdownMenu extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
setFocusRef = c => {
|
setFocusRef = c => {
|
||||||
this.focusedItem = c;
|
this.focusedItem = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyDown = e => {
|
handleKeyDown = e => {
|
||||||
const items = Array.from(this.node.querySelectorAll('a, button'));
|
const items = Array.from(this.node.querySelectorAll('a, button'));
|
||||||
|
@ -97,18 +97,18 @@ class DropdownMenu extends React.PureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleItemKeyPress = e => {
|
handleItemKeyPress = e => {
|
||||||
if (e.key === 'Enter' || e.key === ' ') {
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
this.handleClick(e);
|
this.handleClick(e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClick = e => {
|
handleClick = e => {
|
||||||
const { onItemClick } = this.props;
|
const { onItemClick } = this.props;
|
||||||
onItemClick(e);
|
onItemClick(e);
|
||||||
}
|
};
|
||||||
|
|
||||||
renderItem = (option, i) => {
|
renderItem = (option, i) => {
|
||||||
if (option === null) {
|
if (option === null) {
|
||||||
|
@ -124,7 +124,7 @@ class DropdownMenu extends React.PureComponent {
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { items, scrollable, renderHeader, loading } = this.props;
|
const { items, scrollable, renderHeader, loading } = this.props;
|
||||||
|
@ -194,7 +194,7 @@ export default class Dropdown extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.props.onOpen(this.state.id, this.handleItemClick, type !== 'click');
|
this.props.onOpen(this.state.id, this.handleItemClick, type !== 'click');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClose = () => {
|
handleClose = () => {
|
||||||
if (this.activeElement) {
|
if (this.activeElement) {
|
||||||
|
@ -202,13 +202,13 @@ export default class Dropdown extends React.PureComponent {
|
||||||
this.activeElement = null;
|
this.activeElement = null;
|
||||||
}
|
}
|
||||||
this.props.onClose(this.state.id);
|
this.props.onClose(this.state.id);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseDown = () => {
|
handleMouseDown = () => {
|
||||||
if (!this.state.open) {
|
if (!this.state.open) {
|
||||||
this.activeElement = document.activeElement;
|
this.activeElement = document.activeElement;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleButtonKeyDown = (e) => {
|
handleButtonKeyDown = (e) => {
|
||||||
switch(e.key) {
|
switch(e.key) {
|
||||||
|
@ -217,7 +217,7 @@ export default class Dropdown extends React.PureComponent {
|
||||||
this.handleMouseDown();
|
this.handleMouseDown();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyPress = (e) => {
|
handleKeyPress = (e) => {
|
||||||
switch(e.key) {
|
switch(e.key) {
|
||||||
|
@ -228,7 +228,7 @@ export default class Dropdown extends React.PureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleItemClick = e => {
|
handleItemClick = e => {
|
||||||
const { onItemClick } = this.props;
|
const { onItemClick } = this.props;
|
||||||
|
@ -247,25 +247,25 @@ export default class Dropdown extends React.PureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.context.router.history.push(item.to);
|
this.context.router.history.push(item.to);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
setTargetRef = c => {
|
setTargetRef = c => {
|
||||||
this.target = c;
|
this.target = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
findTarget = () => {
|
findTarget = () => {
|
||||||
return this.target;
|
return this.target;
|
||||||
}
|
};
|
||||||
|
|
||||||
componentWillUnmount = () => {
|
componentWillUnmount = () => {
|
||||||
if (this.state.id === this.props.openDropdownId) {
|
if (this.state.id === this.props.openDropdownId) {
|
||||||
this.handleClose();
|
this.handleClose();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
close = () => {
|
close = () => {
|
||||||
this.handleClose();
|
this.handleClose();
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -36,7 +36,7 @@ class EditedTimestamp extends React.PureComponent {
|
||||||
return (
|
return (
|
||||||
<FormattedMessage id='status.edited_x_times' defaultMessage='Edited {count, plural, one {{count} time} other {{count} times}}' values={{ count: items.size - 1 }} />
|
<FormattedMessage id='status.edited_x_times' defaultMessage='Edited {count, plural, one {{count} time} other {{count} times}}' values={{ count: items.size - 1 }} />
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
renderItem = (item, index, { onClick, onKeyPress }) => {
|
renderItem = (item, index, { onClick, onKeyPress }) => {
|
||||||
const formattedDate = <RelativeTimestamp timestamp={item.get('created_at')} short={false} />;
|
const formattedDate = <RelativeTimestamp timestamp={item.get('created_at')} short={false} />;
|
||||||
|
@ -53,7 +53,7 @@ class EditedTimestamp extends React.PureComponent {
|
||||||
<button data-index={index} onClick={onClick} onKeyPress={onKeyPress}>{label}</button>
|
<button data-index={index} onClick={onClick} onKeyPress={onKeyPress}>{label}</button>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { timestamp, intl, statusId } = this.props;
|
const { timestamp, intl, statusId } = this.props;
|
||||||
|
|
|
@ -64,7 +64,7 @@ export default class ErrorBoundary extends React.PureComponent {
|
||||||
|
|
||||||
this.setState({ copied: true });
|
this.setState({ copied: true });
|
||||||
setTimeout(() => this.setState({ copied: false }), 700);
|
setTimeout(() => this.setState({ copied: false }), 700);
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { hasError, copied, errorMessage } = this.state;
|
const { hasError, copied, errorMessage } = this.state;
|
||||||
|
|
|
@ -17,7 +17,7 @@ export default class GIFV extends React.PureComponent {
|
||||||
|
|
||||||
handleLoadedData = () => {
|
handleLoadedData = () => {
|
||||||
this.setState({ loading: false });
|
this.setState({ loading: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
componentWillReceiveProps (nextProps) {
|
||||||
if (nextProps.src !== this.props.src) {
|
if (nextProps.src !== this.props.src) {
|
||||||
|
@ -32,7 +32,7 @@ export default class GIFV extends React.PureComponent {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
onClick();
|
onClick();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { src, width, height, alt } = this.props;
|
const { src, width, height, alt } = this.props;
|
||||||
|
|
|
@ -43,7 +43,7 @@ export default class IconButton extends React.PureComponent {
|
||||||
state = {
|
state = {
|
||||||
activate: false,
|
activate: false,
|
||||||
deactivate: false,
|
deactivate: false,
|
||||||
}
|
};
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
componentWillReceiveProps (nextProps) {
|
||||||
if (!nextProps.animate) return;
|
if (!nextProps.animate) return;
|
||||||
|
@ -61,25 +61,25 @@ export default class IconButton extends React.PureComponent {
|
||||||
if (!this.props.disabled) {
|
if (!this.props.disabled) {
|
||||||
this.props.onClick(e);
|
this.props.onClick(e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyPress = (e) => {
|
handleKeyPress = (e) => {
|
||||||
if (this.props.onKeyPress && !this.props.disabled) {
|
if (this.props.onKeyPress && !this.props.disabled) {
|
||||||
this.props.onKeyPress(e);
|
this.props.onKeyPress(e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseDown = (e) => {
|
handleMouseDown = (e) => {
|
||||||
if (!this.props.disabled && this.props.onMouseDown) {
|
if (!this.props.disabled && this.props.onMouseDown) {
|
||||||
this.props.onMouseDown(e);
|
this.props.onMouseDown(e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyDown = (e) => {
|
handleKeyDown = (e) => {
|
||||||
if (!this.props.disabled && this.props.onKeyDown) {
|
if (!this.props.disabled && this.props.onKeyDown) {
|
||||||
this.props.onKeyDown(e);
|
this.props.onKeyDown(e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const style = {
|
const style = {
|
||||||
|
|
|
@ -21,7 +21,7 @@ export default class IntersectionObserverArticle extends React.Component {
|
||||||
|
|
||||||
state = {
|
state = {
|
||||||
isHidden: false, // set to true in requestIdleCallback to trigger un-render
|
isHidden: false, // set to true in requestIdleCallback to trigger un-render
|
||||||
}
|
};
|
||||||
|
|
||||||
shouldComponentUpdate (nextProps, nextState) {
|
shouldComponentUpdate (nextProps, nextState) {
|
||||||
const isUnrendered = !this.state.isIntersecting && (this.state.isHidden || this.props.cachedHeight);
|
const isUnrendered = !this.state.isIntersecting && (this.state.isHidden || this.props.cachedHeight);
|
||||||
|
@ -62,7 +62,7 @@ export default class IntersectionObserverArticle extends React.Component {
|
||||||
|
|
||||||
scheduleIdleTask(this.calculateHeight);
|
scheduleIdleTask(this.calculateHeight);
|
||||||
this.setState(this.updateStateAfterIntersection);
|
this.setState(this.updateStateAfterIntersection);
|
||||||
}
|
};
|
||||||
|
|
||||||
updateStateAfterIntersection = (prevState) => {
|
updateStateAfterIntersection = (prevState) => {
|
||||||
if (prevState.isIntersecting !== false && !this.entry.isIntersecting) {
|
if (prevState.isIntersecting !== false && !this.entry.isIntersecting) {
|
||||||
|
@ -72,7 +72,7 @@ export default class IntersectionObserverArticle extends React.Component {
|
||||||
isIntersecting: this.entry.isIntersecting,
|
isIntersecting: this.entry.isIntersecting,
|
||||||
isHidden: false,
|
isHidden: false,
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
calculateHeight = () => {
|
calculateHeight = () => {
|
||||||
const { onHeightChange, saveHeightKey, id } = this.props;
|
const { onHeightChange, saveHeightKey, id } = this.props;
|
||||||
|
@ -83,7 +83,7 @@ export default class IntersectionObserverArticle extends React.Component {
|
||||||
if (onHeightChange && saveHeightKey) {
|
if (onHeightChange && saveHeightKey) {
|
||||||
onHeightChange(saveHeightKey, id, this.height);
|
onHeightChange(saveHeightKey, id, this.height);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
hideIfNotIntersecting = () => {
|
hideIfNotIntersecting = () => {
|
||||||
if (!this.componentMounted) {
|
if (!this.componentMounted) {
|
||||||
|
@ -95,11 +95,11 @@ export default class IntersectionObserverArticle extends React.Component {
|
||||||
// this is to save DOM nodes and avoid using up too much memory.
|
// this is to save DOM nodes and avoid using up too much memory.
|
||||||
// See: https://github.com/mastodon/mastodon/issues/2900
|
// See: https://github.com/mastodon/mastodon/issues/2900
|
||||||
this.setState((prevState) => ({ isHidden: !prevState.isIntersecting }));
|
this.setState((prevState) => ({ isHidden: !prevState.isIntersecting }));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleRef = (node) => {
|
handleRef = (node) => {
|
||||||
this.node = node;
|
this.node = node;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { children, id, index, listLength, cachedHeight } = this.props;
|
const { children, id, index, listLength, cachedHeight } = this.props;
|
||||||
|
|
|
@ -19,7 +19,7 @@ class LoadGap extends React.PureComponent {
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
this.props.onClick(this.props.maxId);
|
this.props.onClick(this.props.maxId);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { disabled, intl } = this.props;
|
const { disabled, intl } = this.props;
|
||||||
|
|
|
@ -8,11 +8,11 @@ export default class LoadMore extends React.PureComponent {
|
||||||
onClick: PropTypes.func,
|
onClick: PropTypes.func,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
visible: PropTypes.bool,
|
visible: PropTypes.bool,
|
||||||
}
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
visible: true,
|
visible: true,
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { disabled, visible } = this.props;
|
const { disabled, visible } = this.props;
|
||||||
|
|
|
@ -7,7 +7,7 @@ export default class LoadPending extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onClick: PropTypes.func,
|
onClick: PropTypes.func,
|
||||||
count: PropTypes.number,
|
count: PropTypes.number,
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { count } = this.props;
|
const { count } = this.props;
|
||||||
|
|
|
@ -29,7 +29,7 @@ export default class MediaAttachments extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<div className='media-gallery' style={{ height, width }} />
|
<div className='media-gallery' style={{ height, width }} />
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
renderLoadingVideoPlayer = () => {
|
renderLoadingVideoPlayer = () => {
|
||||||
const { height, width } = this.props;
|
const { height, width } = this.props;
|
||||||
|
@ -37,7 +37,7 @@ export default class MediaAttachments extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<div className='video-player' style={{ height, width }} />
|
<div className='video-player' style={{ height, width }} />
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
renderLoadingAudioPlayer = () => {
|
renderLoadingAudioPlayer = () => {
|
||||||
const { height, width } = this.props;
|
const { height, width } = this.props;
|
||||||
|
@ -45,7 +45,7 @@ export default class MediaAttachments extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<div className='audio-player' style={{ height, width }} />
|
<div className='audio-player' style={{ height, width }} />
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { status, width, height } = this.props;
|
const { status, width, height } = this.props;
|
||||||
|
|
|
@ -40,14 +40,14 @@ class Item extends React.PureComponent {
|
||||||
if (this.hoverToPlay()) {
|
if (this.hoverToPlay()) {
|
||||||
e.target.play();
|
e.target.play();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseLeave = (e) => {
|
handleMouseLeave = (e) => {
|
||||||
if (this.hoverToPlay()) {
|
if (this.hoverToPlay()) {
|
||||||
e.target.pause();
|
e.target.pause();
|
||||||
e.target.currentTime = 0;
|
e.target.currentTime = 0;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
getAutoPlay() {
|
getAutoPlay() {
|
||||||
return this.props.autoplay || autoPlayGif;
|
return this.props.autoplay || autoPlayGif;
|
||||||
|
@ -71,11 +71,11 @@ class Item extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleImageLoad = () => {
|
handleImageLoad = () => {
|
||||||
this.setState({ loaded: true });
|
this.setState({ loaded: true });
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { attachment, index, size, standalone, displayWidth, visible } = this.props;
|
const { attachment, index, size, standalone, displayWidth, visible } = this.props;
|
||||||
|
@ -277,11 +277,11 @@ class MediaGallery extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.setState({ visible: !this.state.visible });
|
this.setState({ visible: !this.state.visible });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClick = (index) => {
|
handleClick = (index) => {
|
||||||
this.props.onOpenMedia(this.props.media, index);
|
this.props.onOpenMedia(this.props.media, index);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleRef = c => {
|
handleRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
|
@ -289,7 +289,7 @@ class MediaGallery extends React.PureComponent {
|
||||||
if (this.node) {
|
if (this.node) {
|
||||||
this._setDimensions();
|
this._setDimensions();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
_setDimensions () {
|
_setDimensions () {
|
||||||
const width = this.node.offsetWidth;
|
const width = this.node.offsetWidth;
|
||||||
|
|
|
@ -28,7 +28,7 @@ export default class ModalRoot extends React.PureComponent {
|
||||||
&& !!this.props.children) {
|
&& !!this.props.children) {
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyDown = (e) => {
|
handleKeyDown = (e) => {
|
||||||
if (e.key === 'Tab') {
|
if (e.key === 'Tab') {
|
||||||
|
@ -49,7 +49,7 @@ export default class ModalRoot extends React.PureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
window.addEventListener('keyup', this.handleKeyUp, false);
|
window.addEventListener('keyup', this.handleKeyUp, false);
|
||||||
|
@ -122,11 +122,11 @@ export default class ModalRoot extends React.PureComponent {
|
||||||
|
|
||||||
getSiblings = () => {
|
getSiblings = () => {
|
||||||
return Array(...this.node.parentElement.childNodes).filter(node => node !== this.node);
|
return Array(...this.node.parentElement.childNodes).filter(node => node !== this.node);
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = ref => {
|
setRef = ref => {
|
||||||
this.node = ref;
|
this.node = ref;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { children, onClose } = this.props;
|
const { children, onClose } = this.props;
|
||||||
|
|
|
@ -22,7 +22,7 @@ class PictureInPicturePlaceholder extends React.PureComponent {
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
dispatch(removePictureInPicture());
|
dispatch(removePictureInPicture());
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
|
@ -30,7 +30,7 @@ class PictureInPicturePlaceholder extends React.PureComponent {
|
||||||
if (this.node) {
|
if (this.node) {
|
||||||
this._setDimensions();
|
this._setDimensions();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
_setDimensions () {
|
_setDimensions () {
|
||||||
const width = this.node.offsetWidth;
|
const width = this.node.offsetWidth;
|
||||||
|
|
|
@ -95,7 +95,7 @@ class Poll extends ImmutablePureComponent {
|
||||||
tmp[value] = true;
|
tmp[value] = true;
|
||||||
this.setState({ selected: tmp });
|
this.setState({ selected: tmp });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOptionChange = ({ target: { value } }) => {
|
handleOptionChange = ({ target: { value } }) => {
|
||||||
this._toggleOption(value);
|
this._toggleOption(value);
|
||||||
|
@ -107,7 +107,7 @@ class Poll extends ImmutablePureComponent {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleVote = () => {
|
handleVote = () => {
|
||||||
if (this.props.disabled) {
|
if (this.props.disabled) {
|
||||||
|
|
|
@ -97,7 +97,7 @@ class ScrollableList extends PureComponent {
|
||||||
} else {
|
} else {
|
||||||
return this.node;
|
return this.node;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
setScrollTop = newScrollTop => {
|
setScrollTop = newScrollTop => {
|
||||||
if (this.getScrollTop() !== newScrollTop) {
|
if (this.getScrollTop() !== newScrollTop) {
|
||||||
|
@ -143,7 +143,7 @@ class ScrollableList extends PureComponent {
|
||||||
|
|
||||||
this.mouseMovedRecently = false;
|
this.mouseMovedRecently = false;
|
||||||
this.scrollToTopOnMouseIdle = false;
|
this.scrollToTopOnMouseIdle = false;
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this.attachScrollListener();
|
this.attachScrollListener();
|
||||||
|
@ -161,25 +161,25 @@ class ScrollableList extends PureComponent {
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
getScrollTop = () => {
|
getScrollTop = () => {
|
||||||
return this._getScrollingElement().scrollTop;
|
return this._getScrollingElement().scrollTop;
|
||||||
}
|
};
|
||||||
|
|
||||||
getScrollHeight = () => {
|
getScrollHeight = () => {
|
||||||
return this._getScrollingElement().scrollHeight;
|
return this._getScrollingElement().scrollHeight;
|
||||||
}
|
};
|
||||||
|
|
||||||
getClientHeight = () => {
|
getClientHeight = () => {
|
||||||
return this._getScrollingElement().clientHeight;
|
return this._getScrollingElement().clientHeight;
|
||||||
}
|
};
|
||||||
|
|
||||||
updateScrollBottom = (snapshot) => {
|
updateScrollBottom = (snapshot) => {
|
||||||
const newScrollTop = this.getScrollHeight() - snapshot;
|
const newScrollTop = this.getScrollHeight() - snapshot;
|
||||||
|
|
||||||
this.setScrollTop(newScrollTop);
|
this.setScrollTop(newScrollTop);
|
||||||
}
|
};
|
||||||
|
|
||||||
getSnapshotBeforeUpdate (prevProps) {
|
getSnapshotBeforeUpdate (prevProps) {
|
||||||
const someItemInserted = React.Children.count(prevProps.children) > 0 &&
|
const someItemInserted = React.Children.count(prevProps.children) > 0 &&
|
||||||
|
@ -206,7 +206,7 @@ class ScrollableList extends PureComponent {
|
||||||
if (width && this.state.cachedMediaWidth !== width) {
|
if (width && this.state.cachedMediaWidth !== width) {
|
||||||
this.setState({ cachedMediaWidth: width });
|
this.setState({ cachedMediaWidth: width });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
this.clearMouseIdleTimer();
|
this.clearMouseIdleTimer();
|
||||||
|
@ -218,7 +218,7 @@ class ScrollableList extends PureComponent {
|
||||||
|
|
||||||
onFullScreenChange = () => {
|
onFullScreenChange = () => {
|
||||||
this.setState({ fullscreen: isFullscreen() });
|
this.setState({ fullscreen: isFullscreen() });
|
||||||
}
|
};
|
||||||
|
|
||||||
attachIntersectionObserver () {
|
attachIntersectionObserver () {
|
||||||
let nodeOptions = {
|
let nodeOptions = {
|
||||||
|
@ -269,12 +269,12 @@ class ScrollableList extends PureComponent {
|
||||||
|
|
||||||
setRef = (c) => {
|
setRef = (c) => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = e => {
|
handleLoadMore = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.props.onLoadMore();
|
this.props.onLoadMore();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadPending = e => {
|
handleLoadPending = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -286,7 +286,7 @@ class ScrollableList extends PureComponent {
|
||||||
this.clearMouseIdleTimer();
|
this.clearMouseIdleTimer();
|
||||||
this.mouseIdleTimer = setTimeout(this.handleMouseIdle, MOUSE_IDLE_DELAY);
|
this.mouseIdleTimer = setTimeout(this.handleMouseIdle, MOUSE_IDLE_DELAY);
|
||||||
this.mouseMovedRecently = true;
|
this.mouseMovedRecently = true;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { children, scrollKey, trackScroll, showLoading, isLoading, hasMore, numPending, prepend, alwaysPrepend, append, emptyMessage, onLoadMore } = this.props;
|
const { children, scrollKey, trackScroll, showLoading, isLoading, hasMore, numPending, prepend, alwaysPrepend, append, emptyMessage, onLoadMore } = this.props;
|
||||||
|
|
|
@ -135,7 +135,7 @@ class Status extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleToggleMediaVisibility = () => {
|
handleToggleMediaVisibility = () => {
|
||||||
this.setState({ showMedia: !this.state.showMedia });
|
this.setState({ showMedia: !this.state.showMedia });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClick = e => {
|
handleClick = e => {
|
||||||
if (e && (e.button !== 0 || e.ctrlKey || e.metaKey)) {
|
if (e && (e.button !== 0 || e.ctrlKey || e.metaKey)) {
|
||||||
|
@ -147,11 +147,11 @@ class Status extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.handleHotkeyOpen();
|
this.handleHotkeyOpen();
|
||||||
}
|
};
|
||||||
|
|
||||||
handlePrependAccountClick = e => {
|
handlePrependAccountClick = e => {
|
||||||
this.handleAccountClick(e, false);
|
this.handleAccountClick(e, false);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleAccountClick = (e, proper = true) => {
|
handleAccountClick = (e, proper = true) => {
|
||||||
if (e && (e.button !== 0 || e.ctrlKey || e.metaKey)) {
|
if (e && (e.button !== 0 || e.ctrlKey || e.metaKey)) {
|
||||||
|
@ -163,19 +163,19 @@ class Status extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this._openProfile(proper);
|
this._openProfile(proper);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleExpandedToggle = () => {
|
handleExpandedToggle = () => {
|
||||||
this.props.onToggleHidden(this._properStatus());
|
this.props.onToggleHidden(this._properStatus());
|
||||||
}
|
};
|
||||||
|
|
||||||
handleCollapsedToggle = isCollapsed => {
|
handleCollapsedToggle = isCollapsed => {
|
||||||
this.props.onToggleCollapsed(this._properStatus(), isCollapsed);
|
this.props.onToggleCollapsed(this._properStatus(), isCollapsed);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleTranslate = () => {
|
handleTranslate = () => {
|
||||||
this.props.onTranslate(this._properStatus());
|
this.props.onTranslate(this._properStatus());
|
||||||
}
|
};
|
||||||
|
|
||||||
renderLoadingMediaGallery () {
|
renderLoadingMediaGallery () {
|
||||||
return <div className='media-gallery' style={{ height: '110px' }} />;
|
return <div className='media-gallery' style={{ height: '110px' }} />;
|
||||||
|
@ -192,11 +192,11 @@ class Status extends ImmutablePureComponent {
|
||||||
handleOpenVideo = (options) => {
|
handleOpenVideo = (options) => {
|
||||||
const status = this._properStatus();
|
const status = this._properStatus();
|
||||||
this.props.onOpenVideo(status.get('id'), status.getIn(['media_attachments', 0]), options);
|
this.props.onOpenVideo(status.get('id'), status.getIn(['media_attachments', 0]), options);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOpenMedia = (media, index) => {
|
handleOpenMedia = (media, index) => {
|
||||||
this.props.onOpenMedia(this._properStatus().get('id'), media, index);
|
this.props.onOpenMedia(this._properStatus().get('id'), media, index);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyOpenMedia = e => {
|
handleHotkeyOpenMedia = e => {
|
||||||
const { onOpenMedia, onOpenVideo } = this.props;
|
const { onOpenMedia, onOpenVideo } = this.props;
|
||||||
|
@ -211,32 +211,32 @@ class Status extends ImmutablePureComponent {
|
||||||
onOpenMedia(status.get('id'), status.get('media_attachments'), 0);
|
onOpenMedia(status.get('id'), status.get('media_attachments'), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleDeployPictureInPicture = (type, mediaProps) => {
|
handleDeployPictureInPicture = (type, mediaProps) => {
|
||||||
const { deployPictureInPicture } = this.props;
|
const { deployPictureInPicture } = this.props;
|
||||||
const status = this._properStatus();
|
const status = this._properStatus();
|
||||||
|
|
||||||
deployPictureInPicture(status, type, mediaProps);
|
deployPictureInPicture(status, type, mediaProps);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyReply = e => {
|
handleHotkeyReply = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.props.onReply(this._properStatus(), this.context.router.history);
|
this.props.onReply(this._properStatus(), this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyFavourite = () => {
|
handleHotkeyFavourite = () => {
|
||||||
this.props.onFavourite(this._properStatus());
|
this.props.onFavourite(this._properStatus());
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyBoost = e => {
|
handleHotkeyBoost = e => {
|
||||||
this.props.onReblog(this._properStatus(), e);
|
this.props.onReblog(this._properStatus(), e);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyMention = e => {
|
handleHotkeyMention = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.props.onMention(this._properStatus().get('account'), this.context.router.history);
|
this.props.onMention(this._properStatus().get('account'), this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyOpen = () => {
|
handleHotkeyOpen = () => {
|
||||||
if (this.props.onClick) {
|
if (this.props.onClick) {
|
||||||
|
@ -252,11 +252,11 @@ class Status extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
router.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
|
router.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyOpenProfile = () => {
|
handleHotkeyOpenProfile = () => {
|
||||||
this._openProfile();
|
this._openProfile();
|
||||||
}
|
};
|
||||||
|
|
||||||
_openProfile = (proper = true) => {
|
_openProfile = (proper = true) => {
|
||||||
const { router } = this.context;
|
const { router } = this.context;
|
||||||
|
@ -267,32 +267,32 @@ class Status extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
router.history.push(`/@${status.getIn(['account', 'acct'])}`);
|
router.history.push(`/@${status.getIn(['account', 'acct'])}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyMoveUp = e => {
|
handleHotkeyMoveUp = e => {
|
||||||
this.props.onMoveUp(this.props.status.get('id'), e.target.getAttribute('data-featured'));
|
this.props.onMoveUp(this.props.status.get('id'), e.target.getAttribute('data-featured'));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyMoveDown = e => {
|
handleHotkeyMoveDown = e => {
|
||||||
this.props.onMoveDown(this.props.status.get('id'), e.target.getAttribute('data-featured'));
|
this.props.onMoveDown(this.props.status.get('id'), e.target.getAttribute('data-featured'));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyToggleHidden = () => {
|
handleHotkeyToggleHidden = () => {
|
||||||
this.props.onToggleHidden(this._properStatus());
|
this.props.onToggleHidden(this._properStatus());
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyToggleSensitive = () => {
|
handleHotkeyToggleSensitive = () => {
|
||||||
this.handleToggleMediaVisibility();
|
this.handleToggleMediaVisibility();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleUnfilterClick = e => {
|
handleUnfilterClick = e => {
|
||||||
this.setState({ forceFilter: false });
|
this.setState({ forceFilter: false });
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleFilterClick = () => {
|
handleFilterClick = () => {
|
||||||
this.setState({ forceFilter: true });
|
this.setState({ forceFilter: true });
|
||||||
}
|
};
|
||||||
|
|
||||||
_properStatus () {
|
_properStatus () {
|
||||||
const { status } = this.props;
|
const { status } = this.props;
|
||||||
|
@ -306,7 +306,7 @@ class Status extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleRef = c => {
|
handleRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
let media = null;
|
let media = null;
|
||||||
|
|
|
@ -97,7 +97,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
'status',
|
'status',
|
||||||
'relationship',
|
'relationship',
|
||||||
'withDismiss',
|
'withDismiss',
|
||||||
]
|
];
|
||||||
|
|
||||||
handleReplyClick = () => {
|
handleReplyClick = () => {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.context.identity;
|
||||||
|
@ -107,7 +107,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.props.onInteractionModal('reply', this.props.status);
|
this.props.onInteractionModal('reply', this.props.status);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleShareClick = () => {
|
handleShareClick = () => {
|
||||||
navigator.share({
|
navigator.share({
|
||||||
|
@ -116,7 +116,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
if (e.name !== 'AbortError') console.error(e);
|
if (e.name !== 'AbortError') console.error(e);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
handleFavouriteClick = () => {
|
handleFavouriteClick = () => {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.context.identity;
|
||||||
|
@ -126,7 +126,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.props.onInteractionModal('favourite', this.props.status);
|
this.props.onInteractionModal('favourite', this.props.status);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleReblogClick = e => {
|
handleReblogClick = e => {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.context.identity;
|
||||||
|
@ -136,35 +136,35 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.props.onInteractionModal('reblog', this.props.status);
|
this.props.onInteractionModal('reblog', this.props.status);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBookmarkClick = () => {
|
handleBookmarkClick = () => {
|
||||||
this.props.onBookmark(this.props.status);
|
this.props.onBookmark(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleDeleteClick = () => {
|
handleDeleteClick = () => {
|
||||||
this.props.onDelete(this.props.status, this.context.router.history);
|
this.props.onDelete(this.props.status, this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleRedraftClick = () => {
|
handleRedraftClick = () => {
|
||||||
this.props.onDelete(this.props.status, this.context.router.history, true);
|
this.props.onDelete(this.props.status, this.context.router.history, true);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleEditClick = () => {
|
handleEditClick = () => {
|
||||||
this.props.onEdit(this.props.status, this.context.router.history);
|
this.props.onEdit(this.props.status, this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handlePinClick = () => {
|
handlePinClick = () => {
|
||||||
this.props.onPin(this.props.status);
|
this.props.onPin(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMentionClick = () => {
|
handleMentionClick = () => {
|
||||||
this.props.onMention(this.props.status.get('account'), this.context.router.history);
|
this.props.onMention(this.props.status.get('account'), this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleDirectClick = () => {
|
handleDirectClick = () => {
|
||||||
this.props.onDirect(this.props.status.get('account'), this.context.router.history);
|
this.props.onDirect(this.props.status.get('account'), this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMuteClick = () => {
|
handleMuteClick = () => {
|
||||||
const { status, relationship, onMute, onUnmute } = this.props;
|
const { status, relationship, onMute, onUnmute } = this.props;
|
||||||
|
@ -175,7 +175,7 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
} else {
|
} else {
|
||||||
onMute(account);
|
onMute(account);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBlockClick = () => {
|
handleBlockClick = () => {
|
||||||
const { status, relationship, onBlock, onUnblock } = this.props;
|
const { status, relationship, onBlock, onUnblock } = this.props;
|
||||||
|
@ -186,50 +186,50 @@ class StatusActionBar extends ImmutablePureComponent {
|
||||||
} else {
|
} else {
|
||||||
onBlock(status);
|
onBlock(status);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBlockDomain = () => {
|
handleBlockDomain = () => {
|
||||||
const { status, onBlockDomain } = this.props;
|
const { status, onBlockDomain } = this.props;
|
||||||
const account = status.get('account');
|
const account = status.get('account');
|
||||||
|
|
||||||
onBlockDomain(account.get('acct').split('@')[1]);
|
onBlockDomain(account.get('acct').split('@')[1]);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleUnblockDomain = () => {
|
handleUnblockDomain = () => {
|
||||||
const { status, onUnblockDomain } = this.props;
|
const { status, onUnblockDomain } = this.props;
|
||||||
const account = status.get('account');
|
const account = status.get('account');
|
||||||
|
|
||||||
onUnblockDomain(account.get('acct').split('@')[1]);
|
onUnblockDomain(account.get('acct').split('@')[1]);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOpen = () => {
|
handleOpen = () => {
|
||||||
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}/${this.props.status.get('id')}`);
|
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}/${this.props.status.get('id')}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleEmbed = () => {
|
handleEmbed = () => {
|
||||||
this.props.onEmbed(this.props.status);
|
this.props.onEmbed(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleReport = () => {
|
handleReport = () => {
|
||||||
this.props.onReport(this.props.status);
|
this.props.onReport(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleConversationMuteClick = () => {
|
handleConversationMuteClick = () => {
|
||||||
this.props.onMuteConversation(this.props.status);
|
this.props.onMuteConversation(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleFilterClick = () => {
|
handleFilterClick = () => {
|
||||||
this.props.onAddFilter(this.props.status);
|
this.props.onAddFilter(this.props.status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleCopy = () => {
|
handleCopy = () => {
|
||||||
const url = this.props.status.get('url');
|
const url = this.props.status.get('url');
|
||||||
navigator.clipboard.writeText(url);
|
navigator.clipboard.writeText(url);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHideClick = () => {
|
handleHideClick = () => {
|
||||||
this.props.onFilter();
|
this.props.onFilter();
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { status, relationship, intl, withDismiss, withCounters, scrollKey } = this.props;
|
const { status, relationship, intl, withDismiss, withCounters, scrollKey } = this.props;
|
||||||
|
|
|
@ -130,7 +130,7 @@ class StatusContent extends React.PureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-original');
|
emoji.src = emoji.getAttribute('data-original');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseLeave = ({ currentTarget }) => {
|
handleMouseLeave = ({ currentTarget }) => {
|
||||||
if (autoPlayGif) {
|
if (autoPlayGif) {
|
||||||
|
@ -143,7 +143,7 @@ class StatusContent extends React.PureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-static');
|
emoji.src = emoji.getAttribute('data-static');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this._updateStatusLinks();
|
this._updateStatusLinks();
|
||||||
|
@ -158,7 +158,7 @@ class StatusContent extends React.PureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.context.router.history.push(`/@${mention.get('acct')}`);
|
this.context.router.history.push(`/@${mention.get('acct')}`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onHashtagClick = (hashtag, e) => {
|
onHashtagClick = (hashtag, e) => {
|
||||||
hashtag = hashtag.replace(/^#/, '');
|
hashtag = hashtag.replace(/^#/, '');
|
||||||
|
@ -167,11 +167,11 @@ class StatusContent extends React.PureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.context.router.history.push(`/tags/${hashtag}`);
|
this.context.router.history.push(`/tags/${hashtag}`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseDown = (e) => {
|
handleMouseDown = (e) => {
|
||||||
this.startXY = [e.clientX, e.clientY];
|
this.startXY = [e.clientX, e.clientY];
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseUp = (e) => {
|
handleMouseUp = (e) => {
|
||||||
if (!this.startXY) {
|
if (!this.startXY) {
|
||||||
|
@ -194,7 +194,7 @@ class StatusContent extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.startXY = null;
|
this.startXY = null;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleSpoilerClick = (e) => {
|
handleSpoilerClick = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -205,15 +205,15 @@ class StatusContent extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.setState({ hidden: !this.state.hidden });
|
this.setState({ hidden: !this.state.hidden });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleTranslate = () => {
|
handleTranslate = () => {
|
||||||
this.props.onTranslate();
|
this.props.onTranslate();
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = (c) => {
|
setRef = (c) => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { status, intl } = this.props;
|
const { status, intl } = this.props;
|
||||||
|
|
|
@ -34,7 +34,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
|
|
||||||
getFeaturedStatusCount = () => {
|
getFeaturedStatusCount = () => {
|
||||||
return this.props.featuredStatusIds ? this.props.featuredStatusIds.size : 0;
|
return this.props.featuredStatusIds ? this.props.featuredStatusIds.size : 0;
|
||||||
}
|
};
|
||||||
|
|
||||||
getCurrentStatusIndex = (id, featured) => {
|
getCurrentStatusIndex = (id, featured) => {
|
||||||
if (featured) {
|
if (featured) {
|
||||||
|
@ -42,21 +42,21 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
} else {
|
} else {
|
||||||
return this.props.statusIds.indexOf(id) + this.getFeaturedStatusCount();
|
return this.props.statusIds.indexOf(id) + this.getFeaturedStatusCount();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMoveUp = (id, featured) => {
|
handleMoveUp = (id, featured) => {
|
||||||
const elementIndex = this.getCurrentStatusIndex(id, featured) - 1;
|
const elementIndex = this.getCurrentStatusIndex(id, featured) - 1;
|
||||||
this._selectChild(elementIndex, true);
|
this._selectChild(elementIndex, true);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMoveDown = (id, featured) => {
|
handleMoveDown = (id, featured) => {
|
||||||
const elementIndex = this.getCurrentStatusIndex(id, featured) + 1;
|
const elementIndex = this.getCurrentStatusIndex(id, featured) + 1;
|
||||||
this._selectChild(elementIndex, false);
|
this._selectChild(elementIndex, false);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadOlder = debounce(() => {
|
handleLoadOlder = debounce(() => {
|
||||||
this.props.onLoadMore(this.props.statusIds.size > 0 ? this.props.statusIds.last() : undefined);
|
this.props.onLoadMore(this.props.statusIds.size > 0 ? this.props.statusIds.last() : undefined);
|
||||||
}, 300, { leading: true })
|
}, 300, { leading: true });
|
||||||
|
|
||||||
_selectChild (index, align_top) {
|
_selectChild (index, align_top) {
|
||||||
const container = this.node.node;
|
const container = this.node.node;
|
||||||
|
@ -74,7 +74,7 @@ export default class StatusList extends ImmutablePureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { statusIds, featuredStatusIds, onLoadMore, timelineId, ...other } = this.props;
|
const { statusIds, featuredStatusIds, onLoadMore, timelineId, ...other } = this.props;
|
||||||
|
|
|
@ -39,7 +39,7 @@ export default class MediaContainer extends PureComponent {
|
||||||
document.documentElement.style.marginRight = `${getScrollbarWidth()}px`;
|
document.documentElement.style.marginRight = `${getScrollbarWidth()}px`;
|
||||||
|
|
||||||
this.setState({ media, index });
|
this.setState({ media, index });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOpenVideo = (options) => {
|
handleOpenVideo = (options) => {
|
||||||
const { components } = this.props;
|
const { components } = this.props;
|
||||||
|
@ -50,7 +50,7 @@ export default class MediaContainer extends PureComponent {
|
||||||
document.documentElement.style.marginRight = `${getScrollbarWidth()}px`;
|
document.documentElement.style.marginRight = `${getScrollbarWidth()}px`;
|
||||||
|
|
||||||
this.setState({ media: mediaList, options });
|
this.setState({ media: mediaList, options });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleCloseMedia = () => {
|
handleCloseMedia = () => {
|
||||||
document.body.classList.remove('with-modals--active');
|
document.body.classList.remove('with-modals--active');
|
||||||
|
@ -63,11 +63,11 @@ export default class MediaContainer extends PureComponent {
|
||||||
backgroundColor: null,
|
backgroundColor: null,
|
||||||
options: null,
|
options: null,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
setBackgroundColor = color => {
|
setBackgroundColor = color => {
|
||||||
this.setState({ backgroundColor: color });
|
this.setState({ backgroundColor: color });
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { locale, components } = this.props;
|
const { locale, components } = this.props;
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only';
|
import 'abortcontroller-polyfill/dist/abortcontroller-polyfill-only';
|
||||||
import 'intersection-observer';
|
|
||||||
import 'requestidlecallback';
|
import 'requestidlecallback';
|
||||||
|
|
|
@ -59,7 +59,7 @@ class Section extends React.PureComponent {
|
||||||
const { collapsed } = this.state;
|
const { collapsed } = this.state;
|
||||||
|
|
||||||
this.setState({ collapsed: !collapsed }, () => onOpen && onOpen());
|
this.setState({ collapsed: !collapsed }, () => onOpen && onOpen());
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { title, children } = this.props;
|
const { title, children } = this.props;
|
||||||
|
@ -106,7 +106,7 @@ class About extends React.PureComponent {
|
||||||
handleDomainBlocksOpen = () => {
|
handleDomainBlocksOpen = () => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
dispatch(fetchDomainBlocks());
|
dispatch(fetchDomainBlocks());
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { multiColumn, intl, server, extendedDescription, domainBlocks } = this.props;
|
const { multiColumn, intl, server, extendedDescription, domainBlocks } = this.props;
|
||||||
|
|
|
@ -90,7 +90,7 @@ class AccountNote extends ImmutablePureComponent {
|
||||||
|
|
||||||
setTextareaRef = c => {
|
setTextareaRef = c => {
|
||||||
this.textarea = c;
|
this.textarea = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleChange = e => {
|
handleChange = e => {
|
||||||
this.setState({ value: e.target.value, saving: false });
|
this.setState({ value: e.target.value, saving: false });
|
||||||
|
@ -114,13 +114,13 @@ class AccountNote extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBlur = () => {
|
handleBlur = () => {
|
||||||
if (this._isDirty()) {
|
if (this._isDirty()) {
|
||||||
this._save();
|
this._save();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
_save (showMessage = true) {
|
_save (showMessage = true) {
|
||||||
this.setState({ saving: true }, () => this.props.onSave(this.state.value));
|
this.setState({ saving: true }, () => this.props.onSave(this.state.value));
|
||||||
|
|
|
@ -109,7 +109,7 @@ class Header extends ImmutablePureComponent {
|
||||||
|
|
||||||
openEditProfile = () => {
|
openEditProfile = () => {
|
||||||
window.open('/settings/profile', '_blank');
|
window.open('/settings/profile', '_blank');
|
||||||
}
|
};
|
||||||
|
|
||||||
isStatusesPageActive = (match, location) => {
|
isStatusesPageActive = (match, location) => {
|
||||||
if (!match) {
|
if (!match) {
|
||||||
|
@ -117,7 +117,7 @@ class Header extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
return !location.pathname.match(/\/(followers|following)\/?$/);
|
return !location.pathname.match(/\/(followers|following)\/?$/);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseEnter = ({ currentTarget }) => {
|
handleMouseEnter = ({ currentTarget }) => {
|
||||||
if (autoPlayGif) {
|
if (autoPlayGif) {
|
||||||
|
@ -130,7 +130,7 @@ class Header extends ImmutablePureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-original');
|
emoji.src = emoji.getAttribute('data-original');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseLeave = ({ currentTarget }) => {
|
handleMouseLeave = ({ currentTarget }) => {
|
||||||
if (autoPlayGif) {
|
if (autoPlayGif) {
|
||||||
|
@ -143,14 +143,14 @@ class Header extends ImmutablePureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-static');
|
emoji.src = emoji.getAttribute('data-static');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleAvatarClick = e => {
|
handleAvatarClick = e => {
|
||||||
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.props.onOpenAvatar();
|
this.props.onOpenAvatar();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleShare = () => {
|
handleShare = () => {
|
||||||
const { account } = this.props;
|
const { account } = this.props;
|
||||||
|
@ -161,7 +161,7 @@ class Header extends ImmutablePureComponent {
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
if (e.name !== 'AbortError') console.error(e);
|
if (e.name !== 'AbortError') console.error(e);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { account, hidden, intl, domain } = this.props;
|
const { account, hidden, intl, domain } = this.props;
|
||||||
|
|
|
@ -22,20 +22,20 @@ export default class MediaItem extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleImageLoad = () => {
|
handleImageLoad = () => {
|
||||||
this.setState({ loaded: true });
|
this.setState({ loaded: true });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseEnter = e => {
|
handleMouseEnter = e => {
|
||||||
if (this.hoverToPlay()) {
|
if (this.hoverToPlay()) {
|
||||||
e.target.play();
|
e.target.play();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseLeave = e => {
|
handleMouseLeave = e => {
|
||||||
if (this.hoverToPlay()) {
|
if (this.hoverToPlay()) {
|
||||||
e.target.pause();
|
e.target.pause();
|
||||||
e.target.currentTime = 0;
|
e.target.currentTime = 0;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
hoverToPlay () {
|
hoverToPlay () {
|
||||||
return !autoPlayGif && ['gifv', 'video'].indexOf(this.props.attachment.get('type')) !== -1;
|
return !autoPlayGif && ['gifv', 'video'].indexOf(this.props.attachment.get('type')) !== -1;
|
||||||
|
@ -51,7 +51,7 @@ export default class MediaItem extends ImmutablePureComponent {
|
||||||
this.setState({ visible: true });
|
this.setState({ visible: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { attachment, displayWidth } = this.props;
|
const { attachment, displayWidth } = this.props;
|
||||||
|
|
|
@ -47,7 +47,7 @@ class LoadMoreMedia extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleLoadMore = () => {
|
handleLoadMore = () => {
|
||||||
this.props.onLoadMore(this.props.maxId);
|
this.props.onLoadMore(this.props.maxId);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
return (
|
return (
|
||||||
|
@ -114,7 +114,7 @@ class AccountGallery extends ImmutablePureComponent {
|
||||||
if (this.props.hasMore) {
|
if (this.props.hasMore) {
|
||||||
this.handleLoadMore(this.props.attachments.size > 0 ? this.props.attachments.last().getIn(['status', 'id']) : undefined);
|
this.handleLoadMore(this.props.attachments.size > 0 ? this.props.attachments.last().getIn(['status', 'id']) : undefined);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleScroll = e => {
|
handleScroll = e => {
|
||||||
const { scrollTop, scrollHeight, clientHeight } = e.target;
|
const { scrollTop, scrollHeight, clientHeight } = e.target;
|
||||||
|
@ -123,7 +123,7 @@ class AccountGallery extends ImmutablePureComponent {
|
||||||
if (150 > offset && !this.props.isLoading) {
|
if (150 > offset && !this.props.isLoading) {
|
||||||
this.handleScrollToBottom();
|
this.handleScrollToBottom();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = maxId => {
|
handleLoadMore = maxId => {
|
||||||
this.props.dispatch(expandAccountMediaTimeline(this.props.accountId, { maxId }));
|
this.props.dispatch(expandAccountMediaTimeline(this.props.accountId, { maxId }));
|
||||||
|
@ -132,7 +132,7 @@ class AccountGallery extends ImmutablePureComponent {
|
||||||
handleLoadOlder = e => {
|
handleLoadOlder = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.handleScrollToBottom();
|
this.handleScrollToBottom();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOpenMedia = attachment => {
|
handleOpenMedia = attachment => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
|
@ -148,13 +148,13 @@ class AccountGallery extends ImmutablePureComponent {
|
||||||
|
|
||||||
dispatch(openModal('MEDIA', { media, index, statusId }));
|
dispatch(openModal('MEDIA', { media, index, statusId }));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleRef = c => {
|
handleRef = c => {
|
||||||
if (c) {
|
if (c) {
|
||||||
this.setState({ width: c.offsetWidth });
|
this.setState({ width: c.offsetWidth });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { attachments, isLoading, hasMore, isAccount, multiColumn, blockedBy, suspended } = this.props;
|
const { attachments, isLoading, hasMore, isAccount, multiColumn, blockedBy, suspended } = this.props;
|
||||||
|
|
|
@ -36,35 +36,35 @@ export default class Header extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleFollow = () => {
|
handleFollow = () => {
|
||||||
this.props.onFollow(this.props.account);
|
this.props.onFollow(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBlock = () => {
|
handleBlock = () => {
|
||||||
this.props.onBlock(this.props.account);
|
this.props.onBlock(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMention = () => {
|
handleMention = () => {
|
||||||
this.props.onMention(this.props.account, this.context.router.history);
|
this.props.onMention(this.props.account, this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleDirect = () => {
|
handleDirect = () => {
|
||||||
this.props.onDirect(this.props.account, this.context.router.history);
|
this.props.onDirect(this.props.account, this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleReport = () => {
|
handleReport = () => {
|
||||||
this.props.onReport(this.props.account);
|
this.props.onReport(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleReblogToggle = () => {
|
handleReblogToggle = () => {
|
||||||
this.props.onReblogToggle(this.props.account);
|
this.props.onReblogToggle(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleNotifyToggle = () => {
|
handleNotifyToggle = () => {
|
||||||
this.props.onNotifyToggle(this.props.account);
|
this.props.onNotifyToggle(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMute = () => {
|
handleMute = () => {
|
||||||
this.props.onMute(this.props.account);
|
this.props.onMute(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBlockDomain = () => {
|
handleBlockDomain = () => {
|
||||||
const domain = this.props.account.get('acct').split('@')[1];
|
const domain = this.props.account.get('acct').split('@')[1];
|
||||||
|
@ -72,7 +72,7 @@ export default class Header extends ImmutablePureComponent {
|
||||||
if (!domain) return;
|
if (!domain) return;
|
||||||
|
|
||||||
this.props.onBlockDomain(domain);
|
this.props.onBlockDomain(domain);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleUnblockDomain = () => {
|
handleUnblockDomain = () => {
|
||||||
const domain = this.props.account.get('acct').split('@')[1];
|
const domain = this.props.account.get('acct').split('@')[1];
|
||||||
|
@ -80,31 +80,31 @@ export default class Header extends ImmutablePureComponent {
|
||||||
if (!domain) return;
|
if (!domain) return;
|
||||||
|
|
||||||
this.props.onUnblockDomain(domain);
|
this.props.onUnblockDomain(domain);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleEndorseToggle = () => {
|
handleEndorseToggle = () => {
|
||||||
this.props.onEndorseToggle(this.props.account);
|
this.props.onEndorseToggle(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleAddToList = () => {
|
handleAddToList = () => {
|
||||||
this.props.onAddToList(this.props.account);
|
this.props.onAddToList(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleEditAccountNote = () => {
|
handleEditAccountNote = () => {
|
||||||
this.props.onEditAccountNote(this.props.account);
|
this.props.onEditAccountNote(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleChangeLanguages = () => {
|
handleChangeLanguages = () => {
|
||||||
this.props.onChangeLanguages(this.props.account);
|
this.props.onChangeLanguages(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleInteractionModal = () => {
|
handleInteractionModal = () => {
|
||||||
this.props.onInteractionModal(this.props.account);
|
this.props.onInteractionModal(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOpenAvatar = () => {
|
handleOpenAvatar = () => {
|
||||||
this.props.onOpenAvatar(this.props.account);
|
this.props.onOpenAvatar(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { account, hidden, hideTabs } = this.props;
|
const { account, hidden, hideTabs } = this.props;
|
||||||
|
|
|
@ -20,7 +20,7 @@ class LimitedAccountHint extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
accountId: PropTypes.string.isRequired,
|
accountId: PropTypes.string.isRequired,
|
||||||
reveal: PropTypes.func,
|
reveal: PropTypes.func,
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { reveal } = this.props;
|
const { reveal } = this.props;
|
||||||
|
|
|
@ -145,7 +145,7 @@ class AccountTimeline extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleLoadMore = maxId => {
|
handleLoadMore = maxId => {
|
||||||
this.props.dispatch(expandAccountTimeline(this.props.accountId, { maxId, withReplies: this.props.withReplies, tagged: this.props.params.tagged }));
|
this.props.dispatch(expandAccountTimeline(this.props.accountId, { maxId, withReplies: this.props.withReplies, tagged: this.props.params.tagged }));
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { accountId, statusIds, featuredStatusIds, isLoading, hasMore, blockedBy, suspended, isAccount, hidden, multiColumn, remote, remoteUrl } = this.props;
|
const { accountId, statusIds, featuredStatusIds, isLoading, hasMore, blockedBy, suspended, isAccount, hidden, multiColumn, remote, remoteUrl } = this.props;
|
||||||
|
|
|
@ -75,7 +75,7 @@ class Audio extends React.PureComponent {
|
||||||
if (this.player) {
|
if (this.player) {
|
||||||
this._setDimensions();
|
this._setDimensions();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
_pack() {
|
_pack() {
|
||||||
return {
|
return {
|
||||||
|
@ -105,11 +105,11 @@ class Audio extends React.PureComponent {
|
||||||
|
|
||||||
setSeekRef = c => {
|
setSeekRef = c => {
|
||||||
this.seek = c;
|
this.seek = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
setVolumeRef = c => {
|
setVolumeRef = c => {
|
||||||
this.volume = c;
|
this.volume = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
setAudioRef = c => {
|
setAudioRef = c => {
|
||||||
this.audio = c;
|
this.audio = c;
|
||||||
|
@ -118,13 +118,13 @@ class Audio extends React.PureComponent {
|
||||||
this.audio.volume = 1;
|
this.audio.volume = 1;
|
||||||
this.audio.muted = false;
|
this.audio.muted = false;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
setCanvasRef = c => {
|
setCanvasRef = c => {
|
||||||
this.canvas = c;
|
this.canvas = c;
|
||||||
|
|
||||||
this.visualizer.setCanvas(c);
|
this.visualizer.setCanvas(c);
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
window.addEventListener('scroll', this.handleScroll);
|
window.addEventListener('scroll', this.handleScroll);
|
||||||
|
@ -163,7 +163,7 @@ class Audio extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.setState({ paused: true }, () => this.audio.pause());
|
this.setState({ paused: true }, () => this.audio.pause());
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleResize = debounce(() => {
|
handleResize = debounce(() => {
|
||||||
if (this.player) {
|
if (this.player) {
|
||||||
|
@ -181,7 +181,7 @@ class Audio extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this._renderCanvas();
|
this._renderCanvas();
|
||||||
}
|
};
|
||||||
|
|
||||||
handlePause = () => {
|
handlePause = () => {
|
||||||
this.setState({ paused: true });
|
this.setState({ paused: true });
|
||||||
|
@ -189,7 +189,7 @@ class Audio extends React.PureComponent {
|
||||||
if (this.audioContext) {
|
if (this.audioContext) {
|
||||||
this.audioContext.suspend();
|
this.audioContext.suspend();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleProgress = () => {
|
handleProgress = () => {
|
||||||
const lastTimeRange = this.audio.buffered.length - 1;
|
const lastTimeRange = this.audio.buffered.length - 1;
|
||||||
|
@ -197,7 +197,7 @@ class Audio extends React.PureComponent {
|
||||||
if (lastTimeRange > -1) {
|
if (lastTimeRange > -1) {
|
||||||
this.setState({ buffer: Math.ceil(this.audio.buffered.end(lastTimeRange) / this.audio.duration * 100) });
|
this.setState({ buffer: Math.ceil(this.audio.buffered.end(lastTimeRange) / this.audio.duration * 100) });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
toggleMute = () => {
|
toggleMute = () => {
|
||||||
const muted = !this.state.muted;
|
const muted = !this.state.muted;
|
||||||
|
@ -207,7 +207,7 @@ class Audio extends React.PureComponent {
|
||||||
this.gainNode.gain.value = muted ? 0 : this.state.volume;
|
this.gainNode.gain.value = muted ? 0 : this.state.volume;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
toggleReveal = () => {
|
toggleReveal = () => {
|
||||||
if (this.props.onToggleVisibility) {
|
if (this.props.onToggleVisibility) {
|
||||||
|
@ -215,7 +215,7 @@ class Audio extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.setState({ revealed: !this.state.revealed });
|
this.setState({ revealed: !this.state.revealed });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleVolumeMouseDown = e => {
|
handleVolumeMouseDown = e => {
|
||||||
document.addEventListener('mousemove', this.handleMouseVolSlide, true);
|
document.addEventListener('mousemove', this.handleMouseVolSlide, true);
|
||||||
|
@ -227,14 +227,14 @@ class Audio extends React.PureComponent {
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleVolumeMouseUp = () => {
|
handleVolumeMouseUp = () => {
|
||||||
document.removeEventListener('mousemove', this.handleMouseVolSlide, true);
|
document.removeEventListener('mousemove', this.handleMouseVolSlide, true);
|
||||||
document.removeEventListener('mouseup', this.handleVolumeMouseUp, true);
|
document.removeEventListener('mouseup', this.handleVolumeMouseUp, true);
|
||||||
document.removeEventListener('touchmove', this.handleMouseVolSlide, true);
|
document.removeEventListener('touchmove', this.handleMouseVolSlide, true);
|
||||||
document.removeEventListener('touchend', this.handleVolumeMouseUp, true);
|
document.removeEventListener('touchend', this.handleVolumeMouseUp, true);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseDown = e => {
|
handleMouseDown = e => {
|
||||||
document.addEventListener('mousemove', this.handleMouseMove, true);
|
document.addEventListener('mousemove', this.handleMouseMove, true);
|
||||||
|
@ -248,7 +248,7 @@ class Audio extends React.PureComponent {
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseUp = () => {
|
handleMouseUp = () => {
|
||||||
document.removeEventListener('mousemove', this.handleMouseMove, true);
|
document.removeEventListener('mousemove', this.handleMouseMove, true);
|
||||||
|
@ -258,7 +258,7 @@ class Audio extends React.PureComponent {
|
||||||
|
|
||||||
this.setState({ dragging: false });
|
this.setState({ dragging: false });
|
||||||
this.audio.play();
|
this.audio.play();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseMove = throttle(e => {
|
handleMouseMove = throttle(e => {
|
||||||
const { x } = getPointerPosition(this.seek, e);
|
const { x } = getPointerPosition(this.seek, e);
|
||||||
|
@ -276,7 +276,7 @@ class Audio extends React.PureComponent {
|
||||||
currentTime: this.audio.currentTime,
|
currentTime: this.audio.currentTime,
|
||||||
duration: this.audio.duration,
|
duration: this.audio.duration,
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseVolSlide = throttle(e => {
|
handleMouseVolSlide = throttle(e => {
|
||||||
const { x } = getPointerPosition(this.volume, e);
|
const { x } = getPointerPosition(this.volume, e);
|
||||||
|
@ -311,11 +311,11 @@ class Audio extends React.PureComponent {
|
||||||
|
|
||||||
handleMouseEnter = () => {
|
handleMouseEnter = () => {
|
||||||
this.setState({ hovered: true });
|
this.setState({ hovered: true });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseLeave = () => {
|
handleMouseLeave = () => {
|
||||||
this.setState({ hovered: false });
|
this.setState({ hovered: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadedData = () => {
|
handleLoadedData = () => {
|
||||||
const { autoPlay, currentTime } = this.props;
|
const { autoPlay, currentTime } = this.props;
|
||||||
|
@ -327,7 +327,7 @@ class Audio extends React.PureComponent {
|
||||||
if (autoPlay) {
|
if (autoPlay) {
|
||||||
this.togglePlay();
|
this.togglePlay();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
_initAudioContext () {
|
_initAudioContext () {
|
||||||
const AudioContext = window.AudioContext || window.webkitAudioContext;
|
const AudioContext = window.AudioContext || window.webkitAudioContext;
|
||||||
|
@ -361,7 +361,7 @@ class Audio extends React.PureComponent {
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
_renderCanvas () {
|
_renderCanvas () {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
|
@ -432,7 +432,7 @@ class Audio extends React.PureComponent {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this.togglePlay();
|
this.togglePlay();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyDown = e => {
|
handleKeyDown = e => {
|
||||||
switch(e.key) {
|
switch(e.key) {
|
||||||
|
@ -457,7 +457,7 @@ class Audio extends React.PureComponent {
|
||||||
this.seekBy(10);
|
this.seekBy(10);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { src, intl, alt, editable, autoPlay, sensitive, blurhash } = this.props;
|
const { src, intl, alt, editable, autoPlay, sensitive, blurhash } = this.props;
|
||||||
|
|
|
@ -48,24 +48,24 @@ class Bookmarks extends ImmutablePureComponent {
|
||||||
} else {
|
} else {
|
||||||
dispatch(addColumn('BOOKMARKS', {}));
|
dispatch(addColumn('BOOKMARKS', {}));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMove = (dir) => {
|
handleMove = (dir) => {
|
||||||
const { columnId, dispatch } = this.props;
|
const { columnId, dispatch } = this.props;
|
||||||
dispatch(moveColumn(columnId, dir));
|
dispatch(moveColumn(columnId, dir));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHeaderClick = () => {
|
handleHeaderClick = () => {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = debounce(() => {
|
handleLoadMore = debounce(() => {
|
||||||
this.props.dispatch(expandBookmarkedStatuses());
|
this.props.dispatch(expandBookmarkedStatuses());
|
||||||
}, 300, { leading: true })
|
}, 300, { leading: true });
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
|
const { intl, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
|
||||||
|
|
|
@ -60,16 +60,16 @@ class CommunityTimeline extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
dispatch(addColumn('COMMUNITY', { other: { onlyMedia } }));
|
dispatch(addColumn('COMMUNITY', { other: { onlyMedia } }));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMove = (dir) => {
|
handleMove = (dir) => {
|
||||||
const { columnId, dispatch } = this.props;
|
const { columnId, dispatch } = this.props;
|
||||||
dispatch(moveColumn(columnId, dir));
|
dispatch(moveColumn(columnId, dir));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHeaderClick = () => {
|
handleHeaderClick = () => {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
const { dispatch, onlyMedia } = this.props;
|
const { dispatch, onlyMedia } = this.props;
|
||||||
|
@ -109,13 +109,13 @@ class CommunityTimeline extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = maxId => {
|
handleLoadMore = maxId => {
|
||||||
const { dispatch, onlyMedia } = this.props;
|
const { dispatch, onlyMedia } = this.props;
|
||||||
|
|
||||||
dispatch(expandCommunityTimeline({ maxId, onlyMedia }));
|
dispatch(expandCommunityTimeline({ maxId, onlyMedia }));
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, hasUnread, columnId, multiColumn, onlyMedia } = this.props;
|
const { intl, hasUnread, columnId, multiColumn, onlyMedia } = this.props;
|
||||||
|
|
|
@ -31,7 +31,7 @@ class ActionBar extends React.PureComponent {
|
||||||
|
|
||||||
handleLogout = () => {
|
handleLogout = () => {
|
||||||
this.props.onLogout();
|
this.props.onLogout();
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl } = this.props;
|
const { intl } = this.props;
|
||||||
|
|
|
@ -74,17 +74,17 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleChange = (e) => {
|
handleChange = (e) => {
|
||||||
this.props.onChange(e.target.value);
|
this.props.onChange(e.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyDown = (e) => {
|
handleKeyDown = (e) => {
|
||||||
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
|
if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) {
|
||||||
this.handleSubmit();
|
this.handleSubmit();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
getFulltextForCharacterCounting = () => {
|
getFulltextForCharacterCounting = () => {
|
||||||
return [this.props.spoiler? this.props.spoilerText: '', countableText(this.props.text)].join('');
|
return [this.props.spoiler? this.props.spoilerText: '', countableText(this.props.text)].join('');
|
||||||
}
|
};
|
||||||
|
|
||||||
canSubmit = () => {
|
canSubmit = () => {
|
||||||
const { isSubmitting, isChangingUpload, isUploading, anyMedia } = this.props;
|
const { isSubmitting, isChangingUpload, isUploading, anyMedia } = this.props;
|
||||||
|
@ -92,7 +92,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0;
|
const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0;
|
||||||
|
|
||||||
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars || (isOnlyWhitespace && !anyMedia));
|
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars || (isOnlyWhitespace && !anyMedia));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleSubmit = (e) => {
|
handleSubmit = (e) => {
|
||||||
if (this.props.text !== this.autosuggestTextarea.textarea.value) {
|
if (this.props.text !== this.autosuggestTextarea.textarea.value) {
|
||||||
|
@ -110,27 +110,27 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
if (e) {
|
if (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionsClearRequested = () => {
|
onSuggestionsClearRequested = () => {
|
||||||
this.props.onClearSuggestions();
|
this.props.onClearSuggestions();
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionsFetchRequested = (token) => {
|
onSuggestionsFetchRequested = (token) => {
|
||||||
this.props.onFetchSuggestions(token);
|
this.props.onFetchSuggestions(token);
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionSelected = (tokenStart, token, value) => {
|
onSuggestionSelected = (tokenStart, token, value) => {
|
||||||
this.props.onSuggestionSelected(tokenStart, token, value, ['text']);
|
this.props.onSuggestionSelected(tokenStart, token, value, ['text']);
|
||||||
}
|
};
|
||||||
|
|
||||||
onSpoilerSuggestionSelected = (tokenStart, token, value) => {
|
onSpoilerSuggestionSelected = (tokenStart, token, value) => {
|
||||||
this.props.onSuggestionSelected(tokenStart, token, value, ['spoiler_text']);
|
this.props.onSuggestionSelected(tokenStart, token, value, ['spoiler_text']);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleChangeSpoilerText = (e) => {
|
handleChangeSpoilerText = (e) => {
|
||||||
this.props.onChangeSpoilerText(e.target.value);
|
this.props.onChangeSpoilerText(e.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleFocus = () => {
|
handleFocus = () => {
|
||||||
if (this.composeForm && !this.props.singleColumn) {
|
if (this.composeForm && !this.props.singleColumn) {
|
||||||
|
@ -139,7 +139,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
this.composeForm.scrollIntoView();
|
this.composeForm.scrollIntoView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this._updateFocusAndSelection({ });
|
this._updateFocusAndSelection({ });
|
||||||
|
@ -185,15 +185,15 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
this.autosuggestTextarea.textarea.focus();
|
this.autosuggestTextarea.textarea.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
setAutosuggestTextarea = (c) => {
|
setAutosuggestTextarea = (c) => {
|
||||||
this.autosuggestTextarea = c;
|
this.autosuggestTextarea = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
setSpoilerText = (c) => {
|
setSpoilerText = (c) => {
|
||||||
this.spoilerText = c;
|
this.spoilerText = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.composeForm = c;
|
this.composeForm = c;
|
||||||
|
@ -205,7 +205,7 @@ class ComposeForm extends ImmutablePureComponent {
|
||||||
const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1]);
|
const needsSpace = data.custom && position > 0 && !allowedAroundShortCode.includes(text[position - 1]);
|
||||||
|
|
||||||
this.props.onPickEmoji(position, data, needsSpace);
|
this.props.onPickEmoji(position, data, needsSpace);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, onPaste, autoFocus } = this.props;
|
const { intl, onPaste, autoFocus } = this.props;
|
||||||
|
|
|
@ -57,7 +57,7 @@ class ModifierPickerMenu extends React.PureComponent {
|
||||||
|
|
||||||
handleClick = e => {
|
handleClick = e => {
|
||||||
this.props.onSelect(e.currentTarget.getAttribute('data-index') * 1);
|
this.props.onSelect(e.currentTarget.getAttribute('data-index') * 1);
|
||||||
}
|
};
|
||||||
|
|
||||||
componentWillReceiveProps (nextProps) {
|
componentWillReceiveProps (nextProps) {
|
||||||
if (nextProps.active) {
|
if (nextProps.active) {
|
||||||
|
@ -75,7 +75,7 @@ class ModifierPickerMenu extends React.PureComponent {
|
||||||
if (this.node && !this.node.contains(e.target)) {
|
if (this.node && !this.node.contains(e.target)) {
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
attachListeners () {
|
attachListeners () {
|
||||||
document.addEventListener('click', this.handleDocumentClick, false);
|
document.addEventListener('click', this.handleDocumentClick, false);
|
||||||
|
@ -89,7 +89,7 @@ class ModifierPickerMenu extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { active } = this.props;
|
const { active } = this.props;
|
||||||
|
@ -124,12 +124,12 @@ class ModifierPicker extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.props.onOpen();
|
this.props.onOpen();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleSelect = modifier => {
|
handleSelect = modifier => {
|
||||||
this.props.onChange(modifier);
|
this.props.onChange(modifier);
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { active, modifier } = this.props;
|
const { active, modifier } = this.props;
|
||||||
|
@ -174,7 +174,7 @@ class EmojiPickerMenu extends React.PureComponent {
|
||||||
if (this.node && !this.node.contains(e.target)) {
|
if (this.node && !this.node.contains(e.target)) {
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
document.addEventListener('click', this.handleDocumentClick, false);
|
document.addEventListener('click', this.handleDocumentClick, false);
|
||||||
|
@ -198,7 +198,7 @@ class EmojiPickerMenu extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
getI18n = () => {
|
getI18n = () => {
|
||||||
const { intl } = this.props;
|
const { intl } = this.props;
|
||||||
|
@ -219,7 +219,7 @@ class EmojiPickerMenu extends React.PureComponent {
|
||||||
custom: intl.formatMessage(messages.custom),
|
custom: intl.formatMessage(messages.custom),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClick = (emoji, event) => {
|
handleClick = (emoji, event) => {
|
||||||
if (!emoji.native) {
|
if (!emoji.native) {
|
||||||
|
@ -229,19 +229,19 @@ class EmojiPickerMenu extends React.PureComponent {
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
}
|
}
|
||||||
this.props.onPick(emoji);
|
this.props.onPick(emoji);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleModifierOpen = () => {
|
handleModifierOpen = () => {
|
||||||
this.setState({ modifierOpen: true });
|
this.setState({ modifierOpen: true });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleModifierClose = () => {
|
handleModifierClose = () => {
|
||||||
this.setState({ modifierOpen: false });
|
this.setState({ modifierOpen: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleModifierChange = modifier => {
|
handleModifierChange = modifier => {
|
||||||
this.props.onSkinTone(modifier);
|
this.props.onSkinTone(modifier);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { loading, style, intl, custom_emojis, skinTone, frequentlyUsedEmojis } = this.props;
|
const { loading, style, intl, custom_emojis, skinTone, frequentlyUsedEmojis } = this.props;
|
||||||
|
@ -325,7 +325,7 @@ class EmojiPickerDropdown extends React.PureComponent {
|
||||||
|
|
||||||
setRef = (c) => {
|
setRef = (c) => {
|
||||||
this.dropdown = c;
|
this.dropdown = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
onShowDropdown = () => {
|
onShowDropdown = () => {
|
||||||
this.setState({ active: true });
|
this.setState({ active: true });
|
||||||
|
@ -342,11 +342,11 @@ class EmojiPickerDropdown extends React.PureComponent {
|
||||||
this.setState({ loading: false, active: false });
|
this.setState({ loading: false, active: false });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onHideDropdown = () => {
|
onHideDropdown = () => {
|
||||||
this.setState({ active: false });
|
this.setState({ active: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
onToggle = (e) => {
|
onToggle = (e) => {
|
||||||
if (!this.state.loading && (!e.key || e.key === 'Enter')) {
|
if (!this.state.loading && (!e.key || e.key === 'Enter')) {
|
||||||
|
@ -356,21 +356,21 @@ class EmojiPickerDropdown extends React.PureComponent {
|
||||||
this.onShowDropdown(e);
|
this.onShowDropdown(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyDown = e => {
|
handleKeyDown = e => {
|
||||||
if (e.key === 'Escape') {
|
if (e.key === 'Escape') {
|
||||||
this.onHideDropdown();
|
this.onHideDropdown();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
setTargetRef = c => {
|
setTargetRef = c => {
|
||||||
this.target = c;
|
this.target = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
findTarget = () => {
|
findTarget = () => {
|
||||||
return this.target;
|
return this.target;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, onPickEmoji, onSkinTone, skinTone, frequentlyUsedEmojis, button } = this.props;
|
const { intl, onPickEmoji, onSkinTone, skinTone, frequentlyUsedEmojis, button } = this.props;
|
||||||
|
|
|
@ -40,7 +40,7 @@ class LanguageDropdownMenu extends React.PureComponent {
|
||||||
if (this.node && !this.node.contains(e.target)) {
|
if (this.node && !this.node.contains(e.target)) {
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
document.addEventListener('click', this.handleDocumentClick, false);
|
document.addEventListener('click', this.handleDocumentClick, false);
|
||||||
|
@ -63,15 +63,15 @@ class LanguageDropdownMenu extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
setListRef = c => {
|
setListRef = c => {
|
||||||
this.listNode = c;
|
this.listNode = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleSearchChange = ({ target }) => {
|
handleSearchChange = ({ target }) => {
|
||||||
this.setState({ searchValue: target.value });
|
this.setState({ searchValue: target.value });
|
||||||
}
|
};
|
||||||
|
|
||||||
search () {
|
search () {
|
||||||
const { languages, value, frequentlyUsedLanguages } = this.props;
|
const { languages, value, frequentlyUsedLanguages } = this.props;
|
||||||
|
@ -122,7 +122,7 @@ class LanguageDropdownMenu extends React.PureComponent {
|
||||||
|
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
this.props.onChange(value);
|
this.props.onChange(value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyDown = e => {
|
handleKeyDown = e => {
|
||||||
const { onClose } = this.props;
|
const { onClose } = this.props;
|
||||||
|
@ -163,7 +163,7 @@ class LanguageDropdownMenu extends React.PureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleSearchKeyDown = e => {
|
handleSearchKeyDown = e => {
|
||||||
const { onChange, onClose } = this.props;
|
const { onChange, onClose } = this.props;
|
||||||
|
@ -199,11 +199,11 @@ class LanguageDropdownMenu extends React.PureComponent {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClear = () => {
|
handleClear = () => {
|
||||||
this.setState({ searchValue: '' });
|
this.setState({ searchValue: '' });
|
||||||
}
|
};
|
||||||
|
|
||||||
renderItem = lang => {
|
renderItem = lang => {
|
||||||
const { value } = this.props;
|
const { value } = this.props;
|
||||||
|
@ -213,7 +213,7 @@ class LanguageDropdownMenu extends React.PureComponent {
|
||||||
<span className='language-dropdown__dropdown__results__item__native-name'>{lang[2]}</span> <span className='language-dropdown__dropdown__results__item__common-name'>({lang[1]})</span>
|
<span className='language-dropdown__dropdown__results__item__native-name'>{lang[2]}</span> <span className='language-dropdown__dropdown__results__item__common-name'>({lang[1]})</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl } = this.props;
|
const { intl } = this.props;
|
||||||
|
@ -259,7 +259,7 @@ class LanguageDropdown extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setState({ open: !this.state.open });
|
this.setState({ open: !this.state.open });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClose = () => {
|
handleClose = () => {
|
||||||
const { value, onClose } = this.props;
|
const { value, onClose } = this.props;
|
||||||
|
@ -270,24 +270,24 @@ class LanguageDropdown extends React.PureComponent {
|
||||||
|
|
||||||
this.setState({ open: false });
|
this.setState({ open: false });
|
||||||
onClose(value);
|
onClose(value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleChange = value => {
|
handleChange = value => {
|
||||||
const { onChange } = this.props;
|
const { onChange } = this.props;
|
||||||
onChange(value);
|
onChange(value);
|
||||||
}
|
};
|
||||||
|
|
||||||
setTargetRef = c => {
|
setTargetRef = c => {
|
||||||
this.target = c;
|
this.target = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
findTarget = () => {
|
findTarget = () => {
|
||||||
return this.target;
|
return this.target;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOverlayEnter = (state) => {
|
handleOverlayEnter = (state) => {
|
||||||
this.setState({ placement: state.placement });
|
this.setState({ placement: state.placement });
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { value, intl, frequentlyUsedLanguages } = this.props;
|
const { value, intl, frequentlyUsedLanguages } = this.props;
|
||||||
|
|
|
@ -27,7 +27,7 @@ class PollButton extends React.PureComponent {
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
this.props.onClick();
|
this.props.onClick();
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, active, unavailable, disabled } = this.props;
|
const { intl, active, unavailable, disabled } = this.props;
|
||||||
|
|
|
@ -25,6 +25,7 @@ class Option extends React.PureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
title: PropTypes.string.isRequired,
|
title: PropTypes.string.isRequired,
|
||||||
|
lang: PropTypes.string,
|
||||||
index: PropTypes.number.isRequired,
|
index: PropTypes.number.isRequired,
|
||||||
isPollMultiple: PropTypes.bool,
|
isPollMultiple: PropTypes.bool,
|
||||||
autoFocus: PropTypes.bool,
|
autoFocus: PropTypes.bool,
|
||||||
|
@ -57,22 +58,22 @@ class Option extends React.PureComponent {
|
||||||
if (e.key === 'Enter' || e.key === ' ') {
|
if (e.key === 'Enter' || e.key === ' ') {
|
||||||
this.handleToggleMultiple(e);
|
this.handleToggleMultiple(e);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionsClearRequested = () => {
|
onSuggestionsClearRequested = () => {
|
||||||
this.props.onClearSuggestions();
|
this.props.onClearSuggestions();
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionsFetchRequested = (token) => {
|
onSuggestionsFetchRequested = (token) => {
|
||||||
this.props.onFetchSuggestions(token);
|
this.props.onFetchSuggestions(token);
|
||||||
}
|
};
|
||||||
|
|
||||||
onSuggestionSelected = (tokenStart, token, value) => {
|
onSuggestionSelected = (tokenStart, token, value) => {
|
||||||
this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]);
|
this.props.onSuggestionSelected(tokenStart, token, value, ['poll', 'options', this.props.index]);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { isPollMultiple, title, index, autoFocus, intl } = this.props;
|
const { isPollMultiple, title, lang, index, autoFocus, intl } = this.props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
|
@ -91,6 +92,7 @@ class Option extends React.PureComponent {
|
||||||
placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })}
|
placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })}
|
||||||
maxLength={100}
|
maxLength={100}
|
||||||
value={title}
|
value={title}
|
||||||
|
lang={lang}
|
||||||
onChange={this.handleOptionTitleChange}
|
onChange={this.handleOptionTitleChange}
|
||||||
suggestions={this.props.suggestions}
|
suggestions={this.props.suggestions}
|
||||||
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
|
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
|
||||||
|
@ -116,6 +118,7 @@ class PollForm extends ImmutablePureComponent {
|
||||||
|
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
options: ImmutablePropTypes.list,
|
options: ImmutablePropTypes.list,
|
||||||
|
lang: PropTypes.string,
|
||||||
expiresIn: PropTypes.number,
|
expiresIn: PropTypes.number,
|
||||||
isMultiple: PropTypes.bool,
|
isMultiple: PropTypes.bool,
|
||||||
onChangeOption: PropTypes.func.isRequired,
|
onChangeOption: PropTypes.func.isRequired,
|
||||||
|
@ -142,7 +145,7 @@ class PollForm extends ImmutablePureComponent {
|
||||||
};
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { options, expiresIn, isMultiple, onChangeOption, onRemoveOption, intl, ...other } = this.props;
|
const { options, lang, expiresIn, isMultiple, onChangeOption, onRemoveOption, intl, ...other } = this.props;
|
||||||
|
|
||||||
if (!options) {
|
if (!options) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -153,7 +156,7 @@ class PollForm extends ImmutablePureComponent {
|
||||||
return (
|
return (
|
||||||
<div className='compose-form__poll-wrapper'>
|
<div className='compose-form__poll-wrapper'>
|
||||||
<ul>
|
<ul>
|
||||||
{options.map((title, i) => <Option title={title} key={i} index={i} onChange={onChangeOption} onRemove={onRemoveOption} isPollMultiple={isMultiple} onToggleMultiple={this.handleToggleMultiple} autoFocus={i === autoFocusIndex} {...other} />)}
|
{options.map((title, i) => <Option title={title} lang={lang} key={i} index={i} onChange={onChangeOption} onRemove={onRemoveOption} isPollMultiple={isMultiple} onToggleMultiple={this.handleToggleMultiple} autoFocus={i === autoFocusIndex} {...other} />)}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<div className='poll__footer'>
|
<div className='poll__footer'>
|
||||||
|
|
|
@ -35,7 +35,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
|
||||||
if (this.node && !this.node.contains(e.target)) {
|
if (this.node && !this.node.contains(e.target)) {
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyDown = e => {
|
handleKeyDown = e => {
|
||||||
const { items } = this.props;
|
const { items } = this.props;
|
||||||
|
@ -79,7 +79,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClick = e => {
|
handleClick = e => {
|
||||||
const value = e.currentTarget.getAttribute('data-index');
|
const value = e.currentTarget.getAttribute('data-index');
|
||||||
|
@ -88,7 +88,7 @@ class PrivacyDropdownMenu extends React.PureComponent {
|
||||||
|
|
||||||
this.props.onClose();
|
this.props.onClose();
|
||||||
this.props.onChange(value);
|
this.props.onChange(value);
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
document.addEventListener('click', this.handleDocumentClick, false);
|
document.addEventListener('click', this.handleDocumentClick, false);
|
||||||
|
@ -103,11 +103,11 @@ class PrivacyDropdownMenu extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
setFocusRef = c => {
|
setFocusRef = c => {
|
||||||
this.focusedItem = c;
|
this.focusedItem = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { style, items, value } = this.props;
|
const { style, items, value } = this.props;
|
||||||
|
@ -168,7 +168,7 @@ class PrivacyDropdown extends React.PureComponent {
|
||||||
}
|
}
|
||||||
this.setState({ open: !this.state.open });
|
this.setState({ open: !this.state.open });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleModalActionClick = (e) => {
|
handleModalActionClick = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -177,7 +177,7 @@ class PrivacyDropdown extends React.PureComponent {
|
||||||
|
|
||||||
this.props.onModalClose();
|
this.props.onModalClose();
|
||||||
this.props.onChange(value);
|
this.props.onChange(value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyDown = e => {
|
handleKeyDown = e => {
|
||||||
switch(e.key) {
|
switch(e.key) {
|
||||||
|
@ -185,13 +185,13 @@ class PrivacyDropdown extends React.PureComponent {
|
||||||
this.handleClose();
|
this.handleClose();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseDown = () => {
|
handleMouseDown = () => {
|
||||||
if (!this.state.open) {
|
if (!this.state.open) {
|
||||||
this.activeElement = document.activeElement;
|
this.activeElement = document.activeElement;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleButtonKeyDown = (e) => {
|
handleButtonKeyDown = (e) => {
|
||||||
switch(e.key) {
|
switch(e.key) {
|
||||||
|
@ -200,18 +200,18 @@ class PrivacyDropdown extends React.PureComponent {
|
||||||
this.handleMouseDown();
|
this.handleMouseDown();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClose = () => {
|
handleClose = () => {
|
||||||
if (this.state.open && this.activeElement) {
|
if (this.state.open && this.activeElement) {
|
||||||
this.activeElement.focus({ preventScroll: true });
|
this.activeElement.focus({ preventScroll: true });
|
||||||
}
|
}
|
||||||
this.setState({ open: false });
|
this.setState({ open: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleChange = value => {
|
handleChange = value => {
|
||||||
this.props.onChange(value);
|
this.props.onChange(value);
|
||||||
}
|
};
|
||||||
|
|
||||||
componentWillMount () {
|
componentWillMount () {
|
||||||
const { intl: { formatMessage } } = this.props;
|
const { intl: { formatMessage } } = this.props;
|
||||||
|
@ -231,15 +231,15 @@ class PrivacyDropdown extends React.PureComponent {
|
||||||
|
|
||||||
setTargetRef = c => {
|
setTargetRef = c => {
|
||||||
this.target = c;
|
this.target = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
findTarget = () => {
|
findTarget = () => {
|
||||||
return this.target;
|
return this.target;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOverlayEnter = (state) => {
|
handleOverlayEnter = (state) => {
|
||||||
this.setState({ placement: state.placement });
|
this.setState({ placement: state.placement });
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { value, container, disabled, intl } = this.props;
|
const { value, container, disabled, intl } = this.props;
|
||||||
|
|
|
@ -27,14 +27,14 @@ class ReplyIndicator extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
this.props.onCancel();
|
this.props.onCancel();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleAccountClick = (e) => {
|
handleAccountClick = (e) => {
|
||||||
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
|
this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { status, intl } = this.props;
|
const { status, intl } = this.props;
|
||||||
|
|
|
@ -58,11 +58,11 @@ class Search extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.searchForm = c;
|
this.searchForm = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleChange = (e) => {
|
handleChange = (e) => {
|
||||||
this.props.onChange(e.target.value);
|
this.props.onChange(e.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClear = (e) => {
|
handleClear = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -70,7 +70,7 @@ class Search extends React.PureComponent {
|
||||||
if (this.props.value.length > 0 || this.props.submitted) {
|
if (this.props.value.length > 0 || this.props.submitted) {
|
||||||
this.props.onClear();
|
this.props.onClear();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyUp = (e) => {
|
handleKeyUp = (e) => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
|
@ -84,7 +84,7 @@ class Search extends React.PureComponent {
|
||||||
} else if (e.key === 'Escape') {
|
} else if (e.key === 'Escape') {
|
||||||
document.querySelector('.ui').parentElement.focus();
|
document.querySelector('.ui').parentElement.focus();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleFocus = () => {
|
handleFocus = () => {
|
||||||
this.setState({ expanded: true });
|
this.setState({ expanded: true });
|
||||||
|
@ -96,15 +96,15 @@ class Search extends React.PureComponent {
|
||||||
this.searchForm.scrollIntoView();
|
this.searchForm.scrollIntoView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleBlur = () => {
|
handleBlur = () => {
|
||||||
this.setState({ expanded: false });
|
this.setState({ expanded: false });
|
||||||
}
|
};
|
||||||
|
|
||||||
findTarget = () => {
|
findTarget = () => {
|
||||||
return this.searchForm;
|
return this.searchForm;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, value, submitted } = this.props;
|
const { intl, value, submitted } = this.props;
|
||||||
|
|
|
@ -22,12 +22,12 @@ export default class Upload extends ImmutablePureComponent {
|
||||||
handleUndoClick = e => {
|
handleUndoClick = e => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this.props.onUndo(this.props.media.get('id'));
|
this.props.onUndo(this.props.media.get('id'));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleFocalPointClick = e => {
|
handleFocalPointClick = e => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this.props.onOpenFocalPoint(this.props.media.get('id'));
|
this.props.onOpenFocalPoint(this.props.media.get('id'));
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { media } = this.props;
|
const { media } = this.props;
|
||||||
|
|
|
@ -41,15 +41,15 @@ class UploadButton extends ImmutablePureComponent {
|
||||||
if (e.target.files.length > 0) {
|
if (e.target.files.length > 0) {
|
||||||
this.props.onSelectFile(e.target.files);
|
this.props.onSelectFile(e.target.files);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
this.fileElement.click();
|
this.fileElement.click();
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = (c) => {
|
setRef = (c) => {
|
||||||
this.fileElement = c;
|
this.fileElement = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, resetFileKey, unavailable, disabled, acceptContentTypes } = this.props;
|
const { intl, resetFileKey, unavailable, disabled, acceptContentTypes } = this.props;
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
const mapStateToProps = state => ({
|
const mapStateToProps = state => ({
|
||||||
suggestions: state.getIn(['compose', 'suggestions']),
|
suggestions: state.getIn(['compose', 'suggestions']),
|
||||||
options: state.getIn(['compose', 'poll', 'options']),
|
options: state.getIn(['compose', 'poll', 'options']),
|
||||||
|
lang: state.getIn(['compose', 'language']),
|
||||||
expiresIn: state.getIn(['compose', 'poll', 'expires_in']),
|
expiresIn: state.getIn(['compose', 'poll', 'expires_in']),
|
||||||
isMultiple: state.getIn(['compose', 'poll', 'multiple']),
|
isMultiple: state.getIn(['compose', 'poll', 'multiple']),
|
||||||
});
|
});
|
||||||
|
|
|
@ -74,15 +74,15 @@ class Compose extends React.PureComponent {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
};
|
||||||
|
|
||||||
onFocus = () => {
|
onFocus = () => {
|
||||||
this.props.dispatch(changeComposing(true));
|
this.props.dispatch(changeComposing(true));
|
||||||
}
|
};
|
||||||
|
|
||||||
onBlur = () => {
|
onBlur = () => {
|
||||||
this.props.dispatch(changeComposing(false));
|
this.props.dispatch(changeComposing(false));
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { multiColumn, showSearch, intl } = this.props;
|
const { multiColumn, showSearch, intl } = this.props;
|
||||||
|
|
|
@ -55,7 +55,7 @@ class Conversation extends ImmutablePureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-original');
|
emoji.src = emoji.getAttribute('data-original');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseLeave = ({ currentTarget }) => {
|
handleMouseLeave = ({ currentTarget }) => {
|
||||||
if (autoPlayGif) {
|
if (autoPlayGif) {
|
||||||
|
@ -68,7 +68,7 @@ class Conversation extends ImmutablePureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-static');
|
emoji.src = emoji.getAttribute('data-static');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
if (!this.context.router) {
|
if (!this.context.router) {
|
||||||
|
@ -82,35 +82,35 @@ class Conversation extends ImmutablePureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.context.router.history.push(`/@${lastStatus.getIn(['account', 'acct'])}/${lastStatus.get('id')}`);
|
this.context.router.history.push(`/@${lastStatus.getIn(['account', 'acct'])}/${lastStatus.get('id')}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMarkAsRead = () => {
|
handleMarkAsRead = () => {
|
||||||
this.props.markRead();
|
this.props.markRead();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleReply = () => {
|
handleReply = () => {
|
||||||
this.props.reply(this.props.lastStatus, this.context.router.history);
|
this.props.reply(this.props.lastStatus, this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleDelete = () => {
|
handleDelete = () => {
|
||||||
this.props.delete();
|
this.props.delete();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyMoveUp = () => {
|
handleHotkeyMoveUp = () => {
|
||||||
this.props.onMoveUp(this.props.conversationId);
|
this.props.onMoveUp(this.props.conversationId);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyMoveDown = () => {
|
handleHotkeyMoveDown = () => {
|
||||||
this.props.onMoveDown(this.props.conversationId);
|
this.props.onMoveDown(this.props.conversationId);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleConversationMute = () => {
|
handleConversationMute = () => {
|
||||||
this.props.onMute(this.props.lastStatus);
|
this.props.onMute(this.props.lastStatus);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleShowMore = () => {
|
handleShowMore = () => {
|
||||||
this.props.onToggleHidden(this.props.lastStatus);
|
this.props.onToggleHidden(this.props.lastStatus);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { accounts, lastStatus, unread, scrollKey, intl } = this.props;
|
const { accounts, lastStatus, unread, scrollKey, intl } = this.props;
|
||||||
|
|
|
@ -16,17 +16,17 @@ export default class ConversationsList extends ImmutablePureComponent {
|
||||||
onLoadMore: PropTypes.func,
|
onLoadMore: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
getCurrentIndex = id => this.props.conversations.findIndex(x => x.get('id') === id)
|
getCurrentIndex = id => this.props.conversations.findIndex(x => x.get('id') === id);
|
||||||
|
|
||||||
handleMoveUp = id => {
|
handleMoveUp = id => {
|
||||||
const elementIndex = this.getCurrentIndex(id) - 1;
|
const elementIndex = this.getCurrentIndex(id) - 1;
|
||||||
this._selectChild(elementIndex, true);
|
this._selectChild(elementIndex, true);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMoveDown = id => {
|
handleMoveDown = id => {
|
||||||
const elementIndex = this.getCurrentIndex(id) + 1;
|
const elementIndex = this.getCurrentIndex(id) + 1;
|
||||||
this._selectChild(elementIndex, false);
|
this._selectChild(elementIndex, false);
|
||||||
}
|
};
|
||||||
|
|
||||||
_selectChild (index, align_top) {
|
_selectChild (index, align_top) {
|
||||||
const container = this.node.node;
|
const container = this.node.node;
|
||||||
|
@ -44,7 +44,7 @@ export default class ConversationsList extends ImmutablePureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadOlder = debounce(() => {
|
handleLoadOlder = debounce(() => {
|
||||||
const last = this.props.conversations.last();
|
const last = this.props.conversations.last();
|
||||||
|
@ -52,7 +52,7 @@ export default class ConversationsList extends ImmutablePureComponent {
|
||||||
if (last && last.get('last_status')) {
|
if (last && last.get('last_status')) {
|
||||||
this.props.onLoadMore(last.get('last_status'));
|
this.props.onLoadMore(last.get('last_status'));
|
||||||
}
|
}
|
||||||
}, 300, { leading: true })
|
}, 300, { leading: true });
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { conversations, onLoadMore, ...other } = this.props;
|
const { conversations, onLoadMore, ...other } = this.props;
|
||||||
|
|
|
@ -34,16 +34,16 @@ class DirectTimeline extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
dispatch(addColumn('DIRECT', {}));
|
dispatch(addColumn('DIRECT', {}));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMove = (dir) => {
|
handleMove = (dir) => {
|
||||||
const { columnId, dispatch } = this.props;
|
const { columnId, dispatch } = this.props;
|
||||||
dispatch(moveColumn(columnId, dir));
|
dispatch(moveColumn(columnId, dir));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHeaderClick = () => {
|
handleHeaderClick = () => {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
|
@ -64,11 +64,11 @@ class DirectTimeline extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = maxId => {
|
handleLoadMore = maxId => {
|
||||||
this.props.dispatch(expandConversations({ maxId }));
|
this.props.dispatch(expandConversations({ maxId }));
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, hasUnread, columnId, multiColumn } = this.props;
|
const { intl, hasUnread, columnId, multiColumn } = this.props;
|
||||||
|
|
|
@ -115,7 +115,7 @@ class AccountCard extends ImmutablePureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-original');
|
emoji.src = emoji.getAttribute('data-original');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseLeave = ({ currentTarget }) => {
|
handleMouseLeave = ({ currentTarget }) => {
|
||||||
if (autoPlayGif) {
|
if (autoPlayGif) {
|
||||||
|
@ -128,7 +128,7 @@ class AccountCard extends ImmutablePureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-static');
|
emoji.src = emoji.getAttribute('data-static');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleFollow = () => {
|
handleFollow = () => {
|
||||||
this.props.onFollow(this.props.account);
|
this.props.onFollow(this.props.account);
|
||||||
|
@ -140,11 +140,11 @@ class AccountCard extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleMute = () => {
|
handleMute = () => {
|
||||||
this.props.onMute(this.props.account);
|
this.props.onMute(this.props.account);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleEditProfile = () => {
|
handleEditProfile = () => {
|
||||||
window.open('/settings/profile', '_blank');
|
window.open('/settings/profile', '_blank');
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { account, intl } = this.props;
|
const { account, intl } = this.props;
|
||||||
|
|
|
@ -64,7 +64,7 @@ class Directory extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
dispatch(addColumn('DIRECTORY', this.getParams(this.props, this.state)));
|
dispatch(addColumn('DIRECTORY', this.getParams(this.props, this.state)));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
getParams = (props, state) => ({
|
getParams = (props, state) => ({
|
||||||
order: state.order === null ? (props.params.order || 'active') : state.order,
|
order: state.order === null ? (props.params.order || 'active') : state.order,
|
||||||
|
@ -74,11 +74,11 @@ class Directory extends React.PureComponent {
|
||||||
handleMove = dir => {
|
handleMove = dir => {
|
||||||
const { columnId, dispatch } = this.props;
|
const { columnId, dispatch } = this.props;
|
||||||
dispatch(moveColumn(columnId, dir));
|
dispatch(moveColumn(columnId, dir));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHeaderClick = () => {
|
handleHeaderClick = () => {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
|
@ -97,7 +97,7 @@ class Directory extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleChangeOrder = e => {
|
handleChangeOrder = e => {
|
||||||
const { dispatch, columnId } = this.props;
|
const { dispatch, columnId } = this.props;
|
||||||
|
@ -107,7 +107,7 @@ class Directory extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.setState({ order: e.target.value });
|
this.setState({ order: e.target.value });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleChangeLocal = e => {
|
handleChangeLocal = e => {
|
||||||
const { dispatch, columnId } = this.props;
|
const { dispatch, columnId } = this.props;
|
||||||
|
@ -117,12 +117,12 @@ class Directory extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.setState({ local: e.target.value === '1' });
|
this.setState({ local: e.target.value === '1' });
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = () => {
|
handleLoadMore = () => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
dispatch(expandDirectory(this.getParams(this.props, this.state)));
|
dispatch(expandDirectory(this.getParams(this.props, this.state)));
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { isLoading, accountIds, intl, columnId, multiColumn, domain } = this.props;
|
const { isLoading, accountIds, intl, columnId, multiColumn, domain } = this.props;
|
||||||
|
|
|
@ -135,19 +135,19 @@ function getData(emoji, skin, set) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.short_names.hasOwnProperty(emoji)) {
|
if (Object.prototype.hasOwnProperty.call(data.short_names, emoji)) {
|
||||||
emoji = data.short_names[emoji];
|
emoji = data.short_names[emoji];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.emojis.hasOwnProperty(emoji)) {
|
if (Object.prototype.hasOwnProperty.call(data.emojis, emoji)) {
|
||||||
emojiData = data.emojis[emoji];
|
emojiData = data.emojis[emoji];
|
||||||
}
|
}
|
||||||
} else if (emoji.id) {
|
} else if (emoji.id) {
|
||||||
if (data.short_names.hasOwnProperty(emoji.id)) {
|
if (Object.prototype.hasOwnProperty.call(data.short_names, emoji.id)) {
|
||||||
emoji.id = data.short_names[emoji.id];
|
emoji.id = data.short_names[emoji.id];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.emojis.hasOwnProperty(emoji.id)) {
|
if (Object.prototype.hasOwnProperty.call(data.emojis, emoji.id)) {
|
||||||
emojiData = data.emojis[emoji.id];
|
emojiData = data.emojis[emoji.id];
|
||||||
skin = skin || emoji.skin;
|
skin = skin || emoji.skin;
|
||||||
}
|
}
|
||||||
|
@ -216,7 +216,7 @@ function deepMerge(a, b) {
|
||||||
let originalValue = a[key],
|
let originalValue = a[key],
|
||||||
value = originalValue;
|
value = originalValue;
|
||||||
|
|
||||||
if (b.hasOwnProperty(key)) {
|
if (Object.prototype.hasOwnProperty.call(b, key)) {
|
||||||
value = b[key];
|
value = b[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,11 +41,11 @@ class Explore extends React.PureComponent {
|
||||||
|
|
||||||
handleHeaderClick = () => {
|
handleHeaderClick = () => {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { intl, multiColumn, isSearching } = this.props;
|
const { intl, multiColumn, isSearching } = this.props;
|
||||||
|
|
|
@ -33,7 +33,7 @@ class Statuses extends React.PureComponent {
|
||||||
handleLoadMore = debounce(() => {
|
handleLoadMore = debounce(() => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
dispatch(expandTrendingStatuses());
|
dispatch(expandTrendingStatuses());
|
||||||
}, 300, { leading: true })
|
}, 300, { leading: true });
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { isLoading, hasMore, statusIds, multiColumn } = this.props;
|
const { isLoading, hasMore, statusIds, multiColumn } = this.props;
|
||||||
|
|
|
@ -48,24 +48,24 @@ class Favourites extends ImmutablePureComponent {
|
||||||
} else {
|
} else {
|
||||||
dispatch(addColumn('FAVOURITES', {}));
|
dispatch(addColumn('FAVOURITES', {}));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMove = (dir) => {
|
handleMove = (dir) => {
|
||||||
const { columnId, dispatch } = this.props;
|
const { columnId, dispatch } = this.props;
|
||||||
dispatch(moveColumn(columnId, dir));
|
dispatch(moveColumn(columnId, dir));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHeaderClick = () => {
|
handleHeaderClick = () => {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = debounce(() => {
|
handleLoadMore = debounce(() => {
|
||||||
this.props.dispatch(expandFavouritedStatuses());
|
this.props.dispatch(expandFavouritedStatuses());
|
||||||
}, 300, { leading: true })
|
}, 300, { leading: true });
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
|
const { intl, statusIds, columnId, multiColumn, hasMore, isLoading } = this.props;
|
||||||
|
|
|
@ -47,7 +47,7 @@ class Favourites extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleRefresh = () => {
|
handleRefresh = () => {
|
||||||
this.props.dispatch(fetchFavourites(this.props.params.statusId));
|
this.props.dispatch(fetchFavourites(this.props.params.statusId));
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, accountIds, multiColumn } = this.props;
|
const { intl, accountIds, multiColumn } = this.props;
|
||||||
|
|
|
@ -71,7 +71,7 @@ class SelectFilter extends React.PureComponent {
|
||||||
<span className='language-dropdown__dropdown__results__item__native-name'>{filter[1]}</span> {warning}
|
<span className='language-dropdown__dropdown__results__item__native-name'>{filter[1]}</span> {warning}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
renderCreateNew (name) {
|
renderCreateNew (name) {
|
||||||
return (
|
return (
|
||||||
|
@ -83,11 +83,11 @@ class SelectFilter extends React.PureComponent {
|
||||||
|
|
||||||
handleSearchChange = ({ target }) => {
|
handleSearchChange = ({ target }) => {
|
||||||
this.setState({ searchValue: target.value });
|
this.setState({ searchValue: target.value });
|
||||||
}
|
};
|
||||||
|
|
||||||
setListRef = c => {
|
setListRef = c => {
|
||||||
this.listNode = c;
|
this.listNode = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyDown = e => {
|
handleKeyDown = e => {
|
||||||
const index = Array.from(this.listNode.childNodes).findIndex(node => node === e.currentTarget);
|
const index = Array.from(this.listNode.childNodes).findIndex(node => node === e.currentTarget);
|
||||||
|
@ -125,7 +125,7 @@ class SelectFilter extends React.PureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleSearchKeyDown = e => {
|
handleSearchKeyDown = e => {
|
||||||
let element = null;
|
let element = null;
|
||||||
|
@ -143,11 +143,11 @@ class SelectFilter extends React.PureComponent {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClear = () => {
|
handleClear = () => {
|
||||||
this.setState({ searchValue: '' });
|
this.setState({ searchValue: '' });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleItemClick = e => {
|
handleItemClick = e => {
|
||||||
const value = e.currentTarget.getAttribute('data-index');
|
const value = e.currentTarget.getAttribute('data-index');
|
||||||
|
@ -155,7 +155,7 @@ class SelectFilter extends React.PureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
this.props.onSelectFilter(value);
|
this.props.onSelectFilter(value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleNewFilterClick = e => {
|
handleNewFilterClick = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
|
@ -50,7 +50,7 @@ class Account extends ImmutablePureComponent {
|
||||||
} else {
|
} else {
|
||||||
dispatch(followAccount(account.get('id')));
|
dispatch(followAccount(account.get('id')));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { account, intl } = this.props;
|
const { account, intl } = this.props;
|
||||||
|
|
|
@ -69,7 +69,7 @@ class FollowRecommendations extends ImmutablePureComponent {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
router.history.push('/home');
|
router.history.push('/home');
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { suggestions, isLoading } = this.props;
|
const { suggestions, isLoading } = this.props;
|
||||||
|
|
|
@ -38,7 +38,7 @@ class FollowedTags extends ImmutablePureComponent {
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.dispatch(fetchFollowedHashtags());
|
this.props.dispatch(fetchFollowedHashtags());
|
||||||
};
|
}
|
||||||
|
|
||||||
handleLoadMore = debounce(() => {
|
handleLoadMore = debounce(() => {
|
||||||
this.props.dispatch(expandFollowedHashtags());
|
this.props.dispatch(expandFollowedHashtags());
|
||||||
|
|
|
@ -35,7 +35,7 @@ class Content extends ImmutablePureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.node = c;
|
this.node = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
this._updateLinks();
|
this._updateLinks();
|
||||||
|
@ -89,7 +89,7 @@ class Content extends ImmutablePureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.context.router.history.push(`/@${mention.get('acct')}`);
|
this.context.router.history.push(`/@${mention.get('acct')}`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onHashtagClick = (hashtag, e) => {
|
onHashtagClick = (hashtag, e) => {
|
||||||
hashtag = hashtag.replace(/^#/, '');
|
hashtag = hashtag.replace(/^#/, '');
|
||||||
|
@ -98,14 +98,14 @@ class Content extends ImmutablePureComponent {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.context.router.history.push(`/tags/${hashtag}`);
|
this.context.router.history.push(`/tags/${hashtag}`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
onStatusClick = (status, e) => {
|
onStatusClick = (status, e) => {
|
||||||
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
if (this.context.router && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.context.router.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
|
this.context.router.history.push(`/@${status.getIn(['account', 'acct'])}/${status.get('id')}`);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseEnter = ({ currentTarget }) => {
|
handleMouseEnter = ({ currentTarget }) => {
|
||||||
if (autoPlayGif) {
|
if (autoPlayGif) {
|
||||||
|
@ -118,7 +118,7 @@ class Content extends ImmutablePureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-original');
|
emoji.src = emoji.getAttribute('data-original');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseLeave = ({ currentTarget }) => {
|
handleMouseLeave = ({ currentTarget }) => {
|
||||||
if (autoPlayGif) {
|
if (autoPlayGif) {
|
||||||
|
@ -131,7 +131,7 @@ class Content extends ImmutablePureComponent {
|
||||||
let emoji = emojis[i];
|
let emoji = emojis[i];
|
||||||
emoji.src = emoji.getAttribute('data-static');
|
emoji.src = emoji.getAttribute('data-static');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { announcement } = this.props;
|
const { announcement } = this.props;
|
||||||
|
@ -216,11 +216,11 @@ class Reaction extends ImmutablePureComponent {
|
||||||
} else {
|
} else {
|
||||||
addReaction(announcementId, reaction.get('name'));
|
addReaction(announcementId, reaction.get('name'));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMouseEnter = () => this.setState({ hovered: true })
|
handleMouseEnter = () => this.setState({ hovered: true });
|
||||||
|
|
||||||
handleMouseLeave = () => this.setState({ hovered: false })
|
handleMouseLeave = () => this.setState({ hovered: false });
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { reaction } = this.props;
|
const { reaction } = this.props;
|
||||||
|
@ -254,7 +254,7 @@ class ReactionsBar extends ImmutablePureComponent {
|
||||||
handleEmojiPick = data => {
|
handleEmojiPick = data => {
|
||||||
const { addReaction, announcementId } = this.props;
|
const { addReaction, announcementId } = this.props;
|
||||||
addReaction(announcementId, data.native.replace(/:/g, ''));
|
addReaction(announcementId, data.native.replace(/:/g, ''));
|
||||||
}
|
};
|
||||||
|
|
||||||
willEnter () {
|
willEnter () {
|
||||||
return { scale: reduceMotion ? 1 : 0 };
|
return { scale: reduceMotion ? 1 : 0 };
|
||||||
|
@ -397,15 +397,15 @@ class Announcements extends ImmutablePureComponent {
|
||||||
|
|
||||||
handleChangeIndex = index => {
|
handleChangeIndex = index => {
|
||||||
this.setState({ index: index % this.props.announcements.size });
|
this.setState({ index: index % this.props.announcements.size });
|
||||||
}
|
};
|
||||||
|
|
||||||
handleNextClick = () => {
|
handleNextClick = () => {
|
||||||
this.setState({ index: (this.state.index + 1) % this.props.announcements.size });
|
this.setState({ index: (this.state.index + 1) % this.props.announcements.size });
|
||||||
}
|
};
|
||||||
|
|
||||||
handlePrevClick = () => {
|
handlePrevClick = () => {
|
||||||
this.setState({ index: (this.props.announcements.size + this.state.index - 1) % this.props.announcements.size });
|
this.setState({ index: (this.props.announcements.size + this.state.index - 1) % this.props.announcements.size });
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { announcements, intl } = this.props;
|
const { announcements, intl } = this.props;
|
||||||
|
|
|
@ -54,7 +54,7 @@ class HashtagTimeline extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
dispatch(addColumn('HASHTAG', { id: this.props.params.id }));
|
dispatch(addColumn('HASHTAG', { id: this.props.params.id }));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
title = () => {
|
title = () => {
|
||||||
const { id } = this.props.params;
|
const { id } = this.props.params;
|
||||||
|
@ -73,7 +73,7 @@ class HashtagTimeline extends React.PureComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
return title;
|
return title;
|
||||||
}
|
};
|
||||||
|
|
||||||
additionalFor = (mode) => {
|
additionalFor = (mode) => {
|
||||||
const { tags } = this.props.params;
|
const { tags } = this.props.params;
|
||||||
|
@ -83,16 +83,16 @@ class HashtagTimeline extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMove = (dir) => {
|
handleMove = (dir) => {
|
||||||
const { columnId, dispatch } = this.props;
|
const { columnId, dispatch } = this.props;
|
||||||
dispatch(moveColumn(columnId, dir));
|
dispatch(moveColumn(columnId, dir));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHeaderClick = () => {
|
handleHeaderClick = () => {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
}
|
};
|
||||||
|
|
||||||
_subscribe (dispatch, id, tags = {}, local) {
|
_subscribe (dispatch, id, tags = {}, local) {
|
||||||
const { signedIn } = this.context.identity;
|
const { signedIn } = this.context.identity;
|
||||||
|
@ -157,14 +157,14 @@ class HashtagTimeline extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = maxId => {
|
handleLoadMore = maxId => {
|
||||||
const { dispatch, params } = this.props;
|
const { dispatch, params } = this.props;
|
||||||
const { id, tags, local } = params;
|
const { id, tags, local } = params;
|
||||||
|
|
||||||
dispatch(expandHashtagTimeline(id, { maxId, tags, local }));
|
dispatch(expandHashtagTimeline(id, { maxId, tags, local }));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleFollow = () => {
|
handleFollow = () => {
|
||||||
const { dispatch, params, tag } = this.props;
|
const { dispatch, params, tag } = this.props;
|
||||||
|
@ -180,7 +180,7 @@ class HashtagTimeline extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
dispatch(followHashtag(id));
|
dispatch(followHashtag(id));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { hasUnread, columnId, multiColumn, tag, intl } = this.props;
|
const { hasUnread, columnId, multiColumn, tag, intl } = this.props;
|
||||||
|
|
|
@ -58,24 +58,24 @@ class HomeTimeline extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
dispatch(addColumn('HOME', {}));
|
dispatch(addColumn('HOME', {}));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMove = (dir) => {
|
handleMove = (dir) => {
|
||||||
const { columnId, dispatch } = this.props;
|
const { columnId, dispatch } = this.props;
|
||||||
dispatch(moveColumn(columnId, dir));
|
dispatch(moveColumn(columnId, dir));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHeaderClick = () => {
|
handleHeaderClick = () => {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
}
|
};
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = maxId => {
|
handleLoadMore = maxId => {
|
||||||
this.props.dispatch(expandHomeTimeline({ maxId }));
|
this.props.dispatch(expandHomeTimeline({ maxId }));
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
setTimeout(() => this.props.dispatch(fetchAnnouncements()), 700);
|
setTimeout(() => this.props.dispatch(fetchAnnouncements()), 700);
|
||||||
|
@ -114,7 +114,7 @@ class HomeTimeline extends React.PureComponent {
|
||||||
handleToggleAnnouncementsClick = (e) => {
|
handleToggleAnnouncementsClick = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
this.props.dispatch(toggleShowAnnouncements());
|
this.props.dispatch(toggleShowAnnouncements());
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl, hasUnread, columnId, multiColumn, hasAnnouncements, unreadAnnouncements, showAnnouncements } = this.props;
|
const { intl, hasUnread, columnId, multiColumn, hasAnnouncements, unreadAnnouncements, showAnnouncements } = this.props;
|
||||||
|
|
|
@ -30,14 +30,14 @@ class Copypaste extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.input = c;
|
this.input = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleInputClick = () => {
|
handleInputClick = () => {
|
||||||
this.setState({ copied: false });
|
this.setState({ copied: false });
|
||||||
this.input.focus();
|
this.input.focus();
|
||||||
this.input.select();
|
this.input.select();
|
||||||
this.input.setSelectionRange(0, this.input.value.length);
|
this.input.setSelectionRange(0, this.input.value.length);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleButtonClick = () => {
|
handleButtonClick = () => {
|
||||||
const { value } = this.props;
|
const { value } = this.props;
|
||||||
|
@ -45,7 +45,7 @@ class Copypaste extends React.PureComponent {
|
||||||
this.input.blur();
|
this.input.blur();
|
||||||
this.setState({ copied: true });
|
this.setState({ copied: true });
|
||||||
this.timeout = setTimeout(() => this.setState({ copied: false }), 700);
|
this.timeout = setTimeout(() => this.setState({ copied: false }), 700);
|
||||||
}
|
};
|
||||||
|
|
||||||
componentWillUnmount () {
|
componentWillUnmount () {
|
||||||
if (this.timeout) clearTimeout(this.timeout);
|
if (this.timeout) clearTimeout(this.timeout);
|
||||||
|
@ -86,7 +86,7 @@ class InteractionModal extends React.PureComponent {
|
||||||
|
|
||||||
handleSignupClick = () => {
|
handleSignupClick = () => {
|
||||||
this.props.onSignupClick();
|
this.props.onSignupClick();
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { url, type, displayNameHtml } = this.props;
|
const { url, type, displayNameHtml } = this.props;
|
||||||
|
|
|
@ -33,16 +33,16 @@ class ListForm extends React.PureComponent {
|
||||||
|
|
||||||
handleChange = e => {
|
handleChange = e => {
|
||||||
this.props.onChange(e.target.value);
|
this.props.onChange(e.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleSubmit = e => {
|
handleSubmit = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.props.onSubmit();
|
this.props.onSubmit();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
this.props.onSubmit();
|
this.props.onSubmit();
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { value, disabled, intl } = this.props;
|
const { value, disabled, intl } = this.props;
|
||||||
|
|
|
@ -34,17 +34,17 @@ class Search extends React.PureComponent {
|
||||||
|
|
||||||
handleChange = e => {
|
handleChange = e => {
|
||||||
this.props.onChange(e.target.value);
|
this.props.onChange(e.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleKeyUp = e => {
|
handleKeyUp = e => {
|
||||||
if (e.keyCode === 13) {
|
if (e.keyCode === 13) {
|
||||||
this.props.onSubmit(this.props.value);
|
this.props.onSubmit(this.props.value);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClear = () => {
|
handleClear = () => {
|
||||||
this.props.onClear();
|
this.props.onClear();
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { value, intl } = this.props;
|
const { value, intl } = this.props;
|
||||||
|
|
|
@ -58,16 +58,16 @@ class ListTimeline extends React.PureComponent {
|
||||||
dispatch(addColumn('LIST', { id: this.props.params.id }));
|
dispatch(addColumn('LIST', { id: this.props.params.id }));
|
||||||
this.context.router.history.push('/');
|
this.context.router.history.push('/');
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMove = (dir) => {
|
handleMove = (dir) => {
|
||||||
const { columnId, dispatch } = this.props;
|
const { columnId, dispatch } = this.props;
|
||||||
dispatch(moveColumn(columnId, dir));
|
dispatch(moveColumn(columnId, dir));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHeaderClick = () => {
|
handleHeaderClick = () => {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
}
|
};
|
||||||
|
|
||||||
componentDidMount () {
|
componentDidMount () {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
|
@ -105,16 +105,16 @@ class ListTimeline extends React.PureComponent {
|
||||||
|
|
||||||
setRef = c => {
|
setRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleLoadMore = maxId => {
|
handleLoadMore = maxId => {
|
||||||
const { id } = this.props.params;
|
const { id } = this.props.params;
|
||||||
this.props.dispatch(expandListTimeline(id, { maxId }));
|
this.props.dispatch(expandListTimeline(id, { maxId }));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleEditClick = () => {
|
handleEditClick = () => {
|
||||||
this.props.dispatch(openModal('LIST_EDITOR', { listId: this.props.params.id }));
|
this.props.dispatch(openModal('LIST_EDITOR', { listId: this.props.params.id }));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleDeleteClick = () => {
|
handleDeleteClick = () => {
|
||||||
const { dispatch, columnId, intl } = this.props;
|
const { dispatch, columnId, intl } = this.props;
|
||||||
|
@ -133,13 +133,13 @@ class ListTimeline extends React.PureComponent {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleRepliesPolicyChange = ({ target }) => {
|
handleRepliesPolicyChange = ({ target }) => {
|
||||||
const { dispatch } = this.props;
|
const { dispatch } = this.props;
|
||||||
const { id } = this.props.params;
|
const { id } = this.props.params;
|
||||||
dispatch(updateList(id, undefined, false, target.value));
|
dispatch(updateList(id, undefined, false, target.value));
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { hasUnread, columnId, multiColumn, list, intl } = this.props;
|
const { hasUnread, columnId, multiColumn, list, intl } = this.props;
|
||||||
|
|
|
@ -34,16 +34,16 @@ class NewListForm extends React.PureComponent {
|
||||||
|
|
||||||
handleChange = e => {
|
handleChange = e => {
|
||||||
this.props.onChange(e.target.value);
|
this.props.onChange(e.target.value);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleSubmit = e => {
|
handleSubmit = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.props.onSubmit();
|
this.props.onSubmit();
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
this.props.onSubmit();
|
this.props.onSubmit();
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { value, disabled, intl } = this.props;
|
const { value, disabled, intl } = this.props;
|
||||||
|
|
|
@ -26,7 +26,7 @@ export default class ColumnSettings extends React.PureComponent {
|
||||||
|
|
||||||
onPushChange = (path, checked) => {
|
onPushChange = (path, checked) => {
|
||||||
this.props.onChange(['push', ...path], checked);
|
this.props.onChange(['push', ...path], checked);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { settings, pushSettings, onChange, onClear, alertsEnabled, browserSupport, browserPermission, onRequestNotificationPermission } = this.props;
|
const { settings, pushSettings, onChange, onClear, alertsEnabled, browserSupport, browserPermission, onRequestNotificationPermission } = this.props;
|
||||||
|
|
|
@ -61,12 +61,12 @@ class Notification extends ImmutablePureComponent {
|
||||||
handleMoveUp = () => {
|
handleMoveUp = () => {
|
||||||
const { notification, onMoveUp } = this.props;
|
const { notification, onMoveUp } = this.props;
|
||||||
onMoveUp(notification.get('id'));
|
onMoveUp(notification.get('id'));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMoveDown = () => {
|
handleMoveDown = () => {
|
||||||
const { notification, onMoveDown } = this.props;
|
const { notification, onMoveDown } = this.props;
|
||||||
onMoveDown(notification.get('id'));
|
onMoveDown(notification.get('id'));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOpen = () => {
|
handleOpen = () => {
|
||||||
const { notification } = this.props;
|
const { notification } = this.props;
|
||||||
|
@ -76,34 +76,34 @@ class Notification extends ImmutablePureComponent {
|
||||||
} else {
|
} else {
|
||||||
this.handleOpenProfile();
|
this.handleOpenProfile();
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleOpenProfile = () => {
|
handleOpenProfile = () => {
|
||||||
const { notification } = this.props;
|
const { notification } = this.props;
|
||||||
this.context.router.history.push(`/@${notification.getIn(['account', 'acct'])}`);
|
this.context.router.history.push(`/@${notification.getIn(['account', 'acct'])}`);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMention = e => {
|
handleMention = e => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
const { notification, onMention } = this.props;
|
const { notification, onMention } = this.props;
|
||||||
onMention(notification.get('account'), this.context.router.history);
|
onMention(notification.get('account'), this.context.router.history);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyFavourite = () => {
|
handleHotkeyFavourite = () => {
|
||||||
const { status } = this.props;
|
const { status } = this.props;
|
||||||
if (status) this.props.onFavourite(status);
|
if (status) this.props.onFavourite(status);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyBoost = e => {
|
handleHotkeyBoost = e => {
|
||||||
const { status } = this.props;
|
const { status } = this.props;
|
||||||
if (status) this.props.onReblog(status, e);
|
if (status) this.props.onReblog(status, e);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHotkeyToggleHidden = () => {
|
handleHotkeyToggleHidden = () => {
|
||||||
const { status } = this.props;
|
const { status } = this.props;
|
||||||
if (status) this.props.onToggleHidden(status);
|
if (status) this.props.onToggleHidden(status);
|
||||||
}
|
};
|
||||||
|
|
||||||
getHandlers () {
|
getHandlers () {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -23,11 +23,11 @@ class NotificationsPermissionBanner extends React.PureComponent {
|
||||||
|
|
||||||
handleClick = () => {
|
handleClick = () => {
|
||||||
this.props.dispatch(requestBrowserPermission());
|
this.props.dispatch(requestBrowserPermission());
|
||||||
}
|
};
|
||||||
|
|
||||||
handleClose = () => {
|
handleClose = () => {
|
||||||
this.props.dispatch(changeSetting(['notifications', 'dismissPermissionBanner'], true));
|
this.props.dispatch(changeSetting(['notifications', 'dismissPermissionBanner'], true));
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { intl } = this.props;
|
const { intl } = this.props;
|
||||||
|
|
|
@ -13,11 +13,11 @@ export default class SettingToggle extends React.PureComponent {
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
defaultValue: PropTypes.bool,
|
defaultValue: PropTypes.bool,
|
||||||
disabled: PropTypes.bool,
|
disabled: PropTypes.bool,
|
||||||
}
|
};
|
||||||
|
|
||||||
onChange = ({ target }) => {
|
onChange = ({ target }) => {
|
||||||
this.props.onChange(this.props.settingPath, target.checked);
|
this.props.onChange(this.props.settingPath, target.checked);
|
||||||
}
|
};
|
||||||
|
|
||||||
render () {
|
render () {
|
||||||
const { prefix, settings, settingPath, label, defaultValue, disabled } = this.props;
|
const { prefix, settings, settingPath, label, defaultValue, disabled } = this.props;
|
||||||
|
|
|
@ -136,30 +136,30 @@ class Notifications extends React.PureComponent {
|
||||||
} else {
|
} else {
|
||||||
dispatch(addColumn('NOTIFICATIONS', {}));
|
dispatch(addColumn('NOTIFICATIONS', {}));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMove = (dir) => {
|
handleMove = (dir) => {
|
||||||
const { columnId, dispatch } = this.props;
|
const { columnId, dispatch } = this.props;
|
||||||
dispatch(moveColumn(columnId, dir));
|
dispatch(moveColumn(columnId, dir));
|
||||||
}
|
};
|
||||||
|
|
||||||
handleHeaderClick = () => {
|
handleHeaderClick = () => {
|
||||||
this.column.scrollTop();
|
this.column.scrollTop();
|
||||||
}
|
};
|
||||||
|
|
||||||
setColumnRef = c => {
|
setColumnRef = c => {
|
||||||
this.column = c;
|
this.column = c;
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMoveUp = id => {
|
handleMoveUp = id => {
|
||||||
const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) - 1;
|
const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) - 1;
|
||||||
this._selectChild(elementIndex, true);
|
this._selectChild(elementIndex, true);
|
||||||
}
|
};
|
||||||
|
|
||||||
handleMoveDown = id => {
|
handleMoveDown = id => {
|
||||||
const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) + 1;
|
const elementIndex = this.props.notifications.findIndex(item => item !== null && item.get('id') === id) + 1;
|
||||||
this._selectChild(elementIndex, false);
|
this._selectChild(elementIndex, false);
|
||||||
}
|
};
|
||||||
|
|
||||||
_selectChild (index, align_top) {
|
_selectChild (index, align_top) {
|
||||||
const container = this.column.node;
|
const container = this.column.node;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue