From db28bb487bfb5c08d6381bdfde04dce0f0547328 Mon Sep 17 00:00:00 2001 From: Shlee Date: Fri, 30 Aug 2019 22:59:11 +0800 Subject: [PATCH 01/48] Pushed CircleCI docker images to more recent V (#11708) --- .circleci/config.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2355d9d7d8..8ab08ebae5 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -3,7 +3,7 @@ version: 2 aliases: - &defaults docker: - - image: circleci/ruby:2.6.0-stretch-node + - image: circleci/ruby:2.6-stretch-node environment: &ruby_environment BUNDLE_APP_CONFIG: ./.bundle/ DB_HOST: localhost @@ -105,14 +105,14 @@ jobs: install-ruby2.5: <<: *defaults docker: - - image: circleci/ruby:2.5.3-stretch-node + - image: circleci/ruby:2.5-stretch-node environment: *ruby_environment <<: *install_ruby_dependencies install-ruby2.4: <<: *defaults docker: - - image: circleci/ruby:2.4.5-stretch-node + - image: circleci/ruby:2.4-stretch-node environment: *ruby_environment <<: *install_ruby_dependencies @@ -131,40 +131,40 @@ jobs: test-ruby2.6: <<: *defaults docker: - - image: circleci/ruby:2.6.0-stretch-node + - image: circleci/ruby:2.6-stretch-node environment: *ruby_environment - image: circleci/postgres:10.6-alpine environment: POSTGRES_USER: root - - image: circleci/redis:5.0.3-alpine3.8 + - image: circleci/redis:5-alpine <<: *test_steps test-ruby2.5: <<: *defaults docker: - - image: circleci/ruby:2.5.3-stretch-node + - image: circleci/ruby:2.5-stretch-node environment: *ruby_environment - image: circleci/postgres:10.6-alpine environment: POSTGRES_USER: root - - image: circleci/redis:4.0.12-alpine + - image: circleci/redis:5-alpine <<: *test_steps test-ruby2.4: <<: *defaults docker: - - image: circleci/ruby:2.4.5-stretch-node + - image: circleci/ruby:2.4-stretch-node environment: *ruby_environment - image: circleci/postgres:10.6-alpine environment: POSTGRES_USER: root - - image: circleci/redis:4.0.12-alpine + - image: circleci/redis:5-alpine <<: *test_steps test-webui: <<: *defaults docker: - - image: circleci/node:8.15.0-stretch + - image: circleci/node:12.9-stretch steps: - *attach_workspace - run: ./bin/retry yarn test:jest From 33f4b6e1ebe64114ef29ed0facf59a18b910235a Mon Sep 17 00:00:00 2001 From: Shlee Date: Sun, 1 Sep 2019 02:06:49 +0800 Subject: [PATCH 02/48] Update Dockerfile (#11710) --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index d8c7e0f0c5..3cf12c22c6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,7 @@ RUN echo "Etc/UTC" > /etc/localtime && \ make install # Install jemalloc -ENV JE_VER="5.1.0" +ENV JE_VER="5.2.1" RUN apt update && \ apt -y install autoconf && \ cd ~ && \ @@ -30,7 +30,7 @@ RUN apt update && \ make install_bin install_include install_lib # Install ruby -ENV RUBY_VER="2.6.1" +ENV RUBY_VER="2.6.4" ENV CPPFLAGS="-I/opt/jemalloc/include" ENV LDFLAGS="-L/opt/jemalloc/lib/" RUN apt update && \ From 59b013df5f736de2ab959dbf139c2b961539cc71 Mon Sep 17 00:00:00 2001 From: Shlee Date: Sun, 1 Sep 2019 02:07:29 +0800 Subject: [PATCH 03/48] Update NodeJS source for Docker Image (#11707) * Update Ruby/Node/jemalloc source for Docker Image * Update Dockerfile * Update Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3cf12c22c6..b5904ad95c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ FROM ubuntu:18.04 as build-dep SHELL ["bash", "-c"] # Install Node -ENV NODE_VER="8.15.0" +ENV NODE_VER="12.9.1" RUN echo "Etc/UTC" > /etc/localtime && \ apt update && \ apt -y install wget make gcc g++ python && \ From d3442894310022062debc4c6ed6b117f8bc3904b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 1 Sep 2019 19:43:35 +0200 Subject: [PATCH 04/48] Add "not available" label on unknown media attachments (#11715) --- .../mastodon/components/media_gallery.js | 15 +++++++++++---- app/javascript/styles/mastodon/components.scss | 8 ++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js index 9cd71b7c99..55e0e77d62 100644 --- a/app/javascript/mastodon/components/media_gallery.js +++ b/app/javascript/mastodon/components/media_gallery.js @@ -315,15 +315,22 @@ class MediaGallery extends React.PureComponent { style.height = height; } - const size = media.take(4).size; + const size = media.take(4).size; + const uncached = media.every(attachment => attachment.get('type') === 'unknown'); if (this.isStandaloneEligible()) { children = ; } else { - children = media.take(4).map((attachment, i) => ); + children = media.take(4).map((attachment, i) => ); } - if (visible) { + if (uncached) { + spoilerButton = ( + + ); + } else if (visible) { spoilerButton = ; } else { spoilerButton = ( @@ -335,7 +342,7 @@ class MediaGallery extends React.PureComponent { return (
-
+
{spoilerButton}
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index d7e90fcafc..0b569bb8f6 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -3477,6 +3477,14 @@ a.status-card.compact:hover { background: rgba($base-overlay-background, 0.8); } } + + &:disabled { + cursor: not-allowed; + + .spoiler-button__overlay__label { + background: rgba($base-overlay-background, 0.5); + } + } } } From 47584180d8ed03666d45f423107d3113cc4a6230 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 1 Sep 2019 19:44:05 +0200 Subject: [PATCH 05/48] Fix wrong percentages in admin UI for hashtag usage breakdown (#11714) --- app/controllers/admin/tags_controller.rb | 3 ++- app/views/admin/tags/show.html.haml | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/tags_controller.rb b/app/controllers/admin/tags_controller.rb index 39aca2a4b3..25d9b7d3d2 100644 --- a/app/controllers/admin/tags_controller.rb +++ b/app/controllers/admin/tags_controller.rb @@ -37,7 +37,8 @@ module Admin def set_usage_by_domain @usage_by_domain = @tag.statuses - .where(visibility: :public) + .with_public_visibility + .excluding_silenced_accounts .where(Status.arel_table[:id].gteq(Mastodon::Snowflake.id_at(Time.now.utc.beginning_of_day))) .joins(:account) .group('accounts.domain') diff --git a/app/views/admin/tags/show.html.haml b/app/views/admin/tags/show.html.haml index c3779d48c4..f9677874a7 100644 --- a/app/views/admin/tags/show.html.haml +++ b/app/views/admin/tags/show.html.haml @@ -38,8 +38,10 @@ .table-wrapper %table.table %tbody + - total = @usage_by_domain.sum(&:statuses_count).to_f + - @usage_by_domain.each do |(domain, count)| %tr %th= domain || site_hostname - %td= number_to_percentage((count / @tag.history[0][:uses].to_f) * 100) + %td= number_to_percentage((count / total) * 100, precision: 1) %td= number_with_delimiter count From 34eac5a1ecab250760bec1f703ddf828670210fa Mon Sep 17 00:00:00 2001 From: ThibG Date: Sun, 1 Sep 2019 20:04:35 +0200 Subject: [PATCH 06/48] Fix custom emoji animation on hover in WebUI directory bios (#11716) --- .../directory/components/account_card.js | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/app/javascript/mastodon/features/directory/components/account_card.js b/app/javascript/mastodon/features/directory/components/account_card.js index cb23a02bad..50ad744501 100644 --- a/app/javascript/mastodon/features/directory/components/account_card.js +++ b/app/javascript/mastodon/features/directory/components/account_card.js @@ -82,6 +82,43 @@ class AccountCard extends ImmutablePureComponent { onMute: PropTypes.func.isRequired, }; + _updateEmojis () { + const node = this.node; + + if (!node || autoPlayGif) { + return; + } + + const emojis = node.querySelectorAll('.custom-emoji'); + + for (var i = 0; i < emojis.length; i++) { + let emoji = emojis[i]; + if (emoji.classList.contains('status-emoji')) { + continue; + } + emoji.classList.add('status-emoji'); + + emoji.addEventListener('mouseenter', this.handleEmojiMouseEnter, false); + emoji.addEventListener('mouseleave', this.handleEmojiMouseLeave, false); + } + } + + componentDidMount () { + this._updateEmojis(); + } + + componentDidUpdate () { + this._updateEmojis(); + } + + handleEmojiMouseEnter = ({ target }) => { + target.src = target.getAttribute('data-original'); + } + + handleEmojiMouseLeave = ({ target }) => { + target.src = target.getAttribute('data-static'); + } + handleFollow = () => { this.props.onFollow(this.props.account); } @@ -94,6 +131,10 @@ class AccountCard extends ImmutablePureComponent { this.props.onMute(this.props.account); } + setRef = (c) => { + this.node = c; + } + render () { const { account, intl } = this.props; @@ -133,7 +174,7 @@ class AccountCard extends ImmutablePureComponent {
-
+
From dd45df66303795d4156606db47e300909b533721 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2019 20:18:22 +0900 Subject: [PATCH 07/48] Bump @babel/plugin-transform-runtime from 7.4.4 to 7.5.5 (#11725) Bumps [@babel/plugin-transform-runtime](https://github.com/babel/babel) from 7.4.4 to 7.5.5. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/master/CHANGELOG.md) - [Commits](https://github.com/babel/babel/compare/v7.4.4...v7.5.5) Signed-off-by: dependabot-preview[bot] --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index f79fa49121..932aa059e3 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "@babel/plugin-transform-react-inline-elements": "^7.2.0", "@babel/plugin-transform-react-jsx-self": "^7.2.0", "@babel/plugin-transform-react-jsx-source": "^7.5.0", - "@babel/plugin-transform-runtime": "^7.4.4", + "@babel/plugin-transform-runtime": "^7.5.5", "@babel/preset-env": "^7.5.5", "@babel/preset-react": "^7.0.0", "@babel/runtime": "^7.5.4", diff --git a/yarn.lock b/yarn.lock index a02b5a0816..51b9c055c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -657,10 +657,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.0.0" -"@babel/plugin-transform-runtime@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.4.4.tgz#a50f5d16e9c3a4ac18a1a9f9803c107c380bce08" - integrity sha512-aMVojEjPszvau3NRg+TIH14ynZLvPewH4xhlCW1w6A3rkxTS1m4uwzRclYR9oS+rl/dr+kT+pzbfHuAWP/lc7Q== +"@babel/plugin-transform-runtime@^7.5.5": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.5.5.tgz#a6331afbfc59189d2135b2e09474457a8e3d28bc" + integrity sha512-6Xmeidsun5rkwnGfMOp6/z9nSzWpHFNVr2Jx7kwoq4mVatQfQx5S56drBgEHF+XQbKOdIaOiMIINvp/kAwMN+w== dependencies: "@babel/helper-module-imports" "^7.0.0" "@babel/helper-plugin-utils" "^7.0.0" From ac6935b629f5e9cd07cca468a6f3588a6e585e25 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 2 Sep 2019 20:19:16 +0900 Subject: [PATCH 08/48] Bump babel-eslint from 10.0.2 to 10.0.3 (#11723) Bumps [babel-eslint](https://github.com/babel/babel-eslint) from 10.0.2 to 10.0.3. - [Release notes](https://github.com/babel/babel-eslint/releases) - [Commits](https://github.com/babel/babel-eslint/compare/v10.0.2...v10.0.3) Signed-off-by: dependabot-preview[bot] --- package.json | 2 +- yarn.lock | 59 +++++++++++----------------------------------------- 2 files changed, 13 insertions(+), 48 deletions(-) diff --git a/package.json b/package.json index 932aa059e3..135ba684a2 100644 --- a/package.json +++ b/package.json @@ -169,7 +169,7 @@ "websocket.js": "^0.1.12" }, "devDependencies": { - "babel-eslint": "^10.0.2", + "babel-eslint": "^10.0.3", "babel-jest": "^24.8.0", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.14.0", diff --git a/yarn.lock b/yarn.lock index 51b9c055c9..cd8618714f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,14 +2,7 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" - integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA== - dependencies: - "@babel/highlight" "^7.0.0" - -"@babel/code-frame@^7.5.5": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== @@ -291,12 +284,7 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.2.2", "@babel/parser@^7.3.4", "@babel/parser@^7.4.4", "@babel/parser@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.5.tgz#04af8d5d5a2b044a2a1bffacc1e5e6673544e872" - integrity sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew== - -"@babel/parser@^7.5.5": +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.2.2", "@babel/parser@^7.3.4", "@babel/parser@^7.4.4", "@babel/parser@^7.4.5", "@babel/parser@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b" integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g== @@ -819,22 +807,7 @@ "@babel/parser" "^7.4.4" "@babel/types" "^7.4.4" -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.3.4", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.5.tgz#4e92d1728fd2f1897dafdd321efbff92156c3216" - integrity sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A== - dependencies: - "@babel/code-frame" "^7.0.0" - "@babel/generator" "^7.4.4" - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-split-export-declaration" "^7.4.4" - "@babel/parser" "^7.4.5" - "@babel/types" "^7.4.4" - debug "^4.1.0" - globals "^11.1.0" - lodash "^4.17.11" - -"@babel/traverse@^7.5.5": +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.3.4", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5": version "7.5.5" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.5.5.tgz#f664f8f368ed32988cd648da9f72d5ca70f165bb" integrity sha512-MqB0782whsfffYfSjH4TM+LMjrJnhCNEDMDIjeTpl+ASaUvxcjoiVCo/sM1GhS1pHOXYfWVCYneLjMckuUxDaQ== @@ -1733,17 +1706,17 @@ axobject-query@^2.0.2: dependencies: ast-types-flow "0.0.7" -babel-eslint@^10.0.2: - version "10.0.2" - resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.2.tgz#182d5ac204579ff0881684b040560fdcc1558456" - integrity sha512-UdsurWPtgiPgpJ06ryUnuaSXC2s0WoSZnQmEpbAH65XZSdwowgN5MvyP7e88nW07FYXv72erVtpBkxyDVKhH1Q== +babel-eslint@^10.0.3: + version "10.0.3" + resolved "https://registry.yarnpkg.com/babel-eslint/-/babel-eslint-10.0.3.tgz#81a2c669be0f205e19462fed2482d33e4687a88a" + integrity sha512-z3U7eMY6r/3f3/JB9mTsLjyxrv0Yb1zb8PCWCLpguxfCzBIZUwy23R1t/XKewP+8mEN2Ck8Dtr4q20z6ce6SoA== dependencies: "@babel/code-frame" "^7.0.0" "@babel/parser" "^7.0.0" "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" - eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" + resolve "^1.12.0" babel-jest@^24.8.0: version "24.8.0" @@ -3812,14 +3785,6 @@ eslint-plugin-react@~7.14.3: prop-types "^15.7.2" resolve "^1.10.1" -eslint-scope@3.7.1: - version "3.7.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" - integrity sha1-PWPD7f2gLgbgGkUq2IyqzHzctug= - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - eslint-scope@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" @@ -9019,10 +8984,10 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" - integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== +resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.12.0.tgz#3fc644a35c84a48554609ff26ec52b66fa577df6" + integrity sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w== dependencies: path-parse "^1.0.6" From 70ddef2654a931827ce5e4323e3042365f6078f2 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 2 Sep 2019 18:11:13 +0200 Subject: [PATCH 09/48] Change trending hashtags to not disappear instantly after midnight (#11712) --- app/controllers/admin/tags_controller.rb | 2 +- app/lib/feed_manager.rb | 2 +- app/models/tag.rb | 4 +- app/models/trending_tags.rb | 102 ++++++++++++------ .../scheduler/trending_tags_scheduler.rb | 11 ++ config/sidekiq.yml | 3 + .../20190901035623_add_max_score_to_tags.rb | 6 ++ .../20190901040524_remove_score_from_tags.rb | 12 +++ db/schema.rb | 6 +- spec/models/trending_tags_spec.rb | 68 ++++++++++++ 10 files changed, 179 insertions(+), 37 deletions(-) create mode 100644 app/workers/scheduler/trending_tags_scheduler.rb create mode 100644 db/migrate/20190901035623_add_max_score_to_tags.rb create mode 100644 db/post_migrate/20190901040524_remove_score_from_tags.rb create mode 100644 spec/models/trending_tags_spec.rb diff --git a/app/controllers/admin/tags_controller.rb b/app/controllers/admin/tags_controller.rb index 25d9b7d3d2..8bd4e5f8b7 100644 --- a/app/controllers/admin/tags_controller.rb +++ b/app/controllers/admin/tags_controller.rb @@ -57,7 +57,7 @@ module Admin scope = scope.unreviewed if filter_params[:review] == 'unreviewed' scope = scope.reviewed.order(reviewed_at: :desc) if filter_params[:review] == 'reviewed' scope = scope.pending_review.order(requested_review_at: :desc) if filter_params[:review] == 'pending_review' - scope.order(score: :desc) + scope.order(max_score: :desc) end def filter_params diff --git a/app/lib/feed_manager.rb b/app/lib/feed_manager.rb index ca3d890a81..871ec5c194 100644 --- a/app/lib/feed_manager.rb +++ b/app/lib/feed_manager.rb @@ -63,7 +63,7 @@ class FeedManager reblog_key = key(type, account_id, 'reblogs') # Remove any items past the MAX_ITEMS'th entry in our feed - redis.zremrangebyrank(timeline_key, '0', (-(FeedManager::MAX_ITEMS + 1)).to_s) + redis.zremrangebyrank(timeline_key, 0, -(FeedManager::MAX_ITEMS + 1)) # Get the score of the REBLOG_FALLOFF'th item in our feed, and stop # tracking anything after it for deduplication purposes. diff --git a/app/models/tag.rb b/app/models/tag.rb index 945e3a3c62..135e0a0306 100644 --- a/app/models/tag.rb +++ b/app/models/tag.rb @@ -7,14 +7,14 @@ # name :string default(""), not null # created_at :datetime not null # updated_at :datetime not null -# score :integer # usable :boolean # trendable :boolean # listable :boolean # reviewed_at :datetime # requested_review_at :datetime # last_status_at :datetime -# last_trend_at :datetime +# max_score :float +# max_score_at :datetime # class Tag < ApplicationRecord diff --git a/app/models/trending_tags.rb b/app/models/trending_tags.rb index e4ce988c18..e1b92b1757 100644 --- a/app/models/trending_tags.rb +++ b/app/models/trending_tags.rb @@ -7,6 +7,8 @@ class TrendingTags THRESHOLD = 5 LIMIT = 10 REVIEW_THRESHOLD = 3 + MAX_SCORE_COOLDOWN = 3.days.freeze + MAX_SCORE_HALFLIFE = 6.hours.freeze class << self include Redisable @@ -16,14 +18,75 @@ class TrendingTags increment_historical_use!(tag.id, at_time) increment_unique_use!(tag.id, account.id, at_time) - increment_vote!(tag, at_time) + increment_use!(tag.id, at_time) tag.update(last_status_at: Time.now.utc) if tag.last_status_at.nil? || tag.last_status_at < 12.hours.ago - tag.update(last_trend_at: Time.now.utc) if trending?(tag) && (tag.last_trend_at.nil? || tag.last_trend_at < 12.hours.ago) + end + + def update!(at_time = Time.now.utc) + tag_ids = redis.smembers("#{KEY}:used:#{at_time.beginning_of_day.to_i}") + redis.zrange(KEY, 0, -1) + tags = Tag.where(id: tag_ids.uniq) + + # First pass to calculate scores and update the set + + tags.each do |tag| + expected = redis.pfcount("activity:tags:#{tag.id}:#{(at_time - 1.day).beginning_of_day.to_i}:accounts").to_f + expected = 1.0 if expected.zero? + observed = redis.pfcount("activity:tags:#{tag.id}:#{at_time.beginning_of_day.to_i}:accounts").to_f + max_time = tag.max_score_at + max_score = tag.max_score + max_score = 0 if max_time.nil? || max_time < (at_time - MAX_SCORE_COOLDOWN) + + score = begin + if expected > observed || observed < THRESHOLD + 0 + else + ((observed - expected)**2) / expected + end + end + + if score > max_score + max_score = score + max_time = at_time + + # Not interested in triggering any callbacks for this + tag.update_columns(max_score: max_score, max_score_at: max_time) + end + + decaying_score = max_score * (0.5**((at_time.to_f - max_time.to_f) / MAX_SCORE_HALFLIFE.to_f)) + + if decaying_score.zero? + redis.zrem(KEY, tag.id) + else + redis.zadd(KEY, decaying_score, tag.id) + end + end + + users_for_review = User.staff.includes(:account).to_a.select(&:allows_trending_tag_emails?) + + # Second pass to notify about previously unreviewed trends + + tags.each do |tag| + current_rank = redis.zrevrank(KEY, tag.id) + needs_review_notification = tag.requires_review? && !tag.requested_review? + rank_passes_threshold = current_rank.present? && current_rank <= REVIEW_THRESHOLD + + next unless !tag.trendable? && rank_passes_threshold && needs_review_notification + + tag.touch(:requested_review_at) + + users_for_review.each do |user| + AdminMailer.new_trending_tag(user.account, tag).deliver_later! + end + end + + # Trim older items + + redis.zremrangebyrank(KEY, 0, -(LIMIT + 1)) end def get(limit, filtered: true) - tag_ids = redis.zrevrange("#{KEY}:#{Time.now.utc.beginning_of_day.to_i}", 0, LIMIT - 1).map(&:to_i) + tag_ids = redis.zrevrange(KEY, 0, LIMIT - 1).map(&:to_i) tags = Tag.where(id: tag_ids) tags = tags.where(trendable: true) if filtered @@ -33,8 +96,8 @@ class TrendingTags end def trending?(tag) - rank = redis.zrevrank("#{KEY}:#{Time.now.utc.beginning_of_day.to_i}", tag.id) - rank.present? && rank <= LIMIT + rank = redis.zrevrank(KEY, tag.id) + rank.present? && rank < LIMIT end private @@ -51,31 +114,10 @@ class TrendingTags redis.expire(key, EXPIRE_HISTORY_AFTER) end - def increment_vote!(tag, at_time) - key = "#{KEY}:#{at_time.beginning_of_day.to_i}" - expected = redis.pfcount("activity:tags:#{tag.id}:#{(at_time - 1.day).beginning_of_day.to_i}:accounts").to_f - expected = 1.0 if expected.zero? - observed = redis.pfcount("activity:tags:#{tag.id}:#{at_time.beginning_of_day.to_i}:accounts").to_f - - if expected > observed || observed < THRESHOLD - redis.zrem(key, tag.id) - else - score = ((observed - expected)**2) / expected - old_rank = redis.zrevrank(key, tag.id) - - redis.zadd(key, score, tag.id) - request_review!(tag) if (old_rank.nil? || old_rank > REVIEW_THRESHOLD) && redis.zrevrank(key, tag.id) <= REVIEW_THRESHOLD && !tag.trendable? && tag.requires_review? && !tag.requested_review? - end - - redis.expire(key, EXPIRE_TRENDS_AFTER) - end - - def request_review!(tag) - return unless Setting.trends - - tag.touch(:requested_review_at) - - User.staff.includes(:account).find_each { |u| AdminMailer.new_trending_tag(u.account, tag).deliver_later! if u.allows_trending_tag_emails? } + def increment_use!(tag_id, at_time) + key = "#{KEY}:used:#{at_time.beginning_of_day.to_i}" + redis.sadd(key, tag_id) + redis.expire(key, EXPIRE_HISTORY_AFTER) end end end diff --git a/app/workers/scheduler/trending_tags_scheduler.rb b/app/workers/scheduler/trending_tags_scheduler.rb new file mode 100644 index 0000000000..77f0d57475 --- /dev/null +++ b/app/workers/scheduler/trending_tags_scheduler.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class Scheduler::TrendingTagsScheduler + include Sidekiq::Worker + + sidekiq_options unique: :until_executed, retry: 0 + + def perform + TrendingTags.update! if Setting.trends + end +end diff --git a/config/sidekiq.yml b/config/sidekiq.yml index 6ebe450b00..5de25de234 100644 --- a/config/sidekiq.yml +++ b/config/sidekiq.yml @@ -9,6 +9,9 @@ scheduled_statuses_scheduler: every: '5m' class: Scheduler::ScheduledStatusesScheduler + trending_tags_scheduler: + every: '5m' + class: Scheduler::TrendingTagsScheduler media_cleanup_scheduler: cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *' class: Scheduler::MediaCleanupScheduler diff --git a/db/migrate/20190901035623_add_max_score_to_tags.rb b/db/migrate/20190901035623_add_max_score_to_tags.rb new file mode 100644 index 0000000000..f936e98718 --- /dev/null +++ b/db/migrate/20190901035623_add_max_score_to_tags.rb @@ -0,0 +1,6 @@ +class AddMaxScoreToTags < ActiveRecord::Migration[5.2] + def change + add_column :tags, :max_score, :float + add_column :tags, :max_score_at, :datetime + end +end diff --git a/db/post_migrate/20190901040524_remove_score_from_tags.rb b/db/post_migrate/20190901040524_remove_score_from_tags.rb new file mode 100644 index 0000000000..a1112700b5 --- /dev/null +++ b/db/post_migrate/20190901040524_remove_score_from_tags.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +class RemoveScoreFromTags < ActiveRecord::Migration[5.2] + disable_ddl_transaction! + + def change + safety_assured do + remove_column :tags, :score, :int + remove_column :tags, :last_trend_at, :datetime + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 482bca367a..5576f70bf4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2019_08_23_221802) do +ActiveRecord::Schema.define(version: 2019_09_01_040524) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -664,14 +664,14 @@ ActiveRecord::Schema.define(version: 2019_08_23_221802) do t.string "name", default: "", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.integer "score" t.boolean "usable" t.boolean "trendable" t.boolean "listable" t.datetime "reviewed_at" t.datetime "requested_review_at" t.datetime "last_status_at" - t.datetime "last_trend_at" + t.float "max_score" + t.datetime "max_score_at" t.index "lower((name)::text)", name: "index_tags_on_name_lower", unique: true end diff --git a/spec/models/trending_tags_spec.rb b/spec/models/trending_tags_spec.rb new file mode 100644 index 0000000000..b6122c9948 --- /dev/null +++ b/spec/models/trending_tags_spec.rb @@ -0,0 +1,68 @@ +require 'rails_helper' + +RSpec.describe TrendingTags do + describe '.record_use!' do + pending + end + + describe '.update!' do + let!(:at_time) { Time.now.utc } + let!(:tag1) { Fabricate(:tag, name: 'Catstodon') } + let!(:tag2) { Fabricate(:tag, name: 'DogsOfMastodon') } + let!(:tag3) { Fabricate(:tag, name: 'OCs') } + + before do + allow(Redis.current).to receive(:pfcount) do |key| + case key + when "activity:tags:#{tag1.id}:#{(at_time - 1.day).beginning_of_day.to_i}:accounts" + 2 + when "activity:tags:#{tag1.id}:#{at_time.beginning_of_day.to_i}:accounts" + 16 + when "activity:tags:#{tag2.id}:#{(at_time - 1.day).beginning_of_day.to_i}:accounts" + 0 + when "activity:tags:#{tag2.id}:#{at_time.beginning_of_day.to_i}:accounts" + 4 + when "activity:tags:#{tag3.id}:#{(at_time - 1.day).beginning_of_day.to_i}:accounts" + 13 + end + end + + Redis.current.zadd('trending_tags', 0.9, tag3.id) + Redis.current.sadd("trending_tags:used:#{at_time.beginning_of_day.to_i}", [tag1.id, tag2.id]) + + tag3.update(max_score: 0.9, max_score_at: (at_time - 1.day).beginning_of_day + 12.hours) + + described_class.update!(at_time) + end + + it 'calculates and re-calculates scores' do + expect(described_class.get(10, filtered: false)).to eq [tag1, tag3] + end + + it 'omits hashtags below threshold' do + expect(described_class.get(10, filtered: false)).to_not include(tag2) + end + + it 'decays scores' do + expect(Redis.current.zscore('trending_tags', tag3.id)).to be < 0.9 + end + end + + describe '.trending?' do + let(:tag) { Fabricate(:tag) } + + before do + 10.times { |i| Redis.current.zadd('trending_tags', i + 1, Fabricate(:tag).id) } + end + + it 'returns true if the hashtag is within limit' do + Redis.current.zadd('trending_tags', 11, tag.id) + expect(described_class.trending?(tag)).to be true + end + + it 'returns false if the hashtag is outside the limit' do + Redis.current.zadd('trending_tags', 0, tag.id) + expect(described_class.trending?(tag)).to be false + end + end +end From 6493f4ffaea9ae391a9cc24e2743531fd0c3a3e8 Mon Sep 17 00:00:00 2001 From: ThibG Date: Mon, 2 Sep 2019 18:11:34 +0200 Subject: [PATCH 10/48] Fix height of dashboard counters (#11736) --- app/javascript/styles/mastodon/dashboard.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/javascript/styles/mastodon/dashboard.scss b/app/javascript/styles/mastodon/dashboard.scss index e4564f062c..c0944d417d 100644 --- a/app/javascript/styles/mastodon/dashboard.scss +++ b/app/javascript/styles/mastodon/dashboard.scss @@ -15,6 +15,8 @@ padding: 20px; background: lighten($ui-base-color, 4%); border-radius: 4px; + box-sizing: border-box; + height: 100%; } & > a { From 0ea53122f2a0db726afe96cfedd8e7fe3d930e0a Mon Sep 17 00:00:00 2001 From: ThibG Date: Mon, 2 Sep 2019 18:12:12 +0200 Subject: [PATCH 11/48] Fix Mastodon logo style on hover on public pages' footer (#11735) Fixes #11690 --- app/javascript/styles/mastodon/footer.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/styles/mastodon/footer.scss b/app/javascript/styles/mastodon/footer.scss index f74c004e99..00d2908832 100644 --- a/app/javascript/styles/mastodon/footer.scss +++ b/app/javascript/styles/mastodon/footer.scss @@ -128,7 +128,7 @@ &:hover, &:focus, &:active { - svg path { + svg { fill: lighten($ui-base-color, 38%); } } From 1f22b8197cb961371fa761e1fa214d4f4a2074d1 Mon Sep 17 00:00:00 2001 From: mayaeh Date: Tue, 3 Sep 2019 01:12:27 +0900 Subject: [PATCH 12/48] Integrate translation strings for the Profile Directory. (#11722) Run `yarn manage:translations en` --- .../ui/components/navigation_panel.js | 2 +- .../mastodon/locales/defaultMessages.json | 119 +++++++++++++++++- app/javascript/mastodon/locales/en.json | 13 +- app/views/directories/index.html.haml | 2 +- config/locales/en.yml | 1 + 5 files changed, 130 insertions(+), 7 deletions(-) diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.js b/app/javascript/mastodon/features/ui/components/navigation_panel.js index 6f07778f24..51e3ec037d 100644 --- a/app/javascript/mastodon/features/ui/components/navigation_panel.js +++ b/app/javascript/mastodon/features/ui/components/navigation_panel.js @@ -18,7 +18,7 @@ const NavigationPanel = () => ( - {profile_directory && } + {profile_directory && } diff --git a/app/javascript/mastodon/locales/defaultMessages.json b/app/javascript/mastodon/locales/defaultMessages.json index 9118527dbc..db2d1c7bd7 100644 --- a/app/javascript/mastodon/locales/defaultMessages.json +++ b/app/javascript/mastodon/locales/defaultMessages.json @@ -8,6 +8,14 @@ { "defaultMessage": "An unexpected error occurred.", "id": "alert.unexpected.message" + }, + { + "defaultMessage": "Rate limited", + "id": "alert.rate_limited.title" + }, + { + "defaultMessage": "Please retry after {retry_time, time, medium}.", + "id": "alert.rate_limited.message" } ], "path": "app/javascript/mastodon/actions/alerts.json" @@ -191,6 +199,10 @@ "defaultMessage": "Toggle visibility", "id": "media_gallery.toggle_visible" }, + { + "defaultMessage": "Not available", + "id": "status.uncached_media_warning" + }, { "defaultMessage": "Sensitive content", "id": "status.sensitive_warning" @@ -1130,6 +1142,19 @@ ], "path": "app/javascript/mastodon/features/compose/components/upload.json" }, + { + "descriptors": [ + { + "defaultMessage": "Are you sure you want to log out?", + "id": "confirmations.logout.message" + }, + { + "defaultMessage": "Log out", + "id": "confirmations.logout.confirm" + } + ], + "path": "app/javascript/mastodon/features/compose/containers/navigation_container.json" + }, { "descriptors": [ { @@ -1218,6 +1243,14 @@ { "defaultMessage": "Compose new toot", "id": "navigation_bar.compose" + }, + { + "defaultMessage": "Are you sure you want to log out?", + "id": "confirmations.logout.message" + }, + { + "defaultMessage": "Log out", + "id": "confirmations.logout.confirm" } ], "path": "app/javascript/mastodon/features/compose/index.json" @@ -1235,6 +1268,76 @@ ], "path": "app/javascript/mastodon/features/direct_timeline/index.json" }, + { + "descriptors": [ + { + "defaultMessage": "Follow", + "id": "account.follow" + }, + { + "defaultMessage": "Unfollow", + "id": "account.unfollow" + }, + { + "defaultMessage": "Awaiting approval", + "id": "account.requested" + }, + { + "defaultMessage": "Unblock @{name}", + "id": "account.unblock" + }, + { + "defaultMessage": "Unmute @{name}", + "id": "account.unmute" + }, + { + "defaultMessage": "Are you sure you want to unfollow {name}?", + "id": "confirmations.unfollow.message" + }, + { + "defaultMessage": "Toots", + "id": "account.posts" + }, + { + "defaultMessage": "Followers", + "id": "account.followers" + }, + { + "defaultMessage": "Never", + "id": "account.never_active" + }, + { + "defaultMessage": "Last active", + "id": "account.last_status" + } + ], + "path": "app/javascript/mastodon/features/directory/components/account_card.json" + }, + { + "descriptors": [ + { + "defaultMessage": "Browse profiles", + "id": "column.directory" + }, + { + "defaultMessage": "Recently active", + "id": "directory.recently_active" + }, + { + "defaultMessage": "New arrivals", + "id": "directory.new_arrivals" + }, + { + "defaultMessage": "From {domain} only", + "id": "directory.local" + }, + { + "defaultMessage": "From known fediverse", + "id": "directory.federated" + } + ], + "path": "app/javascript/mastodon/features/directory/index.json" + }, { "descriptors": [ { @@ -2312,6 +2415,14 @@ }, { "descriptors": [ + { + "defaultMessage": "Are you sure you want to log out?", + "id": "confirmations.logout.message" + }, + { + "defaultMessage": "Log out", + "id": "confirmations.logout.confirm" + }, { "defaultMessage": "Invite people", "id": "getting_started.invite" @@ -2427,6 +2538,10 @@ "defaultMessage": "Lists", "id": "navigation_bar.lists" }, + { + "defaultMessage": "Profile directory", + "id": "getting_started.directory" + }, { "defaultMessage": "Preferences", "id": "navigation_bar.preferences" @@ -2434,10 +2549,6 @@ { "defaultMessage": "Follows and followers", "id": "navigation_bar.follows_and_followers" - }, - { - "defaultMessage": "Profile directory", - "id": "navigation_bar.profile_directory" } ], "path": "app/javascript/mastodon/features/ui/components/navigation_panel.json" diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json index 6c0c5cbb89..debc755c36 100644 --- a/app/javascript/mastodon/locales/en.json +++ b/app/javascript/mastodon/locales/en.json @@ -16,6 +16,7 @@ "account.follows.empty": "This user doesn't follow anyone yet.", "account.follows_you": "Follows you", "account.hide_reblogs": "Hide boosts from @{name}", + "account.last_status": "Last active", "account.link_verified_on": "Ownership of this link was checked on {date}", "account.locked_info": "This account privacy status is set to locked. The owner manually reviews who can follow them.", "account.media": "Media", @@ -24,6 +25,7 @@ "account.mute": "Mute @{name}", "account.mute_notifications": "Mute notifications from @{name}", "account.muted": "Muted", + "account.never_active": "Never", "account.posts": "Toots", "account.posts_with_replies": "Toots and replies", "account.report": "Report @{name}", @@ -36,6 +38,8 @@ "account.unfollow": "Unfollow", "account.unmute": "Unmute @{name}", "account.unmute_notifications": "Unmute notifications from @{name}", + "alert.rate_limited.message": "Please retry after {retry_time, time, medium}.", + "alert.rate_limited.title": "Rate limited", "alert.unexpected.message": "An unexpected error occurred.", "alert.unexpected.title": "Oops!", "autosuggest_hashtag.per_week": "{count} per week", @@ -49,6 +53,7 @@ "column.blocks": "Blocked users", "column.community": "Local timeline", "column.direct": "Direct messages", + "column.directory": "Browse profiles", "column.domain_blocks": "Hidden domains", "column.favourites": "Favourites", "column.follow_requests": "Follow requests", @@ -95,6 +100,8 @@ "confirmations.delete_list.message": "Are you sure you want to permanently delete this list?", "confirmations.domain_block.confirm": "Hide entire domain", "confirmations.domain_block.message": "Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications. Your followers from that domain will be removed.", + "confirmations.logout.confirm": "Log out", + "confirmations.logout.message": "Are you sure you want to log out?", "confirmations.mute.confirm": "Mute", "confirmations.mute.message": "Are you sure you want to mute {name}?", "confirmations.redraft.confirm": "Delete & redraft", @@ -103,6 +110,10 @@ "confirmations.reply.message": "Replying now will overwrite the message you are currently composing. Are you sure you want to proceed?", "confirmations.unfollow.confirm": "Unfollow", "confirmations.unfollow.message": "Are you sure you want to unfollow {name}?", + "directory.federated": "From known fediverse", + "directory.local": "From {domain} only", + "directory.new_arrivals": "New arrivals", + "directory.recently_active": "Recently active", "embed.instructions": "Embed this status on your website by copying the code below.", "embed.preview": "Here is what it will look like:", "emoji_button.activity": "Activity", @@ -249,7 +260,6 @@ "navigation_bar.personal": "Personal", "navigation_bar.pins": "Pinned toots", "navigation_bar.preferences": "Preferences", - "navigation_bar.profile_directory": "Profile directory", "navigation_bar.public_timeline": "Federated timeline", "navigation_bar.security": "Security", "notification.favourite": "{name} favourited your status", @@ -356,6 +366,7 @@ "status.show_more": "Show more", "status.show_more_all": "Show more for all", "status.show_thread": "Show thread", + "status.uncached_media_warning": "Not available", "status.unmute_conversation": "Unmute conversation", "status.unpin": "Unpin from profile", "suggestions.dismiss": "Dismiss suggestion", diff --git a/app/views/directories/index.html.haml b/app/views/directories/index.html.haml index 30daa6bb1a..6bf2ec81ea 100644 --- a/app/views/directories/index.html.haml +++ b/app/views/directories/index.html.haml @@ -49,7 +49,7 @@ - if account.last_status_at.present? %time.time-ago{ datetime: account.last_status_at.iso8601, title: l(account.last_status_at) }= l account.last_status_at - else - = t('invites.expires_in_prompt') + = t('accounts.never_active') %small= t('accounts.last_active') diff --git a/config/locales/en.yml b/config/locales/en.yml index 892d13c726..9c9dbc94b0 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -58,6 +58,7 @@ en: media: Media moved_html: "%{name} has moved to %{new_profile_link}:" network_hidden: This information is not available + never_active: Never nothing_here: There is nothing here! people_followed_by: People whom %{name} follows people_who_follow: People who follow %{name} From 5466b39c78e0c97a9db6377eefa4c3ce44dc1514 Mon Sep 17 00:00:00 2001 From: Hugo Gameiro Date: Mon, 2 Sep 2019 17:12:40 +0100 Subject: [PATCH 13/48] Add SMTP reply_to option (#11718) * Add SMTP_REPLY_TO in .env.production.sample * Set reply_to in SMTP options --- .env.production.sample | 1 + config/environments/production.rb | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.env.production.sample b/.env.production.sample index d66b050509..b322aee1d7 100644 --- a/.env.production.sample +++ b/.env.production.sample @@ -69,6 +69,7 @@ SMTP_PORT=587 SMTP_LOGIN= SMTP_PASSWORD= SMTP_FROM_ADDRESS=notifications@example.com +#SMTP_REPLY_TO= #SMTP_DOMAIN= # defaults to LOCAL_DOMAIN #SMTP_DELIVERY_METHOD=smtp # delivery method can also be sendmail #SMTP_AUTH_METHOD=plain diff --git a/config/environments/production.rb b/config/environments/production.rb index d1b5a8df54..29d6194dda 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -83,7 +83,10 @@ Rails.application.configure do config.action_mailer.perform_caching = false # E-mails - config.action_mailer.default_options = { from: ENV.fetch('SMTP_FROM_ADDRESS', 'notifications@localhost') } + config.action_mailer.default_options = { + from: ENV.fetch('SMTP_FROM_ADDRESS', 'notifications@localhost'), + reply_to: ENV['SMTP_REPLY_TO'] + } config.action_mailer.smtp_settings = { :port => ENV['SMTP_PORT'], From 34adc8784a3f165a4bd5719a067093f703f499e9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 3 Sep 2019 04:56:40 +0200 Subject: [PATCH 14/48] Fix uncached media in web UI not being clickable (#11745) --- app/javascript/mastodon/components/media_gallery.js | 4 ++-- app/javascript/styles/mastodon/components.scss | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js index 55e0e77d62..e8dd79af9e 100644 --- a/app/javascript/mastodon/components/media_gallery.js +++ b/app/javascript/mastodon/components/media_gallery.js @@ -159,7 +159,7 @@ class Item extends React.PureComponent { if (attachment.get('type') === 'unknown') { return ( @@ -342,7 +342,7 @@ class MediaGallery extends React.PureComponent { return (
-
+
{spoilerButton}
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 0b569bb8f6..fde5e4c958 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -3449,6 +3449,10 @@ a.status-card.compact:hover { height: auto; } + &--click-thru { + pointer-events: none; + } + &--hidden { display: none; } @@ -3479,8 +3483,6 @@ a.status-card.compact:hover { } &:disabled { - cursor: not-allowed; - .spoiler-button__overlay__label { background: rgba($base-overlay-background, 0.5); } From 3221f998dd1fcfc2111178637fbb1f712d9e8388 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 3 Sep 2019 04:56:54 +0200 Subject: [PATCH 15/48] Change OpenGraph description on sign-up page to reflect invite (#11744) --- app/helpers/instance_helper.rb | 12 ++++++++++++ app/views/auth/registrations/new.html.haml | 2 +- app/views/shared/_og.html.haml | 4 ++-- config/locales/en.yml | 4 ++++ 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/helpers/instance_helper.rb b/app/helpers/instance_helper.rb index dd0b25f3ef..daacb535b6 100644 --- a/app/helpers/instance_helper.rb +++ b/app/helpers/instance_helper.rb @@ -8,4 +8,16 @@ module InstanceHelper def site_hostname @site_hostname ||= Addressable::URI.parse("//#{Rails.configuration.x.local_domain}").display_uri.host end + + def description_for_sign_up + prefix = begin + if @invite.present? + I18n.t('auth.description.prefix_invited_by_user', name: @invite.user.account.username) + else + I18n.t('auth.description.prefix_sign_up') + end + end + + safe_join([prefix, I18n.t('auth.description.suffix')], ' ') + end end diff --git a/app/views/auth/registrations/new.html.haml b/app/views/auth/registrations/new.html.haml index 83384d7379..e807c8d867 100644 --- a/app/views/auth/registrations/new.html.haml +++ b/app/views/auth/registrations/new.html.haml @@ -2,7 +2,7 @@ = t('auth.register') - content_for :header_tags do - = render partial: 'shared/og' + = render partial: 'shared/og', locals: { description: description_for_sign_up } = simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| = render 'shared/error_messages', object: resource diff --git a/app/views/shared/_og.html.haml b/app/views/shared/_og.html.haml index 67238fc8bf..576f47a676 100644 --- a/app/views/shared/_og.html.haml +++ b/app/views/shared/_og.html.haml @@ -1,5 +1,5 @@ -- thumbnail = @instance_presenter.thumbnail -- description = strip_tags(@instance_presenter.site_short_description.presence || @instance_presenter.site_description.presence || t('about.about_mastodon_html')) +- thumbnail = @instance_presenter.thumbnail +- description ||= strip_tags(@instance_presenter.site_short_description.presence || @instance_presenter.site_description.presence || t('about.about_mastodon_html')) %meta{ name: 'description', content: description }/ diff --git a/config/locales/en.yml b/config/locales/en.yml index 9c9dbc94b0..ad29e0a748 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -569,6 +569,10 @@ en: checkbox_agreement_without_rules_html: I agree to the terms of service delete_account: Delete account delete_account_html: If you wish to delete your account, you can proceed here. You will be asked for confirmation. + description: + prefix_invited_by_user: "@%{name} invites you to join this server of Mastodon!" + prefix_sign_up: Sign up on Mastodon today! + suffix: With an account, you will be able to follow people, post updates and exchange messages with users from any Mastodon server and more! didnt_get_confirmation: Didn't receive confirmation instructions? forgot_password: Forgot your password? invalid_reset_password_token: Password reset token is invalid or expired. Please request a new one. From 16c1abdb2d493012f0f0fd5eb36324d2f0cd91d9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 3 Sep 2019 04:57:07 +0200 Subject: [PATCH 16/48] Fix user preference to show trends not working on public pages (#11740) Fix #11738 --- app/views/application/_sidebar.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/application/_sidebar.html.haml b/app/views/application/_sidebar.html.haml index 90c8f9dd1a..33e7c96fe7 100644 --- a/app/views/application/_sidebar.html.haml +++ b/app/views/application/_sidebar.html.haml @@ -5,7 +5,7 @@ .hero-widget__text %p= @instance_presenter.site_short_description.html_safe.presence || @instance_presenter.site_description.html_safe.presence || t('about.generic_description', domain: site_hostname) -- if Setting.trends +- if Setting.trends && !(user_signed_in? && !current_user.setting_trends) - trends = TrendingTags.get(3) - unless trends.empty? From 92a6fa6c90fda809554ae2cac10036202723f5c9 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 3 Sep 2019 05:57:30 +0200 Subject: [PATCH 17/48] Fix error in user warning template (#11741) --- app/views/user_mailer/warning.html.haml | 4 ++-- app/views/user_mailer/warning.text.erb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/user_mailer/warning.html.haml b/app/views/user_mailer/warning.html.haml index 1105f2062f..89dc2a75db 100644 --- a/app/views/user_mailer/warning.html.haml +++ b/app/views/user_mailer/warning.html.haml @@ -42,11 +42,11 @@ - unless @warning.text.blank? = Formatter.instance.linkify(@warning.text) - - unless @statuses&.empty? + - if !@statuses.nil? && !@statuses.empty? %p %strong= t('user_mailer.warning.statuses') -- unless @statuses&.empty? +- if !@statuses.nil? && !@statuses.empty? - @statuses.each_with_index do |status, i| = render 'notification_mailer/status', status: status, i: i + 1, highlighted: true diff --git a/app/views/user_mailer/warning.text.erb b/app/views/user_mailer/warning.text.erb index 45ad3b64d4..bb6610c79b 100644 --- a/app/views/user_mailer/warning.text.erb +++ b/app/views/user_mailer/warning.text.erb @@ -7,7 +7,7 @@ <% end %> <%= @warning.text %> -<% unless @statuses&.empty? %> +<% if !@statuses.nil? && !@statuses.empty? %> <%= t('user_mailer.warning.statuses') %> <% @statuses.each do |status| %> From d19d86fe2b26fb00577d600234c32d726fb199a4 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 3 Sep 2019 06:35:44 +0200 Subject: [PATCH 18/48] Change hashtag component in web UI to show numbers for 2 last days (#11742) To deal with the midnight problem --- app/javascript/mastodon/components/hashtag.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/components/hashtag.js b/app/javascript/mastodon/components/hashtag.js index f091d7893e..2456eac9e6 100644 --- a/app/javascript/mastodon/components/hashtag.js +++ b/app/javascript/mastodon/components/hashtag.js @@ -12,11 +12,11 @@ const Hashtag = ({ hashtag }) => ( #{hashtag.get('name')} - {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']))} }} /> + {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']) + hashtag.getIn(['history', 1, 'accounts']))} }} />
- {shortNumberFormat(hashtag.getIn(['history', 0, 'uses']))} + {shortNumberFormat(hashtag.getIn(['history', 0, 'uses']) + hashtag.getIn(['history', 1, 'uses']))}
From ec1dd865fb09de2505e24001bdb5f3ac82f34a43 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 3 Sep 2019 07:59:52 +0200 Subject: [PATCH 19/48] Fix error in admin UI for hashtag usage breakdown (#11743) --- app/views/admin/tags/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/tags/show.html.haml b/app/views/admin/tags/show.html.haml index f9677874a7..d54a43c1e8 100644 --- a/app/views/admin/tags/show.html.haml +++ b/app/views/admin/tags/show.html.haml @@ -38,7 +38,7 @@ .table-wrapper %table.table %tbody - - total = @usage_by_domain.sum(&:statuses_count).to_f + - total = @usage_by_domain.sum(&:last).to_f - @usage_by_domain.each do |(domain, count)| %tr From 692c5b439ae8659e459da692cf9e6b8e6f29d2a1 Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 3 Sep 2019 22:52:32 +0200 Subject: [PATCH 20/48] Fix ActivityPub context not being dynamically computed (#11746) * Fix contexts not being dynamically included Fixes #11649 * Refactor Note context in serializer * Refactor Actor serializer --- app/lib/activitypub/adapter.rb | 13 +++++++------ app/lib/activitypub/serializer.rb | 8 ++++++++ .../activitypub/actor_serializer.rb | 4 +++- .../activitypub/note_serializer.rb | 7 +++++-- .../initializers/active_model_serializers.rb | 19 ------------------- spec/lib/activitypub/activity/update_spec.rb | 2 +- 6 files changed, 24 insertions(+), 29 deletions(-) diff --git a/app/lib/activitypub/adapter.rb b/app/lib/activitypub/adapter.rb index 1c58be8c0f..cb2ac72d45 100644 --- a/app/lib/activitypub/adapter.rb +++ b/app/lib/activitypub/adapter.rb @@ -32,22 +32,23 @@ class ActivityPub::Adapter < ActiveModelSerializers::Adapter::Base end def serializable_hash(options = nil) + named_contexts = {} + context_extensions = {} options = serialization_options(options) - serialized_hash = serializer.serializable_hash(options) + serialized_hash = serializer.serializable_hash(options.merge(named_contexts: named_contexts, context_extensions: context_extensions)) serialized_hash = serialized_hash.select { |k, _| options[:fields].include?(k) } if options[:fields] serialized_hash = self.class.transform_key_casing!(serialized_hash, instance_options) - { '@context' => serialized_context }.merge(serialized_hash) + { '@context' => serialized_context(named_contexts, context_extensions) }.merge(serialized_hash) end private - def serialized_context + def serialized_context(named_contexts_map, context_extensions_map) context_array = [] - serializer_options = serializer.send(:instance_options) || {} - named_contexts = [:activitystreams] + serializer._named_contexts.keys + serializer_options.fetch(:named_contexts, {}).keys - context_extensions = serializer._context_extensions.keys + serializer_options.fetch(:context_extensions, {}).keys + named_contexts = [:activitystreams] + named_contexts_map.keys + context_extensions = context_extensions_map.keys named_contexts.each do |key| context_array << NAMED_CONTEXT_MAP[key] diff --git a/app/lib/activitypub/serializer.rb b/app/lib/activitypub/serializer.rb index 07bd8c4946..1fdc793104 100644 --- a/app/lib/activitypub/serializer.rb +++ b/app/lib/activitypub/serializer.rb @@ -27,4 +27,12 @@ class ActivityPub::Serializer < ActiveModel::Serializer _context_extensions[extension_name] = true end end + + def serializable_hash(adapter_options = nil, options = {}, adapter_instance = self.class.serialization_adapter_instance) + unless adapter_options&.fetch(:named_contexts, nil).nil? + adapter_options[:named_contexts].merge!(_named_contexts) + adapter_options[:context_extensions].merge!(_context_extensions) + end + super(adapter_options, options, adapter_instance) + end end diff --git a/app/serializers/activitypub/actor_serializer.rb b/app/serializers/activitypub/actor_serializer.rb index 222e17c994..17df85de31 100644 --- a/app/serializers/activitypub/actor_serializer.rb +++ b/app/serializers/activitypub/actor_serializer.rb @@ -6,7 +6,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer context :security context_extensions :manually_approves_followers, :featured, :also_known_as, - :moved_to, :property_value, :hashtag, :emoji, :identity_proof, + :moved_to, :property_value, :identity_proof, :discoverable attributes :id, :type, :following, :followers, @@ -138,6 +138,8 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer end class TagSerializer < ActivityPub::Serializer + context_extensions :hashtag + include RoutingHelper attributes :type, :href, :name diff --git a/app/serializers/activitypub/note_serializer.rb b/app/serializers/activitypub/note_serializer.rb index 7592e0b1a8..364d3eda59 100644 --- a/app/serializers/activitypub/note_serializer.rb +++ b/app/serializers/activitypub/note_serializer.rb @@ -1,8 +1,7 @@ # frozen_string_literal: true class ActivityPub::NoteSerializer < ActivityPub::Serializer - context_extensions :atom_uri, :conversation, :sensitive, - :hashtag, :emoji, :focal_point, :blurhash + context_extensions :atom_uri, :conversation, :sensitive attributes :id, :type, :summary, :in_reply_to, :published, :url, @@ -151,6 +150,8 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer end class MediaAttachmentSerializer < ActivityPub::Serializer + context_extensions :blurhash, :focal_point + include RoutingHelper attributes :type, :media_type, :url, :name, :blurhash @@ -198,6 +199,8 @@ class ActivityPub::NoteSerializer < ActivityPub::Serializer end class TagSerializer < ActivityPub::Serializer + context_extensions :hashtag + include RoutingHelper attributes :type, :href, :name diff --git a/config/initializers/active_model_serializers.rb b/config/initializers/active_model_serializers.rb index 329a5fb2c3..0e69e1d96c 100644 --- a/config/initializers/active_model_serializers.rb +++ b/config/initializers/active_model_serializers.rb @@ -3,22 +3,3 @@ ActiveModelSerializers.config.tap do |config| end ActiveSupport::Notifications.unsubscribe(ActiveModelSerializers::Logging::RENDER_EVENT) - -class ActiveModel::Serializer::Reflection - # We monkey-patch this method so that when we include associations in a serializer, - # the nested serializers can send information about used contexts upwards back to - # the root. We do this via instance_options because the nesting can be dynamic. - def build_association(parent_serializer, parent_serializer_options, include_slice = {}) - serializer = options[:serializer] - - parent_serializer_options.merge!(named_contexts: serializer._named_contexts, context_extensions: serializer._context_extensions) if serializer.respond_to?(:_named_contexts) - - association_options = { - parent_serializer: parent_serializer, - parent_serializer_options: parent_serializer_options, - include_slice: include_slice, - } - - ActiveModel::Serializer::Association.new(self, association_options) - end -end diff --git a/spec/lib/activitypub/activity/update_spec.rb b/spec/lib/activitypub/activity/update_spec.rb index fbfc585cf9..42da298606 100644 --- a/spec/lib/activitypub/activity/update_spec.rb +++ b/spec/lib/activitypub/activity/update_spec.rb @@ -19,7 +19,7 @@ RSpec.describe ActivityPub::Activity::Update do end let(:actor_json) do - ActiveModelSerializers::SerializableResource.new(modified_sender, serializer: ActivityPub::ActorSerializer, key_transform: :camel_lower).as_json + ActiveModelSerializers::SerializableResource.new(modified_sender, serializer: ActivityPub::ActorSerializer, adapter: ActivityPub::Adapter).as_json end let(:json) do From c1e238a77b1f92a031fcb644c2d37809b96e9027 Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 3 Sep 2019 22:53:27 +0200 Subject: [PATCH 21/48] Fix admin interface showing superfluous reject media/reports on suspended blocks (#11749) * Fix admin interface showing superfluous reject media/reports on suspended domains * Fix reject media/reports checkboxes being visible when editing domain block of suspend severity --- app/javascript/packs/admin.js | 10 +++++++++- app/views/admin/instances/index.html.haml | 19 ++++++++++--------- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/app/javascript/packs/admin.js b/app/javascript/packs/admin.js index f0c0ee0b74..42c747d2ef 100644 --- a/app/javascript/packs/admin.js +++ b/app/javascript/packs/admin.js @@ -1,4 +1,5 @@ import { delegate } from 'rails-ujs'; +import ready from '../mastodon/ready'; const batchCheckboxClassName = '.batch-checkbox input[type="checkbox"]'; @@ -29,7 +30,7 @@ delegate(document, '.media-spoiler-hide-button', 'click', () => { }); }); -delegate(document, '#domain_block_severity', 'change', ({ target }) => { +const onDomainBlockSeverityChange = (target) => { const rejectMediaDiv = document.querySelector('.input.with_label.domain_block_reject_media'); const rejectReportsDiv = document.querySelector('.input.with_label.domain_block_reject_reports'); @@ -40,4 +41,11 @@ delegate(document, '#domain_block_severity', 'change', ({ target }) => { if (rejectReportsDiv) { rejectReportsDiv.style.display = (target.value === 'suspend') ? 'none' : 'block'; } +}; + +delegate(document, '#domain_block_severity', 'change', ({ target }) => onDomainBlockSeverityChange(target)); + +ready(() => { + const input = document.getElementById('domain_block_severity'); + if (input) onDomainBlockSeverityChange(input); }); diff --git a/app/views/admin/instances/index.html.haml b/app/views/admin/instances/index.html.haml index 982dc50354..1d85aa75e0 100644 --- a/app/views/admin/instances/index.html.haml +++ b/app/views/admin/instances/index.html.haml @@ -44,15 +44,16 @@ - if !instance.domain_block.noop? = t("admin.domain_blocks.severity.#{instance.domain_block.severity}") - first_item = false - - if instance.domain_block.reject_media? - - unless first_item - • - = t('admin.domain_blocks.rejecting_media') - - first_item = false - - if instance.domain_block.reject_reports? - - unless first_item - • - = t('admin.domain_blocks.rejecting_reports') + - unless instance.domain_block.suspend? + - if instance.domain_block.reject_media? + - unless first_item + • + = t('admin.domain_blocks.rejecting_media') + - first_item = false + - if instance.domain_block.reject_reports? + - unless first_item + • + = t('admin.domain_blocks.rejecting_reports') - elsif whitelist_mode? = t('admin.accounts.whitelisted') - else From 43f56f12917f154fbb70cbc305daba9e2fd364ed Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 4 Sep 2019 04:13:54 +0200 Subject: [PATCH 22/48] Change account deletion page to have better explanations (#11753) Fix deletion of unconfirmed account not freeing up the username Add prefill of logged-in user's email in the reconfirmation form --- .../auth/confirmations_controller.rb | 23 ++++++++++++++++++ app/javascript/styles/mastodon/forms.scss | 9 +++++++ app/services/suspend_account_service.rb | 1 + app/views/auth/setup/show.html.haml | 5 +--- app/views/auth/shared/_links.html.haml | 22 ++++++++++------- app/views/settings/deletes/show.html.haml | 24 +++++++++++++------ config/locales/en.yml | 16 +++++++++---- 7 files changed, 77 insertions(+), 23 deletions(-) diff --git a/app/controllers/auth/confirmations_controller.rb b/app/controllers/auth/confirmations_controller.rb index 0d7c6e7c2d..3e419eb96f 100644 --- a/app/controllers/auth/confirmations_controller.rb +++ b/app/controllers/auth/confirmations_controller.rb @@ -4,15 +4,38 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController layout 'auth' before_action :set_body_classes + before_action :require_unconfirmed! skip_before_action :require_functional! + def new + super + + resource.email = current_user.unconfirmed_email || current_user.email if user_signed_in? + end + private + def require_unconfirmed! + redirect_to edit_user_registration_path if user_signed_in? && current_user.confirmed? && current_user.unconfirmed_email.blank? + end + def set_body_classes @body_classes = 'lighter' end + def after_resending_confirmation_instructions_path_for(_resource_name) + if user_signed_in? + if user.confirmed? && user.approved? + edit_user_registration_path + else + auth_setup_path + end + else + new_user_session_path + end + end + def after_confirmation_path_for(_resource_name, user) if user.created_by_application && truthy_param?(:redirect_to_app) user.created_by_application.redirect_uri diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index ac99124ea8..16352340bf 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -112,6 +112,15 @@ code { padding: 0.2em 0.4em; background: darken($ui-base-color, 12%); } + + li { + list-style: disc; + margin-left: 18px; + } + } + + ul.hint { + margin-bottom: 15px; } span.hint { diff --git a/app/services/suspend_account_service.rb b/app/services/suspend_account_service.rb index 902af376c8..85da7e9210 100644 --- a/app/services/suspend_account_service.rb +++ b/app/services/suspend_account_service.rb @@ -61,6 +61,7 @@ class SuspendAccountService < BaseService return if !@account.local? || @account.user.nil? if @options[:including_user] + @options[:destroy] = true if !@account.user_confirmed? || @account.user_pending? @account.user.destroy else @account.user.disable! diff --git a/app/views/auth/setup/show.html.haml b/app/views/auth/setup/show.html.haml index 8bb44ca7f7..c14fed56f8 100644 --- a/app/views/auth/setup/show.html.haml +++ b/app/views/auth/setup/show.html.haml @@ -17,7 +17,4 @@ .simple_form %p.hint= t('auth.setup.email_settings_hint_html', email: content_tag(:strong, @user.email)) -.form-footer - %ul.no-list - %li= link_to t('settings.account_settings'), edit_user_registration_path - %li= link_to t('auth.logout'), destroy_user_session_path, data: { method: :delete } +.form-footer= render 'auth/shared/links' diff --git a/app/views/auth/shared/_links.html.haml b/app/views/auth/shared/_links.html.haml index 3c68ccd222..e6c3f7cca6 100644 --- a/app/views/auth/shared/_links.html.haml +++ b/app/views/auth/shared/_links.html.haml @@ -1,12 +1,18 @@ %ul.no-list - - if controller_name != 'sessions' - %li= link_to t('auth.login'), new_session_path(resource_name) + - if user_signed_in? + %li= link_to t('settings.account_settings'), edit_user_registration_path + - else + - if controller_name != 'sessions' + %li= link_to t('auth.login'), new_user_session_path - - if devise_mapping.registerable? && controller_name != 'registrations' - %li= link_to t('auth.register'), available_sign_up_path + - if controller_name != 'registrations' + %li= link_to t('auth.register'), available_sign_up_path - - if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' - %li= link_to t('auth.forgot_password'), new_password_path(resource_name) + - if controller_name != 'passwords' && controller_name != 'registrations' + %li= link_to t('auth.forgot_password'), new_user_password_path - - if devise_mapping.confirmable? && controller_name != 'confirmations' - %li= link_to t('auth.didnt_get_confirmation'), new_confirmation_path(resource_name) + - if controller_name != 'confirmations' + %li= link_to t('auth.didnt_get_confirmation'), new_user_confirmation_path + + - if user_signed_in? && controller_name != 'setup' + %li= link_to t('auth.logout'), destroy_user_session_path, data: { method: :delete } diff --git a/app/views/settings/deletes/show.html.haml b/app/views/settings/deletes/show.html.haml index b246f83a16..6e2ff31c57 100644 --- a/app/views/settings/deletes/show.html.haml +++ b/app/views/settings/deletes/show.html.haml @@ -2,15 +2,25 @@ = t('settings.delete') = simple_form_for @confirmation, url: settings_delete_path, method: :delete do |f| - .warning - %strong - = fa_icon('warning') - = t('deletes.warning_title') - = t('deletes.warning_html') + %p.hint= t('deletes.warning.before') - %p.hint= t('deletes.description_html') + %ul.hint + - if current_user.confirmed? && current_user.approved? + %li.warning-hint= t('deletes.warning.irreversible') + %li.warning-hint= t('deletes.warning.username_unavailable') + %li.warning-hint= t('deletes.warning.data_removal') + %li.warning-hint= t('deletes.warning.caches') + - else + %li.positive-hint= t('deletes.warning.email_change_html', path: edit_user_registration_path) + %li.positive-hint= t('deletes.warning.email_reconfirmation_html', path: new_user_confirmation_path) + %li.positive-hint= t('deletes.warning.email_contact_html', email: Setting.site_contact_email) + %li.positive-hint= t('deletes.warning.username_available') - = f.input :password, placeholder: t('simple_form.labels.defaults.current_password'), input_html: { 'aria-label' => t('simple_form.labels.defaults.current_password'), :autocomplete => 'off' }, hint: t('deletes.confirm_password') + %p.hint= t('deletes.warning.more_details_html', terms_path: terms_path) + + %hr.spacer/ + + = f.input :password, wrapper: :with_block_label, input_html: { :autocomplete => 'off' }, hint: t('deletes.confirm_password') .actions = f.button :button, t('deletes.proceed'), type: :submit, class: 'negative' diff --git a/config/locales/en.yml b/config/locales/en.yml index ad29e0a748..687f5f2a04 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -626,13 +626,21 @@ en: x_months: "%{count}mo" x_seconds: "%{count}s" deletes: - bad_password_msg: Nice try, hackers! Incorrect password + bad_password_msg: The password you entered was incorrect confirm_password: Enter your current password to verify your identity - description_html: This will permanently, irreversibly remove content from your account and deactivate it. Your username will remain reserved to prevent future impersonations. proceed: Delete account success_msg: Your account was successfully deleted - warning_html: Only deletion of content from this particular server is guaranteed. Content that has been widely shared is likely to leave traces. Offline servers and servers that have unsubscribed from your updates will not update their databases. - warning_title: Disseminated content availability + warning: + before: 'Before proceeding, please read these notes carefully:' + caches: Content that has been cached by other servers may persist + data_removal: Your posts and other data will be permanently removed + email_change_html: You can change your e-mail address without deleting your account + email_contact_html: If it still doesn't arrive, you can e-mail %{email} for help + email_reconfirmation_html: If you are not receiving the confirmation e-mail, you can request it again + irreversible: You will not be able to restore or reactivate your account + more_details_html: For more details, see the privacy policy. + username_available: Your username will become available again + username_unavailable: Your username will remain unavailable directories: directory: Profile directory explanation: Discover users based on their interests From 1a00bd9244ee8555d7401f4f0ee01ec381e96c1c Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 4 Sep 2019 04:14:13 +0200 Subject: [PATCH 23/48] Fix wrong pluralization in hashtag component in web UI (#11754) --- app/javascript/mastodon/components/hashtag.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/mastodon/components/hashtag.js b/app/javascript/mastodon/components/hashtag.js index 2456eac9e6..68b9be72d3 100644 --- a/app/javascript/mastodon/components/hashtag.js +++ b/app/javascript/mastodon/components/hashtag.js @@ -12,7 +12,7 @@ const Hashtag = ({ hashtag }) => ( #{hashtag.get('name')} - {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']) + hashtag.getIn(['history', 1, 'accounts']))} }} /> + {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']) + hashtag.getIn(['history', 1, 'accounts']))} }} />
From a6a63358c3fd81b9104aa0a51133cd065eea4a84 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 4 Sep 2019 10:10:18 +0200 Subject: [PATCH 24/48] Fix wrong sum of usage in hashtag component in web UI (#11755) 1 + 1 = 11 --- app/javascript/mastodon/components/hashtag.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/mastodon/components/hashtag.js b/app/javascript/mastodon/components/hashtag.js index 68b9be72d3..62d6132626 100644 --- a/app/javascript/mastodon/components/hashtag.js +++ b/app/javascript/mastodon/components/hashtag.js @@ -12,11 +12,11 @@ const Hashtag = ({ hashtag }) => ( #{hashtag.get('name')} - {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']) + hashtag.getIn(['history', 1, 'accounts']))} }} /> + {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']) * 1 + hashtag.getIn(['history', 1, 'accounts']) * 1)} }} />
- {shortNumberFormat(hashtag.getIn(['history', 0, 'uses']) + hashtag.getIn(['history', 1, 'uses']))} + {shortNumberFormat(hashtag.getIn(['history', 0, 'uses']) * 1 + hashtag.getIn(['history', 1, 'uses']) * 1)}
From 15d6a10c02c6e98a937a84772a37644d7e865743 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2019 01:42:35 +0900 Subject: [PATCH 25/48] Bump webmock from 3.6.2 to 3.7.1 (#11734) Bumps [webmock](https://github.com/bblimke/webmock) from 3.6.2 to 3.7.1. - [Release notes](https://github.com/bblimke/webmock/releases) - [Changelog](https://github.com/bblimke/webmock/blob/master/CHANGELOG.md) - [Commits](https://github.com/bblimke/webmock/compare/v3.6.2...v3.7.1) Signed-off-by: dependabot-preview[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index e40dea54fe..9dcd06ea37 100644 --- a/Gemfile +++ b/Gemfile @@ -118,7 +118,7 @@ group :test do gem 'rails-controller-testing', '~> 1.0' gem 'rspec-sidekiq', '~> 3.0' gem 'simplecov', '~> 0.17', require: false - gem 'webmock', '~> 3.6' + gem 'webmock', '~> 3.7' gem 'parallel_tests', '~> 2.29' end diff --git a/Gemfile.lock b/Gemfile.lock index be310c24a4..872ae3bc4c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -644,7 +644,7 @@ GEM uniform_notifier (1.12.1) warden (1.2.8) rack (>= 2.0.6) - webmock (3.6.2) + webmock (3.7.1) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) @@ -784,7 +784,7 @@ DEPENDENCIES tty-prompt (~> 0.19) twitter-text (~> 1.14) tzinfo-data (~> 1.2019) - webmock (~> 3.6) + webmock (~> 3.7) webpacker (~> 4.0) webpush From e9dbb955a887f5e94b5b7320bb378d09e88870d6 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2019 01:44:01 +0900 Subject: [PATCH 26/48] Bump faker from 2.1.2 to 2.2.1 (#11733) Bumps [faker](https://github.com/faker-ruby/faker) from 2.1.2 to 2.2.1. - [Release notes](https://github.com/faker-ruby/faker/releases) - [Changelog](https://github.com/faker-ruby/faker/blob/master/CHANGELOG.md) - [Commits](https://github.com/faker-ruby/faker/compare/v2.1.2...v2.2.1) Signed-off-by: dependabot-preview[bot] --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 9dcd06ea37..72a444876b 100644 --- a/Gemfile +++ b/Gemfile @@ -113,7 +113,7 @@ end group :test do gem 'capybara', '~> 3.28' gem 'climate_control', '~> 0.2' - gem 'faker', '~> 2.1' + gem 'faker', '~> 2.2' gem 'microformats', '~> 4.1' gem 'rails-controller-testing', '~> 1.0' gem 'rspec-sidekiq', '~> 3.0' diff --git a/Gemfile.lock b/Gemfile.lock index 872ae3bc4c..54ea059eaf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -231,7 +231,7 @@ GEM tzinfo excon (0.62.0) fabrication (2.20.2) - faker (2.1.2) + faker (2.2.1) i18n (>= 0.8) faraday (0.15.0) multipart-post (>= 1.2, < 3) @@ -698,7 +698,7 @@ DEPENDENCIES doorkeeper (~> 5.1) dotenv-rails (~> 2.7) fabrication (~> 2.20) - faker (~> 2.1) + faker (~> 2.2) fast_blank (~> 1.0) fastimage fog-core (<= 2.1.0) From beba6824e1a15b4c8323150fef11d30c0d2b9d0a Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2019 01:45:20 +0900 Subject: [PATCH 27/48] Bump bootsnap from 1.4.4 to 1.4.5 (#11730) Bumps [bootsnap](https://github.com/Shopify/bootsnap) from 1.4.4 to 1.4.5. - [Release notes](https://github.com/Shopify/bootsnap/releases) - [Changelog](https://github.com/Shopify/bootsnap/blob/master/CHANGELOG.md) - [Commits](https://github.com/Shopify/bootsnap/compare/v1.4.4...v1.4.5) Signed-off-by: dependabot-preview[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 54ea059eaf..8fee0532df 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -122,7 +122,7 @@ GEM debug_inspector (>= 0.0.1) blurhash (0.1.3) ffi (~> 1.10.0) - bootsnap (1.4.4) + bootsnap (1.4.5) msgpack (~> 1.0) brakeman (4.6.1) browser (2.6.1) @@ -369,7 +369,7 @@ GEM mini_mime (1.0.2) mini_portile2 (2.4.0) minitest (5.11.3) - msgpack (1.2.10) + msgpack (1.3.1) multi_json (1.13.1) multipart-post (2.0.0) necromancer (0.5.0) From 1b3c2598fa8090835f2ddfb9d2b0917c7752fcce Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2019 01:45:44 +0900 Subject: [PATCH 28/48] Bump rubocop-rails from 2.3.1 to 2.3.2 (#11728) Bumps [rubocop-rails](https://github.com/rubocop-hq/rubocop-rails) from 2.3.1 to 2.3.2. - [Release notes](https://github.com/rubocop-hq/rubocop-rails/releases) - [Changelog](https://github.com/rubocop-hq/rubocop-rails/blob/master/CHANGELOG.md) - [Commits](https://github.com/rubocop-hq/rubocop-rails/compare/v2.3.1...v2.3.2) Signed-off-by: dependabot-preview[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8fee0532df..475a27fb2f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -416,7 +416,7 @@ GEM parallel (1.17.0) parallel_tests (2.29.2) parallel - parser (2.6.3.0) + parser (2.6.4.0) ast (~> 2.4.0) parslet (1.8.2) pastel (0.7.2) @@ -554,7 +554,7 @@ GEM rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) unicode-display_width (>= 1.4.0, < 1.7) - rubocop-rails (2.3.1) + rubocop-rails (2.3.2) rack (>= 1.1) rubocop (>= 0.72.0) ruby-progressbar (1.10.1) From 80f86f290f7d1aea4755fb521ef0cf30c02b82a2 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2019 01:46:37 +0900 Subject: [PATCH 29/48] Bump aws-sdk-s3 from 1.46.0 to 1.48.0 (#11729) Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.46.0 to 1.48.0. - [Release notes](https://github.com/aws/aws-sdk-ruby/releases) - [Changelog](https://github.com/aws/aws-sdk-ruby/blob/master/gems/aws-sdk-s3/CHANGELOG.md) - [Commits](https://github.com/aws/aws-sdk-ruby/compare/v1.46.0...v1.48.0) Signed-off-by: dependabot-preview[bot] --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 72a444876b..932b8a1adf 100644 --- a/Gemfile +++ b/Gemfile @@ -15,7 +15,7 @@ gem 'makara', '~> 0.4' gem 'pghero', '~> 2.3' gem 'dotenv-rails', '~> 2.7' -gem 'aws-sdk-s3', '~> 1.46', require: false +gem 'aws-sdk-s3', '~> 1.48', require: false gem 'fog-core', '<= 2.1.0' gem 'fog-openstack', '~> 0.3', require: false gem 'paperclip', '~> 6.0' diff --git a/Gemfile.lock b/Gemfile.lock index 475a27fb2f..63676bd1bd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -97,8 +97,8 @@ GEM av (0.9.0) cocaine (~> 0.5.3) aws-eventstream (1.0.3) - aws-partitions (1.193.0) - aws-sdk-core (3.61.1) + aws-partitions (1.207.0) + aws-sdk-core (3.65.1) aws-eventstream (~> 1.0, >= 1.0.2) aws-partitions (~> 1.0) aws-sigv4 (~> 1.1) @@ -106,7 +106,7 @@ GEM aws-sdk-kms (1.24.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.46.0) + aws-sdk-s3 (1.48.0) aws-sdk-core (~> 3, >= 3.61.1) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.1) @@ -670,7 +670,7 @@ DEPENDENCIES active_record_query_trace (~> 1.6) addressable (~> 2.6) annotate (~> 2.7) - aws-sdk-s3 (~> 1.46) + aws-sdk-s3 (~> 1.48) better_errors (~> 2.5) binding_of_caller (~> 0.7) blurhash (~> 0.1) From bdca8da8ebb133f9f2a01cd4881a2fc3f6852274 Mon Sep 17 00:00:00 2001 From: Yamagishi Kazutoshi Date: Thu, 5 Sep 2019 03:44:08 +0900 Subject: [PATCH 30/48] Add PERSISTENT_TIMEOUT option (#11756) Add environment variable to so `persistent_timeout` option of puma can be changed. --- config/puma.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/puma.rb b/config/puma.rb index 6a96867d54..224be79036 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -1,3 +1,5 @@ +persistent_timeout ENV.fetch('PERSISTENT_TIMEOUT') { 20 }.to_i + threads_count = ENV.fetch('MAX_THREADS') { 5 }.to_i threads threads_count, threads_count From e974d4923fabd887416609bc6c8ca81ce81d0ff2 Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Thu, 5 Sep 2019 01:00:49 +0430 Subject: [PATCH 31/48] Exclude URLs from text analysis (#11759) By the added regex, URLs, including the one without http or even www like mysite.com will be removed from the toot's body so only the real text of the toot will be analyzed for RTL detection --- app/javascript/mastodon/rtl.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/mastodon/rtl.js b/app/javascript/mastodon/rtl.js index 00870a15d6..89bed6de88 100644 --- a/app/javascript/mastodon/rtl.js +++ b/app/javascript/mastodon/rtl.js @@ -20,6 +20,7 @@ export function isRtl(text) { text = text.replace(/(?:^|[^\/\w])@([a-z0-9_]+(@[a-z0-9\.\-]+)?)/ig, ''); text = text.replace(/(?:^|[^\/\w])#([\S]+)/ig, ''); text = text.replace(/\s+/g, ''); + text = text.replace(/(\w\S+\.\w{2,}\S*)/g, ''); const matches = text.match(rtlChars); From c46dcf77c6f3a081637bc4bbbfb2b457acee763c Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2019 12:04:45 +0900 Subject: [PATCH 32/48] Bump capistrano from 3.11.0 to 3.11.1 (#11731) * Bump capistrano from 3.11.0 to 3.11.1 Bumps [capistrano](https://github.com/capistrano/capistrano) from 3.11.0 to 3.11.1. - [Release notes](https://github.com/capistrano/capistrano/releases) - [Changelog](https://github.com/capistrano/capistrano/blob/master/CHANGELOG.md) - [Commits](https://github.com/capistrano/capistrano/compare/v3.11.0...v3.11.1) Signed-off-by: dependabot-preview[bot] * 3.11.1 --- Gemfile.lock | 12 ++++++------ config/deploy.rb | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 63676bd1bd..f601e7192a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -85,7 +85,7 @@ GEM tzinfo (~> 1.1) addressable (2.6.0) public_suffix (>= 2.0.2, < 4.0) - airbrussh (1.3.0) + airbrussh (1.3.3) sshkit (>= 1.6.1, != 1.7.0) annotate (2.7.5) activerecord (>= 3.2, < 7.0) @@ -134,7 +134,7 @@ GEM bundler (>= 1.2.0, < 3) thor (~> 0.18) byebug (11.0.0) - capistrano (3.11.0) + capistrano (3.11.1) airbrussh (>= 1.0.0) i18n rake (>= 10.0.0) @@ -374,9 +374,9 @@ GEM multipart-post (2.0.0) necromancer (0.5.0) net-ldap (0.16.1) - net-scp (1.2.1) - net-ssh (>= 2.6.5) - net-ssh (5.0.2) + net-scp (2.0.0) + net-ssh (>= 2.6.5, < 6.0.0) + net-ssh (5.2.0) nio4r (2.4.0) nokogiri (1.10.4) mini_portile2 (~> 2.4.0) @@ -600,7 +600,7 @@ GEM actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) - sshkit (1.17.0) + sshkit (1.20.0) net-scp (>= 1.1.2) net-ssh (>= 2.8.0) stackprof (0.2.12) diff --git a/config/deploy.rb b/config/deploy.rb index f0db50788c..c4133e7946 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -1,6 +1,6 @@ # frozen_string_literal: true -lock '3.11.0' +lock '3.11.1' set :repo_url, ENV.fetch('REPO', 'https://github.com/tootsuite/mastodon.git') set :branch, ENV.fetch('BRANCH', 'master') From 529856a6087a88a14fe19ec0ede96573761bfe34 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 5 Sep 2019 12:31:47 +0900 Subject: [PATCH 33/48] Bump addressable from 2.6.0 to 2.7.0 (#11732) Bumps [addressable](https://github.com/sporkmonger/addressable) from 2.6.0 to 2.7.0. - [Release notes](https://github.com/sporkmonger/addressable/releases) - [Changelog](https://github.com/sporkmonger/addressable/blob/master/CHANGELOG.md) - [Commits](https://github.com/sporkmonger/addressable/compare/addressable-2.6.0...addressable-2.7.0) Signed-off-by: dependabot-preview[bot] --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 932b8a1adf..1cbf23cf21 100644 --- a/Gemfile +++ b/Gemfile @@ -24,7 +24,7 @@ gem 'streamio-ffmpeg', '~> 3.0' gem 'blurhash', '~> 0.1' gem 'active_model_serializers', '~> 0.10' -gem 'addressable', '~> 2.6' +gem 'addressable', '~> 2.7' gem 'bootsnap', '~> 1.4', require: false gem 'browser' gem 'charlock_holmes', '~> 0.7.6' diff --git a/Gemfile.lock b/Gemfile.lock index f601e7192a..8ecc8ebb75 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -83,8 +83,8 @@ GEM i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) - addressable (2.6.0) - public_suffix (>= 2.0.2, < 4.0) + addressable (2.7.0) + public_suffix (>= 2.0.2, < 5.0) airbrussh (1.3.3) sshkit (>= 1.6.1, != 1.7.0) annotate (2.7.5) @@ -442,7 +442,7 @@ GEM pry (~> 0.10) pry-rails (0.3.9) pry (>= 0.10.4) - public_suffix (3.1.1) + public_suffix (4.0.1) puma (4.1.0) nio4r (~> 2.0) pundit (2.1.0) @@ -668,7 +668,7 @@ PLATFORMS DEPENDENCIES active_model_serializers (~> 0.10) active_record_query_trace (~> 1.6) - addressable (~> 2.6) + addressable (~> 2.7) annotate (~> 2.7) aws-sdk-s3 (~> 1.48) better_errors (~> 2.5) From 1653b587778db0df201507115d19c0530096a5e3 Mon Sep 17 00:00:00 2001 From: ThibG Date: Thu, 5 Sep 2019 05:32:53 +0200 Subject: [PATCH 34/48] Attempt to concurrently connect to remote IP addresses (#11757) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Attempt to concurrently connect to remote IP addresses * Reduce code length to please CodeClimate 🤷 --- app/lib/request.rb | 52 +++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/app/lib/request.rb b/app/lib/request.rb index 9d874fe2ca..42ccc6513d 100644 --- a/app/lib/request.rb +++ b/app/lib/request.rb @@ -191,6 +191,9 @@ class Request end end + socks = [] + addr_by_socket = {} + addresses.each do |address| begin check_private_address(address) @@ -200,30 +203,45 @@ class Request sock.setsockopt(::Socket::IPPROTO_TCP, ::Socket::TCP_NODELAY, 1) - begin - sock.connect_nonblock(sockaddr) - rescue IO::WaitWritable - if IO.select(nil, [sock], nil, Request::TIMEOUT[:connect]) - begin - sock.connect_nonblock(sockaddr) - rescue Errno::EISCONN - # Yippee! - rescue - sock.close - raise - end - else - sock.close - raise HTTP::TimeoutError, "Connect timed out after #{Request::TIMEOUT[:connect]} seconds" - end - end + sock.connect_nonblock(sockaddr) + # If that hasn't raised an exception, we somehow managed to connect + # immediately, close pending sockets and return immediately + socks.each(&:close) return sock + rescue IO::WaitWritable + socks << sock + addr_by_socket[sock] = sockaddr rescue => e outer_e = e end end + until socks.empty? + _, available_socks, = IO.select(nil, socks, nil, Request::TIMEOUT[:connect]) + + if available_socks.nil? + socks.each(&:close) + raise HTTP::TimeoutError, "Connect timed out after #{Request::TIMEOUT[:connect]} seconds" + end + + available_socks.each do |sock| + socks.delete(sock) + + begin + sock.connect_nonblock(addr_by_socket[sock]) + rescue Errno::EISCONN + rescue => e + sock.close + outer_e = e + next + end + + socks.each(&:close) + return sock + end + end + if outer_e raise outer_e else From 58755439ac758f173cf6c8afb49d62b450782d14 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 5 Sep 2019 06:13:50 +0200 Subject: [PATCH 35/48] Fix wrong variable regression from #11753 (#11763) --- app/controllers/auth/confirmations_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/auth/confirmations_controller.rb b/app/controllers/auth/confirmations_controller.rb index 3e419eb96f..8985252699 100644 --- a/app/controllers/auth/confirmations_controller.rb +++ b/app/controllers/auth/confirmations_controller.rb @@ -26,7 +26,7 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController def after_resending_confirmation_instructions_path_for(_resource_name) if user_signed_in? - if user.confirmed? && user.approved? + if current_user.confirmed? && current_user.approved? edit_user_registration_path else auth_setup_path From 7db2c2e2ba049845bdfdbf9931ffae6ae5ccddd3 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 5 Sep 2019 06:14:06 +0200 Subject: [PATCH 36/48] Fix line breaks in hashtag autosuggestions in web UI (#11764) --- app/javascript/styles/mastodon/components.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index fde5e4c958..ef48d2438c 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -507,6 +507,7 @@ flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; } strong { @@ -515,8 +516,10 @@ &__uses { flex: 0 0 auto; - width: 80px; text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } } From e265b8887dbd883bc7ca04832dc67ffe46966889 Mon Sep 17 00:00:00 2001 From: mayaeh Date: Thu, 5 Sep 2019 13:14:30 +0900 Subject: [PATCH 37/48] Fix NotificationMailer failing when receiving mention with media from remote instance (#11765) --- app/views/notification_mailer/_status.html.haml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/views/notification_mailer/_status.html.haml b/app/views/notification_mailer/_status.html.haml index 40f3aa88a7..e992e5563d 100644 --- a/app/views/notification_mailer/_status.html.haml +++ b/app/views/notification_mailer/_status.html.haml @@ -36,7 +36,10 @@ - if status.media_attachments.size > 0 %p - status.media_attachments.each do |a| - = link_to medium_url(a), medium_url(a) + - if status.local? + = link_to medium_url(a), medium_url(a) + - else + = link_to a.remote_url, a.remote_url %p.status-footer = link_to l(status.created_at), web_url("statuses/#{status.id}") From 23c513846a3f829c81d98de1f6d274fc261aea3e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sun, 1 Sep 2019 19:43:35 +0200 Subject: [PATCH 38/48] [Glitch] Add "not available" label on unknown media attachments Port d3442894310022062debc4c6ed6b117f8bc3904b to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/components/media_gallery.js | 15 +++++++++++---- .../flavours/glitch/styles/components/index.scss | 8 ++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/javascript/flavours/glitch/components/media_gallery.js b/app/javascript/flavours/glitch/components/media_gallery.js index 04d3ce751d..f32f7ff36d 100644 --- a/app/javascript/flavours/glitch/components/media_gallery.js +++ b/app/javascript/flavours/glitch/components/media_gallery.js @@ -329,7 +329,8 @@ export default class MediaGallery extends React.PureComponent { render () { const { media, intl, sensitive, letterbox, fullwidth, defaultWidth } = this.props; const { visible } = this.state; - const size = media.take(4).size; + const size = media.take(4).size; + const uncached = media.every(attachment => attachment.get('type') === 'unknown'); const width = this.state.width || defaultWidth; @@ -350,10 +351,16 @@ export default class MediaGallery extends React.PureComponent { if (this.isStandaloneEligible()) { children = ; } else { - children = media.take(4).map((attachment, i) => ); + children = media.take(4).map((attachment, i) => ); } - if (visible) { + if (uncached) { + spoilerButton = ( + + ); + } else if (visible) { spoilerButton = ; } else { spoilerButton = ( @@ -365,7 +372,7 @@ export default class MediaGallery extends React.PureComponent { return (
-
+
{spoilerButton} {visible && sensitive && ( diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss index 3e224ac63d..7af80dd74c 100644 --- a/app/javascript/flavours/glitch/styles/components/index.scss +++ b/app/javascript/flavours/glitch/styles/components/index.scss @@ -1267,6 +1267,14 @@ background: rgba($base-overlay-background, 0.8); } } + + &:disabled { + cursor: not-allowed; + + .spoiler-button__overlay__label { + background: rgba($base-overlay-background, 0.5); + } + } } } From 2f952f6d0412285beb7f39a831b22bef6c3e9aeb Mon Sep 17 00:00:00 2001 From: ThibG Date: Sun, 1 Sep 2019 20:04:35 +0200 Subject: [PATCH 39/48] [Glitch] Fix custom emoji animation on hover in WebUI directory bios Port 34eac5a1ecab250760bec1f703ddf828670210fa to glitch-soc Signed-off-by: Thibaut Girka --- .../directory/components/account_card.js | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/features/directory/components/account_card.js b/app/javascript/flavours/glitch/features/directory/components/account_card.js index 5ba263825e..d1c4069333 100644 --- a/app/javascript/flavours/glitch/features/directory/components/account_card.js +++ b/app/javascript/flavours/glitch/features/directory/components/account_card.js @@ -82,6 +82,43 @@ class AccountCard extends ImmutablePureComponent { onMute: PropTypes.func.isRequired, }; + _updateEmojis () { + const node = this.node; + + if (!node || autoPlayGif) { + return; + } + + const emojis = node.querySelectorAll('.custom-emoji'); + + for (var i = 0; i < emojis.length; i++) { + let emoji = emojis[i]; + if (emoji.classList.contains('status-emoji')) { + continue; + } + emoji.classList.add('status-emoji'); + + emoji.addEventListener('mouseenter', this.handleEmojiMouseEnter, false); + emoji.addEventListener('mouseleave', this.handleEmojiMouseLeave, false); + } + } + + componentDidMount () { + this._updateEmojis(); + } + + componentDidUpdate () { + this._updateEmojis(); + } + + handleEmojiMouseEnter = ({ target }) => { + target.src = target.getAttribute('data-original'); + } + + handleEmojiMouseLeave = ({ target }) => { + target.src = target.getAttribute('data-static'); + } + handleFollow = () => { this.props.onFollow(this.props.account); } @@ -94,6 +131,10 @@ class AccountCard extends ImmutablePureComponent { this.props.onMute(this.props.account); } + setRef = (c) => { + this.node = c; + } + render () { const { account, intl } = this.props; @@ -133,7 +174,7 @@ class AccountCard extends ImmutablePureComponent {
-
+
From 96b9d3333d33fc2c30384fb12abbb7679edbcf36 Mon Sep 17 00:00:00 2001 From: ThibG Date: Mon, 2 Sep 2019 18:11:34 +0200 Subject: [PATCH 40/48] [Glitch] Fix height of dashboard counters Port 6493f4ffaea9ae391a9cc24e2743531fd0c3a3e8 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/styles/dashboard.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/javascript/flavours/glitch/styles/dashboard.scss b/app/javascript/flavours/glitch/styles/dashboard.scss index e4564f062c..c0944d417d 100644 --- a/app/javascript/flavours/glitch/styles/dashboard.scss +++ b/app/javascript/flavours/glitch/styles/dashboard.scss @@ -15,6 +15,8 @@ padding: 20px; background: lighten($ui-base-color, 4%); border-radius: 4px; + box-sizing: border-box; + height: 100%; } & > a { From 7db6cb93f32ede66b5791e5a66d3823c3ac506a7 Mon Sep 17 00:00:00 2001 From: ThibG Date: Mon, 2 Sep 2019 18:12:12 +0200 Subject: [PATCH 41/48] [Glitch] Fix Mastodon logo style on hover on public pages' footer Port 0ea53122f2a0db726afe96cfedd8e7fe3d930e0a to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/styles/footer.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/styles/footer.scss b/app/javascript/flavours/glitch/styles/footer.scss index f74c004e99..00d2908832 100644 --- a/app/javascript/flavours/glitch/styles/footer.scss +++ b/app/javascript/flavours/glitch/styles/footer.scss @@ -128,7 +128,7 @@ &:hover, &:focus, &:active { - svg path { + svg { fill: lighten($ui-base-color, 38%); } } From dea2b234c93b999ccd8d8a8874e126c249e83794 Mon Sep 17 00:00:00 2001 From: mayaeh Date: Tue, 3 Sep 2019 01:12:27 +0900 Subject: [PATCH 42/48] [Glitch] Integrate translation strings for the Profile Directory. Port 1f22b8197cb961371fa761e1fa214d4f4a2074d1 to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/features/ui/components/navigation_panel.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js b/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js index 1c8c7d76ef..a4f06f4c59 100644 --- a/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js +++ b/app/javascript/flavours/glitch/features/ui/components/navigation_panel.js @@ -18,7 +18,7 @@ const NavigationPanel = ({ onOpenSettings }) => ( - {profile_directory && } + {profile_directory && } From b86292af3390b2e8b40be756d57efe0205a6dd9b Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 3 Sep 2019 04:56:40 +0200 Subject: [PATCH 43/48] [Glitch] Fix uncached media in web UI not being clickable Port 34adc8784a3f165a4bd5719a067093f703f499e9 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/components/media_gallery.js | 4 ++-- app/javascript/flavours/glitch/styles/components/index.scss | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/javascript/flavours/glitch/components/media_gallery.js b/app/javascript/flavours/glitch/components/media_gallery.js index f32f7ff36d..28b369d09c 100644 --- a/app/javascript/flavours/glitch/components/media_gallery.js +++ b/app/javascript/flavours/glitch/components/media_gallery.js @@ -179,7 +179,7 @@ class Item extends React.PureComponent { if (attachment.get('type') === 'unknown') { return ( @@ -372,7 +372,7 @@ export default class MediaGallery extends React.PureComponent { return (
-
+
{spoilerButton} {visible && sensitive && ( diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss index 7af80dd74c..97c5255659 100644 --- a/app/javascript/flavours/glitch/styles/components/index.scss +++ b/app/javascript/flavours/glitch/styles/components/index.scss @@ -1239,6 +1239,10 @@ align-items: center; } + &--click-thru { + pointer-events: none; + } + &--hidden { display: none; } @@ -1269,8 +1273,6 @@ } &:disabled { - cursor: not-allowed; - .spoiler-button__overlay__label { background: rgba($base-overlay-background, 0.5); } From ca86858558c420d87f9e5d5e08d4ff8d34ecbce0 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Tue, 3 Sep 2019 06:35:44 +0200 Subject: [PATCH 44/48] [Glitch] Change hashtag component in web UI to show numbers for 2 last days Port d19d86fe2b26fb00577d600234c32d726fb199a4 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/components/hashtag.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/components/hashtag.js b/app/javascript/flavours/glitch/components/hashtag.js index d75edd9947..426f7ecb05 100644 --- a/app/javascript/flavours/glitch/components/hashtag.js +++ b/app/javascript/flavours/glitch/components/hashtag.js @@ -12,11 +12,11 @@ const Hashtag = ({ hashtag }) => ( #{hashtag.get('name')} - {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']))} }} /> + {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']) + hashtag.getIn(['history', 1, 'accounts']))} }} />
- {shortNumberFormat(hashtag.getIn(['history', 0, 'uses']))} + {shortNumberFormat(hashtag.getIn(['history', 0, 'uses']) + hashtag.getIn(['history', 1, 'uses']))}
From 4907517db4103f93bc7df0c1e9f42a533fff630e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 4 Sep 2019 04:14:13 +0200 Subject: [PATCH 45/48] [Glitch] Fix wrong pluralization in hashtag component in web UI Port 1a00bd9244ee8555d7401f4f0ee01ec381e96c1c to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/components/hashtag.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/components/hashtag.js b/app/javascript/flavours/glitch/components/hashtag.js index 426f7ecb05..03c8b6e3a3 100644 --- a/app/javascript/flavours/glitch/components/hashtag.js +++ b/app/javascript/flavours/glitch/components/hashtag.js @@ -12,7 +12,7 @@ const Hashtag = ({ hashtag }) => ( #{hashtag.get('name')} - {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']) + hashtag.getIn(['history', 1, 'accounts']))} }} /> + {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']) + hashtag.getIn(['history', 1, 'accounts']))} }} />
From a869572aabba1284b646109bc10fe377e6ade3fd Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Wed, 4 Sep 2019 10:10:18 +0200 Subject: [PATCH 46/48] [Glitch] Fix wrong sum of usage in hashtag component in web UI Port a6a63358c3fd81b9104aa0a51133cd065eea4a84 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/components/hashtag.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/javascript/flavours/glitch/components/hashtag.js b/app/javascript/flavours/glitch/components/hashtag.js index 03c8b6e3a3..d42bee0e99 100644 --- a/app/javascript/flavours/glitch/components/hashtag.js +++ b/app/javascript/flavours/glitch/components/hashtag.js @@ -12,11 +12,11 @@ const Hashtag = ({ hashtag }) => ( #{hashtag.get('name')} - {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']) + hashtag.getIn(['history', 1, 'accounts']))} }} /> + {shortNumberFormat(hashtag.getIn(['history', 0, 'accounts']) * 1 + hashtag.getIn(['history', 1, 'accounts']) * 1)} }} />
- {shortNumberFormat(hashtag.getIn(['history', 0, 'uses']) + hashtag.getIn(['history', 1, 'uses']))} + {shortNumberFormat(hashtag.getIn(['history', 0, 'uses']) * 1 + hashtag.getIn(['history', 1, 'uses']) * 1)}
From bd0bde1da2279b21b10c10a9ddbee6ea49282c28 Mon Sep 17 00:00:00 2001 From: Mostafa Ahangarha Date: Thu, 5 Sep 2019 01:00:49 +0430 Subject: [PATCH 47/48] [Glitch] Exclude URLs from text analysis Port e974d4923fabd887416609bc6c8ca81ce81d0ff2 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/util/rtl.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/javascript/flavours/glitch/util/rtl.js b/app/javascript/flavours/glitch/util/rtl.js index 00870a15d6..89bed6de88 100644 --- a/app/javascript/flavours/glitch/util/rtl.js +++ b/app/javascript/flavours/glitch/util/rtl.js @@ -20,6 +20,7 @@ export function isRtl(text) { text = text.replace(/(?:^|[^\/\w])@([a-z0-9_]+(@[a-z0-9\.\-]+)?)/ig, ''); text = text.replace(/(?:^|[^\/\w])#([\S]+)/ig, ''); text = text.replace(/\s+/g, ''); + text = text.replace(/(\w\S+\.\w{2,}\S*)/g, ''); const matches = text.match(rtlChars); From 4434e2eb7f9942b44561c2f7702af3ed3854b8db Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Thu, 5 Sep 2019 06:14:06 +0200 Subject: [PATCH 48/48] [Glitch] Fix line breaks in hashtag autosuggestions in web UI Port 7db2c2e2ba049845bdfdbf9931ffae6ae5ccddd3 to glitch-soc Signed-off-by: Thibaut Girka --- .../flavours/glitch/styles/components/composer.scss | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/javascript/flavours/glitch/styles/components/composer.scss b/app/javascript/flavours/glitch/styles/components/composer.scss index c3d51e4f99..656615f4f2 100644 --- a/app/javascript/flavours/glitch/styles/components/composer.scss +++ b/app/javascript/flavours/glitch/styles/components/composer.scss @@ -353,6 +353,7 @@ flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; + white-space: nowrap; } strong { @@ -361,8 +362,10 @@ &__uses { flex: 0 0 auto; - width: 80px; text-align: right; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; } }