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 2355d9d7d..8ab08ebae 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 d8c7e0f0c..3cf12c22c 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 3cf12c22c..b5904ad95 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 9cd71b7c9..55e0e77d6 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 d7e90fcaf..0b569bb8f 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 39aca2a4b..25d9b7d3d 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 c3779d48c..f9677874a 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 cb23a02ba..50ad74450 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 f79fa4912..932aa059e 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 a02b5a081..51b9c055c 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 932aa059e..135ba684a 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 51b9c055c..cd8618714 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 25d9b7d3d..8bd4e5f8b 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 ca3d890a8..871ec5c19 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 945e3a3c6..135e0a030 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 e4ce988c1..e1b92b175 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 000000000..77f0d5747 --- /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 6ebe450b0..5de25de23 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 000000000..f936e9871 --- /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 000000000..a1112700b --- /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 482bca367..5576f70bf 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 000000000..b6122c994 --- /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 e4564f062..c0944d417 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 f74c004e9..00d290883 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 6f07778f2..51e3ec037 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 9118527db..db2d1c7bd 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 6c0c5cbb8..debc755c3 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 30daa6bb1..6bf2ec81e 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 892d13c72..9c9dbc94b 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 d66b05050..b322aee1d 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 d1b5a8df5..29d6194dd 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 55e0e77d6..e8dd79af9 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 0b569bb8f..fde5e4c95 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 dd0b25f3e..daacb535b 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 83384d737..e807c8d86 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 67238fc8b..576f47a67 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 9c9dbc94b..ad29e0a74 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 90c8f9dd1..33e7c96fe 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 1105f2062..89dc2a75d 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 45ad3b64d..bb6610c79 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 f091d7893..2456eac9e 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 f9677874a..d54a43c1e 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 1c58be8c0..cb2ac72d4 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 07bd8c494..1fdc79310 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 222e17c99..17df85de3 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 7592e0b1a..364d3eda5 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 329a5fb2c..0e69e1d96 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 fbfc585cf..42da29860 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 f0c0ee0b7..42c747d2e 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 982dc5035..1d85aa75e 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 0d7c6e7c2..3e419eb96 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 ac99124ea..16352340b 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 902af376c..85da7e921 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 8bb44ca7f..c14fed56f 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 3c68ccd22..e6c3f7cca 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 b246f83a1..6e2ff31c5 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 ad29e0a74..687f5f2a0 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 2456eac9e..68b9be72d 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 68b9be72d..62d613262 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 e40dea54f..9dcd06ea3 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 be310c24a..872ae3bc4 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 9dcd06ea3..72a444876 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 872ae3bc4..54ea059ea 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 54ea059ea..8fee0532d 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 8fee0532d..475a27fb2 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 72a444876..932b8a1ad 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 475a27fb2..63676bd1b 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 6a96867d5..224be7903 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 00870a15d..89bed6de8 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 63676bd1b..f601e7192 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 f0db50788..c4133e794 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 932b8a1ad..1cbf23cf2 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 f601e7192..8ecc8ebb7 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 9d874fe2c..42ccc6513 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 3e419eb96..898525269 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 fde5e4c95..ef48d2438 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 40f3aa88a..e992e5563 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 04d3ce751..f32f7ff36 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 3e224ac63..7af80dd74 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 5ba263825..d1c406933 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 e4564f062..c0944d417 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 f74c004e9..00d290883 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 1c8c7d76e..a4f06f4c5 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 f32f7ff36..28b369d09 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 7af80dd74..97c525565 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 d75edd994..426f7ecb0 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 426f7ecb0..03c8b6e3a 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 03c8b6e3a..d42bee0e9 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 00870a15d..89bed6de8 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 c3d51e4f9..656615f4f 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; } }