diff --git a/.gitignore b/.gitignore index 25c8388e1..7d76b8275 100644 --- a/.gitignore +++ b/.gitignore @@ -44,6 +44,9 @@ /redis /elasticsearch +# ignore Helm charts +/chart/*.tgz + # ignore Helm dependency charts /chart/charts/*.tgz diff --git a/CHANGELOG.md b/CHANGELOG.md index 777a83790..72f62a1dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - **Add ability to follow hashtags** ([Gargron](https://github.com/mastodon/mastodon/pull/18809), [Gargron](https://github.com/mastodon/mastodon/pull/18862), [Gargron](https://github.com/mastodon/mastodon/pull/19472), [noellabo](https://github.com/mastodon/mastodon/pull/18924)) - Add ability to filter individual posts ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18945)) - **Add ability to translate posts** ([Gargron](https://github.com/mastodon/mastodon/pull/19218), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19433), [Gargron](https://github.com/mastodon/mastodon/pull/19453), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19434), [Gargron](https://github.com/mastodon/mastodon/pull/19388), [ykzts](https://github.com/mastodon/mastodon/pull/19244), [Gargron](https://github.com/mastodon/mastodon/pull/19245)) -- Add featured tags to web UI ([noellabo](https://github.com/mastodon/mastodon/pull/19408), [noellabo](https://github.com/mastodon/mastodon/pull/19380), [noellabo](https://github.com/mastodon/mastodon/pull/19358), [noellabo](https://github.com/mastodon/mastodon/pull/19409), [Gargron](https://github.com/mastodon/mastodon/pull/19382), [ykzts](https://github.com/mastodon/mastodon/pull/19418), [noellabo](https://github.com/mastodon/mastodon/pull/19403), [noellabo](https://github.com/mastodon/mastodon/pull/19404), [Gargron](https://github.com/mastodon/mastodon/pull/19398), [Gargron](https://github.com/mastodon/mastodon/pull/19712)) +- Add featured tags to web UI ([noellabo](https://github.com/mastodon/mastodon/pull/19408), [noellabo](https://github.com/mastodon/mastodon/pull/19380), [noellabo](https://github.com/mastodon/mastodon/pull/19358), [noellabo](https://github.com/mastodon/mastodon/pull/19409), [Gargron](https://github.com/mastodon/mastodon/pull/19382), [ykzts](https://github.com/mastodon/mastodon/pull/19418), [noellabo](https://github.com/mastodon/mastodon/pull/19403), [noellabo](https://github.com/mastodon/mastodon/pull/19404), [Gargron](https://github.com/mastodon/mastodon/pull/19398), [Gargron](https://github.com/mastodon/mastodon/pull/19712), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20018)) - **Add support for language preferences for trending statuses and links** ([Gargron](https://github.com/mastodon/mastodon/pull/18288), [Gargron](https://github.com/mastodon/mastodon/pull/19349), [ykzts](https://github.com/mastodon/mastodon/pull/19335)) - Previously, you could only see trends in your current language - For less popular languages, that meant empty trends @@ -21,6 +21,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Add server rules to sign-up flow ([Gargron](https://github.com/mastodon/mastodon/pull/19296)) - Add privacy icons to report modal in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19190)) - Add `noopener` to links to remote profiles in web UI ([shleeable](https://github.com/mastodon/mastodon/pull/19014)) +- Add option to open original page in dropdowns of remote content in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/20299)) - Add warning for sensitive audio posts in web UI ([rgroothuijsen](https://github.com/mastodon/mastodon/pull/17885)) - Add language attribute to posts in web UI ([tribela](https://github.com/mastodon/mastodon/pull/18544)) - Add support for uploading WebP files ([Saiv46](https://github.com/mastodon/mastodon/pull/18506)) @@ -43,22 +44,26 @@ Some of the features in this release have been funded through the [NGI0 Discover - Add admin API for managing domain blocks ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18247)) - Add admin API for managing e-mail domain blocks ([Gargron](https://github.com/mastodon/mastodon/pull/19066)) - Add admin API for managing canonical e-mail blocks ([Gargron](https://github.com/mastodon/mastodon/pull/19067)) -- Add admin API for managing IP blocks ([Gargron](https://github.com/mastodon/mastodon/pull/19065)) +- Add admin API for managing IP blocks ([Gargron](https://github.com/mastodon/mastodon/pull/19065), [trwnh](https://github.com/mastodon/mastodon/pull/20207)) +- Add `sensitized` attribute to accounts in admin REST API ([trwnh](https://github.com/mastodon/mastodon/pull/20094)) - Add `services` and `metadata` to the NodeInfo endpoint ([MFTabriz](https://github.com/mastodon/mastodon/pull/18563)) - Add `--remove-role` option to `tootctl accounts modify` ([Gargron](https://github.com/mastodon/mastodon/pull/19477)) - Add `--days` option to `tootctl media refresh` ([tribela](https://github.com/mastodon/mastodon/pull/18425)) - Add `EMAIL_DOMAIN_LISTS_APPLY_AFTER_CONFIRMATION` environment variable ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18642)) - Add `IP_RETENTION_PERIOD` and `SESSION_RETENTION_PERIOD` environment variables ([kescherCode](https://github.com/mastodon/mastodon/pull/18757)) - Add `http_hidden_proxy` environment variable ([tribela](https://github.com/mastodon/mastodon/pull/18427)) -- Add caching for payload serialization during fan-out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19637), [Gargron](https://github.com/mastodon/mastodon/pull/19642), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19746), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19747)) +- Add `ENABLE_STARTTLS` environment variable ([erbridge](https://github.com/mastodon/mastodon/pull/20321)) +- Add caching for payload serialization during fan-out ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19637), [Gargron](https://github.com/mastodon/mastodon/pull/19642), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19746), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19747), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19963)) - Add assets from Twemoji 14.0 ([Gargron](https://github.com/mastodon/mastodon/pull/19733)) - Add reputation and followers score boost to SQL-only account search ([Gargron](https://github.com/mastodon/mastodon/pull/19251)) +- Add Scots, Balaibalan, Láadan, Lingua Franca Nova, Lojban, Toki Pona to languages list ([VyrCossont](https://github.com/mastodon/mastodon/pull/20168)) +- Set autocomplete hints for e-mail, password and OTP fields ([rcombs](https://github.com/mastodon/mastodon/pull/19833), [offbyone](https://github.com/mastodon/mastodon/pull/19946), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20071)) ### Changed - **Change brand color and logotypes** ([Gargron](https://github.com/mastodon/mastodon/pull/18592), [Gargron](https://github.com/mastodon/mastodon/pull/18639), [Gargron](https://github.com/mastodon/mastodon/pull/18691), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18634), [Gargron](https://github.com/mastodon/mastodon/pull/19254), [mayaeh](https://github.com/mastodon/mastodon/pull/18710)) - **Change post editing to be enabled in web UI** ([Gargron](https://github.com/mastodon/mastodon/pull/19103)) -- **Change web UI to work for logged-out users** ([Gargron](https://github.com/mastodon/mastodon/pull/18961), [Gargron](https://github.com/mastodon/mastodon/pull/19250), [Gargron](https://github.com/mastodon/mastodon/pull/19294), [Gargron](https://github.com/mastodon/mastodon/pull/19306), [Gargron](https://github.com/mastodon/mastodon/pull/19315), [ykzts](https://github.com/mastodon/mastodon/pull/19322), [Gargron](https://github.com/mastodon/mastodon/pull/19412), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19437), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19415), [Gargron](https://github.com/mastodon/mastodon/pull/19348), [Gargron](https://github.com/mastodon/mastodon/pull/19295), [Gargron](https://github.com/mastodon/mastodon/pull/19422), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19414), [Gargron](https://github.com/mastodon/mastodon/pull/19319), [Gargron](https://github.com/mastodon/mastodon/pull/19345), [Gargron](https://github.com/mastodon/mastodon/pull/19310), [Gargron](https://github.com/mastodon/mastodon/pull/19301), [Gargron](https://github.com/mastodon/mastodon/pull/19423), [ykzts](https://github.com/mastodon/mastodon/pull/19471), [ykzts](https://github.com/mastodon/mastodon/pull/19333), [ykzts](https://github.com/mastodon/mastodon/pull/19337), [ykzts](https://github.com/mastodon/mastodon/pull/19272), [ykzts](https://github.com/mastodon/mastodon/pull/19468), [Gargron](https://github.com/mastodon/mastodon/pull/19466), [Gargron](https://github.com/mastodon/mastodon/pull/19457), [Gargron](https://github.com/mastodon/mastodon/pull/19426), [Gargron](https://github.com/mastodon/mastodon/pull/19427), [Gargron](https://github.com/mastodon/mastodon/pull/19421), [Gargron](https://github.com/mastodon/mastodon/pull/19417), [Gargron](https://github.com/mastodon/mastodon/pull/19413), [Gargron](https://github.com/mastodon/mastodon/pull/19397), [Gargron](https://github.com/mastodon/mastodon/pull/19387), [Gargron](https://github.com/mastodon/mastodon/pull/19396), [Gargron](https://github.com/mastodon/mastodon/pull/19385), [ykzts](https://github.com/mastodon/mastodon/pull/19334), [ykzts](https://github.com/mastodon/mastodon/pull/19329), [Gargron](https://github.com/mastodon/mastodon/pull/19324), [Gargron](https://github.com/mastodon/mastodon/pull/19318), [Gargron](https://github.com/mastodon/mastodon/pull/19316), [Gargron](https://github.com/mastodon/mastodon/pull/19263), [trwnh](https://github.com/mastodon/mastodon/pull/19305), [ykzts](https://github.com/mastodon/mastodon/pull/19273), [Gargron](https://github.com/mastodon/mastodon/pull/19801), [Gargron](https://github.com/mastodon/mastodon/pull/19790), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19773), [Gargron](https://github.com/mastodon/mastodon/pull/19798), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19724), [Gargron](https://github.com/mastodon/mastodon/pull/19709), [Gargron](https://github.com/mastodon/mastodon/pull/19514), [Gargron](https://github.com/mastodon/mastodon/pull/19562)) +- **Change web UI to work for logged-out users** ([Gargron](https://github.com/mastodon/mastodon/pull/18961), [Gargron](https://github.com/mastodon/mastodon/pull/19250), [Gargron](https://github.com/mastodon/mastodon/pull/19294), [Gargron](https://github.com/mastodon/mastodon/pull/19306), [Gargron](https://github.com/mastodon/mastodon/pull/19315), [ykzts](https://github.com/mastodon/mastodon/pull/19322), [Gargron](https://github.com/mastodon/mastodon/pull/19412), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19437), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19415), [Gargron](https://github.com/mastodon/mastodon/pull/19348), [Gargron](https://github.com/mastodon/mastodon/pull/19295), [Gargron](https://github.com/mastodon/mastodon/pull/19422), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19414), [Gargron](https://github.com/mastodon/mastodon/pull/19319), [Gargron](https://github.com/mastodon/mastodon/pull/19345), [Gargron](https://github.com/mastodon/mastodon/pull/19310), [Gargron](https://github.com/mastodon/mastodon/pull/19301), [Gargron](https://github.com/mastodon/mastodon/pull/19423), [ykzts](https://github.com/mastodon/mastodon/pull/19471), [ykzts](https://github.com/mastodon/mastodon/pull/19333), [ykzts](https://github.com/mastodon/mastodon/pull/19337), [ykzts](https://github.com/mastodon/mastodon/pull/19272), [ykzts](https://github.com/mastodon/mastodon/pull/19468), [Gargron](https://github.com/mastodon/mastodon/pull/19466), [Gargron](https://github.com/mastodon/mastodon/pull/19457), [Gargron](https://github.com/mastodon/mastodon/pull/19426), [Gargron](https://github.com/mastodon/mastodon/pull/19427), [Gargron](https://github.com/mastodon/mastodon/pull/19421), [Gargron](https://github.com/mastodon/mastodon/pull/19417), [Gargron](https://github.com/mastodon/mastodon/pull/19413), [Gargron](https://github.com/mastodon/mastodon/pull/19397), [Gargron](https://github.com/mastodon/mastodon/pull/19387), [Gargron](https://github.com/mastodon/mastodon/pull/19396), [Gargron](https://github.com/mastodon/mastodon/pull/19385), [ykzts](https://github.com/mastodon/mastodon/pull/19334), [ykzts](https://github.com/mastodon/mastodon/pull/19329), [Gargron](https://github.com/mastodon/mastodon/pull/19324), [Gargron](https://github.com/mastodon/mastodon/pull/19318), [Gargron](https://github.com/mastodon/mastodon/pull/19316), [Gargron](https://github.com/mastodon/mastodon/pull/19263), [trwnh](https://github.com/mastodon/mastodon/pull/19305), [ykzts](https://github.com/mastodon/mastodon/pull/19273), [Gargron](https://github.com/mastodon/mastodon/pull/19801), [Gargron](https://github.com/mastodon/mastodon/pull/19790), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19773), [Gargron](https://github.com/mastodon/mastodon/pull/19798), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19724), [Gargron](https://github.com/mastodon/mastodon/pull/19709), [Gargron](https://github.com/mastodon/mastodon/pull/19514), [Gargron](https://github.com/mastodon/mastodon/pull/19562), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19981), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19978), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/20148), [Gargron](https://github.com/mastodon/mastodon/pull/20302)) - The web app can now be accessed without being logged in - No more `/web` prefix on web app paths - Profiles, posts, and other public pages now use the same interface for logged in and logged out users @@ -74,14 +79,13 @@ Some of the features in this release have been funded through the [NGI0 Discover - Change label of publish button to be "Publish" again in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/18583)) - Change language to be carried over on reply in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18557)) - Change "Unfollow" to "Cancel follow request" when request still pending in web UI ([prplecake](https://github.com/mastodon/mastodon/pull/19363)) -- **Change post filtering system** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18058), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19050), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18894), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19051), [noellabo](https://github.com/mastodon/mastodon/pull/18923), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18956), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18744)) +- **Change post filtering system** ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18058), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19050), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18894), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19051), [noellabo](https://github.com/mastodon/mastodon/pull/18923), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18956), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18744), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/19878)) - Filtered keywords and phrases can now be grouped into named categories - Filtered posts show which exact filter was hit - Individual posts can be added to a filter - You can peek inside filtered posts anyway - Change path of privacy policy page from `/terms` to `/privacy-policy` ([Gargron](https://github.com/mastodon/mastodon/pull/19249)) - Change how hashtags are normalized ([Gargron](https://github.com/mastodon/mastodon/pull/18795), [Gargron](https://github.com/mastodon/mastodon/pull/18863), [ClearlyClaire](https://github.com/mastodon/mastodon/pull/18854)) -- Change public (but not hashtag) timelines to be filtered by current locale by default ([Gargron](https://github.com/mastodon/mastodon/pull/19291), [Gargron](https://github.com/mastodon/mastodon/pull/19563)) - Change settings area to be separated into categories in admin UI ([Gargron](https://github.com/mastodon/mastodon/pull/19407), [Gargron](https://github.com/mastodon/mastodon/pull/19533)) - Change "No accounts selected" errors to use the appropriate noun in admin UI ([prplecake](https://github.com/mastodon/mastodon/pull/19356)) - Change e-mail domain blocks to match subdomains of blocked domains ([Gargron](https://github.com/mastodon/mastodon/pull/18979)) @@ -95,6 +99,12 @@ Some of the features in this release have been funded through the [NGI0 Discover - Change mentions of blocked users to not be processed ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19725)) - Change max. thumbnail dimensions to 640x360px (360p) ([Gargron](https://github.com/mastodon/mastodon/pull/19619)) - Change post-processing to be deferred only for large media types ([Gargron](https://github.com/mastodon/mastodon/pull/19617)) +- Change link verification to only work for https links without unicode ([Gargron](https://github.com/mastodon/mastodon/pull/20304), [Gargron](https://github.com/mastodon/mastodon/pull/20295)) +- Change account deletion requests to spread out over time ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20222)) +- Change larger reblogs/favourites numbers to be shortened in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/20303)) +- Change incoming activity processing to happen in `ingress` queue ([Gargron](https://github.com/mastodon/mastodon/pull/20264)) +- Change notifications to not link show preview cards in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20335)) +- Change amount of replies returned for logged out users in REST API ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20355)) ### Removed @@ -107,6 +117,25 @@ Some of the features in this release have been funded through the [NGI0 Discover ### Fixed +- Fix connections to IPv6-only servers ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20108)) +- Fix unnecessary service worker registration and preloading when logged out in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20341)) +- Fix unnecessary and slow regex construction ([raggi](https://github.com/mastodon/mastodon/pull/20215)) +- Fix `mailers` queue not being used for mailers ([Gargron](https://github.com/mastodon/mastodon/pull/20274)) +- Fix error in webfinger redirect handling ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20260)) +- Fix report category not being set to `violation` if rule IDs are provided ([trwnh](https://github.com/mastodon/mastodon/pull/20137)) +- Fix nodeinfo metadata attribute being an array instead of an object ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20114)) +- Fix account endorsements not being idempotent ([trwnh](https://github.com/mastodon/mastodon/pull/20118)) +- Fix status and rule IDs not being strings in admin reports REST API ([trwnh](https://github.com/mastodon/mastodon/pull/20122)) +- Fix error on invalid `replies_policy` in REST API ([trwnh](https://github.com/mastodon/mastodon/pull/20126)) +- Fix redrafting a currently-editing post not leaving edit mode in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/20023)) +- Fix performance by avoiding method cache busts ([raggi](https://github.com/mastodon/mastodon/pull/19957)) +- Fix opening the language picker scrolling the single-column view to the top in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19983)) +- Fix content warning button missing `aria-expanded` attribute in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19975)) +- Fix redundant `aria-pressed` attributes in web UI ([Brawaru](https://github.com/mastodon/mastodon/pull/19912)) +- Fix crash when external auth provider has no display name set ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19962)) +- Fix followers count not being updated when migrating follows ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19998)) +- Fix double button to clear emoji search input in web UI ([sunny](https://github.com/mastodon/mastodon/pull/19888)) +- Fix missing null check on applications on strike disputes ([kescherCode](https://github.com/mastodon/mastodon/pull/19851)) - Fix featured tags not saving preferred casing ([Gargron](https://github.com/mastodon/mastodon/pull/19732)) - Fix language not being saved when editing status ([Gargron](https://github.com/mastodon/mastodon/pull/19543)) - Fix not being able to input featured tag with hash symbol ([Gargron](https://github.com/mastodon/mastodon/pull/19535)) @@ -118,7 +147,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix account action type validation ([Gargron](https://github.com/mastodon/mastodon/pull/19476)) - Fix upload progress not communicating processing phase in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19530)) - Fix wrong host being used for custom.css when asset host configured ([Gargron](https://github.com/mastodon/mastodon/pull/19521)) -- Fix account migration form ever using outdated account data ([Gargron](https://github.com/mastodon/mastodon/pull/18429)) +- Fix account migration form ever using outdated account data ([Gargron](https://github.com/mastodon/mastodon/pull/18429), [nightpool](https://github.com/mastodon/mastodon/pull/19883)) - Fix error when uploading malformed CSV import ([Gargron](https://github.com/mastodon/mastodon/pull/19509)) - Fix avatars not using image tags in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/19488)) - Fix handling of duplicate and out-of-order notifications in web UI ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/19693)) @@ -157,6 +186,10 @@ Some of the features in this release have been funded through the [NGI0 Discover - Fix `CAS_DISPLAY_NAME`, `SAML_DISPLAY_NAME` and `OIDC_DISPLAY_NAME` being ignored ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/18568)) - Fix various typos in comments throughout the codebase ([luzpaz](https://github.com/mastodon/mastodon/pull/18604)) +### Security + +- Fix being able to spoof link verification ([Gargron](https://github.com/mastodon/mastodon/pull/20217)) + ## [3.5.3] - 2022-05-26 ### Added @@ -276,7 +309,7 @@ Some of the features in this release have been funded through the [NGI0 Discover ### Fixed -- Fix error resposes for `from` search prefix ([single-right-quote](https://github.com/mastodon/mastodon/pull/17963)) +- Fix error responses for `from` search prefix ([single-right-quote](https://github.com/mastodon/mastodon/pull/17963)) - Fix dangling language-specific trends ([Gargron](https://github.com/mastodon/mastodon/pull/17997)) - Fix extremely rare race condition when deleting a status or account ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17994)) - Fix trends returning less results per page when filtered in REST API ([Gargron](https://github.com/mastodon/mastodon/pull/17996)) @@ -411,7 +444,7 @@ Some of the features in this release have been funded through the [NGI0 Discover - Remove profile directory link from main navigation panel in web UI ([Gargron](https://github.com/mastodon/mastodon/pull/17688)) - **Remove language detection through cld3** ([Gargron](https://github.com/mastodon/mastodon/pull/17478), [ykzts](https://github.com/mastodon/mastodon/pull/17539), [Gargron](https://github.com/mastodon/mastodon/pull/17496), [Gargron](https://github.com/mastodon/mastodon/pull/17722)) - cld3 is very inaccurate on short-form content even with unique alphabets - - Post language can be overriden individually using `language` param + - Post language can be overridden individually using `language` param - Otherwise, it defaults to the user's interface language - Remove support for `OAUTH_REDIRECT_AT_SIGN_IN` ([ClearlyClaire](https://github.com/mastodon/mastodon/pull/17287)) - Use `OMNIAUTH_ONLY` instead diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3f51c4bd0..9963054b3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -42,6 +42,8 @@ It is not always possible to phrase every change in such a manner, but it is des - Code style rules (rubocop, eslint) - Normalization of locale files (i18n-tasks) +**Note**: You may need to log in and authorise the GitHub account your fork of this repository belongs to with CircleCI to enable some of the automated checks to run. + ## Documentation The [Mastodon documentation](https://docs.joinmastodon.org) is a statically generated site. You can [submit merge requests to mastodon/documentation](https://github.com/mastodon/documentation). diff --git a/SECURITY.md b/SECURITY.md index 9a72f3640..ccc7c1034 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,6 +1,6 @@ # Security Policy -If you believe you've identified a security vulnerability in Mastodon (a bug that allows something to happen that shouldn't be possible), you can reach us at . +If you believe you've identified a security vulnerability in Mastodon (a bug that allows something to happen that shouldn't be possible), you can reach us at . You should *not* report such issues on GitHub or in other public spaces to give us time to publish a fix for the issue without exposing Mastodon's users to increased risk. @@ -10,9 +10,8 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through ## Supported Versions -| Version | Supported | -| ------- | ------------------ | -| 3.5.x | Yes | -| 3.4.x | Yes | -| 3.3.x | No | -| < 3.3 | No | +| Version | Supported | +| ------- | ----------| +| 4.0.x | Yes | +| 3.5.x | Yes | +| < 3.5 | No | diff --git a/app.json b/app.json index c694908c5..4f05a64f5 100644 --- a/app.json +++ b/app.json @@ -79,8 +79,13 @@ "description": "SMTP server certificate verification mode. Defaults is 'peer'.", "required": false }, + "SMTP_ENABLE_STARTTLS": { + "description": "Enable STARTTLS? Default is 'auto'.", + "value": "auto", + "required": false + }, "SMTP_ENABLE_STARTTLS_AUTO": { - "description": "Enable STARTTLS if SMTP server supports it? Default is true.", + "description": "Enable STARTTLS if SMTP server supports it? Deprecated by SMTP_ENABLE_STARTTLS.", "required": false } }, diff --git a/app/controllers/api/v1/accounts/pins_controller.rb b/app/controllers/api/v1/accounts/pins_controller.rb index 3915b5669..73f845c61 100644 --- a/app/controllers/api/v1/accounts/pins_controller.rb +++ b/app/controllers/api/v1/accounts/pins_controller.rb @@ -8,7 +8,7 @@ class Api::V1::Accounts::PinsController < Api::BaseController before_action :set_account def create - AccountPin.create!(account: current_account, target_account: @account) + AccountPin.find_or_create_by!(account: current_account, target_account: @account) render json: @account, serializer: REST::RelationshipSerializer, relationships: relationships_presenter end diff --git a/app/controllers/api/v1/filters_controller.rb b/app/controllers/api/v1/filters_controller.rb index 07cd14147..149139b40 100644 --- a/app/controllers/api/v1/filters_controller.rb +++ b/app/controllers/api/v1/filters_controller.rb @@ -52,7 +52,7 @@ class Api::V1::FiltersController < Api::BaseController end def resource_params - params.permit(:phrase, :expires_in, :irreversible, :whole_word, context: []) + params.permit(:phrase, :expires_in, :irreversible, context: []) end def filter_params diff --git a/app/controllers/api/v1/lists_controller.rb b/app/controllers/api/v1/lists_controller.rb index e5ac45fef..843ca2ec2 100644 --- a/app/controllers/api/v1/lists_controller.rb +++ b/app/controllers/api/v1/lists_controller.rb @@ -7,6 +7,10 @@ class Api::V1::ListsController < Api::BaseController before_action :require_user! before_action :set_list, except: [:index, :create] + rescue_from ArgumentError do |e| + render json: { error: e.to_s }, status: 422 + end + def index @lists = List.where(account: current_account).all render json: @lists, each_serializer: REST::ListSerializer diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index 676ec2a79..6290a1746 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -18,14 +18,29 @@ class Api::V1::StatusesController < Api::BaseController # than this anyway CONTEXT_LIMIT = 4_096 + # This remains expensive and we don't want to show everything to logged-out users + ANCESTORS_LIMIT = 40 + DESCENDANTS_LIMIT = 60 + DESCENDANTS_DEPTH_LIMIT = 20 + def show @status = cache_collection([@status], Status).first render json: @status, serializer: REST::StatusSerializer end def context - ancestors_results = @status.in_reply_to_id.nil? ? [] : @status.ancestors(CONTEXT_LIMIT, current_account) - descendants_results = @status.descendants(CONTEXT_LIMIT, current_account) + ancestors_limit = CONTEXT_LIMIT + descendants_limit = CONTEXT_LIMIT + descendants_depth_limit = nil + + if current_account.nil? + ancestors_limit = ANCESTORS_LIMIT + descendants_limit = DESCENDANTS_LIMIT + descendants_depth_limit = DESCENDANTS_DEPTH_LIMIT + end + + ancestors_results = @status.in_reply_to_id.nil? ? [] : @status.ancestors(ancestors_limit, current_account) + descendants_results = @status.descendants(descendants_limit, current_account, descendants_depth_limit) loaded_ancestors = cache_collection(ancestors_results, Status) loaded_descendants = cache_collection(descendants_results, Status) diff --git a/app/controllers/api/v1/tags_controller.rb b/app/controllers/api/v1/tags_controller.rb index 9e5c53330..32f71bdce 100644 --- a/app/controllers/api/v1/tags_controller.rb +++ b/app/controllers/api/v1/tags_controller.rb @@ -24,7 +24,7 @@ class Api::V1::TagsController < Api::BaseController private def set_or_create_tag - return not_found unless /\A(#{Tag::HASHTAG_NAME_RE})\z/.match?(params[:id]) + return not_found unless Tag::HASHTAG_NAME_RE.match?(params[:id]) @tag = Tag.find_normalized(params[:id]) || Tag.new(name: Tag.normalize(params[:id]), display_name: params[:id]) end end diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb index 15b91d63e..d253b744f 100644 --- a/app/controllers/api/v1/timelines/public_controller.rb +++ b/app/controllers/api/v1/timelines/public_controller.rb @@ -35,7 +35,6 @@ class Api::V1::Timelines::PublicController < Api::BaseController def public_feed PublicFeed.new( current_account, - locale: content_locale, local: truthy_param?(:local), remote: truthy_param?(:remote), only_media: truthy_param?(:only_media) diff --git a/app/controllers/auth/omniauth_callbacks_controller.rb b/app/controllers/auth/omniauth_callbacks_controller.rb index f9cf6d655..3d7962de5 100644 --- a/app/controllers/auth/omniauth_callbacks_controller.rb +++ b/app/controllers/auth/omniauth_callbacks_controller.rb @@ -18,7 +18,8 @@ class Auth::OmniauthCallbacksController < Devise::OmniauthCallbacksController ) sign_in_and_redirect @user, event: :authentication - set_flash_message(:notice, :success, kind: Devise.omniauth_configs[provider].strategy.display_name.capitalize) if is_navigational_format? + label = Devise.omniauth_configs[provider]&.strategy&.display_name.presence || I18n.t("auth.providers.#{provider}", default: provider.to_s.chomp('_oauth2').capitalize) + set_flash_message(:notice, :success, kind: label) if is_navigational_format? else session["devise.#{provider}_data"] = request.env['omniauth.auth'] redirect_to new_user_registration_url diff --git a/app/controllers/concerns/status_controller_concern.rb b/app/controllers/concerns/status_controller_concern.rb deleted file mode 100644 index 62a7cf508..000000000 --- a/app/controllers/concerns/status_controller_concern.rb +++ /dev/null @@ -1,87 +0,0 @@ -# frozen_string_literal: true - -module StatusControllerConcern - extend ActiveSupport::Concern - - ANCESTORS_LIMIT = 40 - DESCENDANTS_LIMIT = 60 - DESCENDANTS_DEPTH_LIMIT = 20 - - def create_descendant_thread(starting_depth, statuses) - depth = starting_depth + statuses.size - - if depth < DESCENDANTS_DEPTH_LIMIT - { - statuses: statuses, - starting_depth: starting_depth, - } - else - next_status = statuses.pop - - { - statuses: statuses, - starting_depth: starting_depth, - next_status: next_status, - } - end - end - - def set_ancestors - @ancestors = @status.reply? ? cache_collection(@status.ancestors(ANCESTORS_LIMIT, current_account), Status) : [] - @next_ancestor = @ancestors.size < ANCESTORS_LIMIT ? nil : @ancestors.shift - end - - def set_descendants - @max_descendant_thread_id = params[:max_descendant_thread_id]&.to_i - @since_descendant_thread_id = params[:since_descendant_thread_id]&.to_i - - descendants = cache_collection( - @status.descendants( - DESCENDANTS_LIMIT, - current_account, - @max_descendant_thread_id, - @since_descendant_thread_id, - DESCENDANTS_DEPTH_LIMIT - ), - Status - ) - - @descendant_threads = [] - - if descendants.present? - statuses = [descendants.first] - starting_depth = 0 - - descendants.drop(1).each_with_index do |descendant, index| - if descendants[index].id == descendant.in_reply_to_id - statuses << descendant - else - @descendant_threads << create_descendant_thread(starting_depth, statuses) - - # The thread is broken, assume it's a reply to the root status - starting_depth = 0 - - # ... unless we can find its ancestor in one of the already-processed threads - @descendant_threads.reverse_each do |descendant_thread| - statuses = descendant_thread[:statuses] - - index = statuses.find_index do |thread_status| - thread_status.id == descendant.in_reply_to_id - end - - if index.present? - starting_depth = descendant_thread[:starting_depth] + index + 1 - break - end - end - - statuses = [descendant] - end - end - - @descendant_threads << create_descendant_thread(starting_depth, statuses) - end - - @max_descendant_thread_id = @descendant_threads.pop[:statuses].first.id if descendants.size >= DESCENDANTS_LIMIT - end -end diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb index bb4e5b01f..9eb7ad691 100644 --- a/app/controllers/statuses_controller.rb +++ b/app/controllers/statuses_controller.rb @@ -2,7 +2,6 @@ class StatusesController < ApplicationController include WebAppControllerConcern - include StatusControllerConcern include SignatureAuthentication include Authorization include AccountOwnedConcern diff --git a/app/helpers/languages_helper.rb b/app/helpers/languages_helper.rb index e5bae2c6b..fff073ced 100644 --- a/app/helpers/languages_helper.rb +++ b/app/helpers/languages_helper.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true +# rubocop:disable Metrics/ModuleLength, Style/WordArray module LanguagesHelper ISO_639_1 = { @@ -189,8 +190,14 @@ module LanguagesHelper ISO_639_3 = { ast: ['Asturian', 'Asturianu'].freeze, ckb: ['Sorani (Kurdish)', 'سۆرانی'].freeze, + jbo: ['Lojban', 'la .lojban.'].freeze, kab: ['Kabyle', 'Taqbaylit'].freeze, kmr: ['Kurmanji (Kurdish)', 'Kurmancî'].freeze, + ldn: ['Láadan', 'Láadan'].freeze, + lfn: ['Lingua Franca Nova', 'lingua franca nova'].freeze, + sco: ['Scots', 'Scots'].freeze, + tok: ['Toki Pona', 'toki pona'].freeze, + zba: ['Balaibalan', 'باليبلن'].freeze, zgh: ['Standard Moroccan Tamazight', 'ⵜⴰⵎⴰⵣⵉⵖⵜ'].freeze, }.freeze @@ -259,3 +266,5 @@ module LanguagesHelper locale_name.to_sym if locale_name.present? && I18n.available_locales.include?(locale_name.to_sym) end end + +# rubocop:enable Metrics/ModuleLength, Style/WordArray diff --git a/app/javascript/images/logo_full.svg b/app/javascript/images/logo_full.svg new file mode 100644 index 000000000..03bcf93e3 --- /dev/null +++ b/app/javascript/images/logo_full.svg @@ -0,0 +1 @@ + diff --git a/app/javascript/images/logo_transparent.svg b/app/javascript/images/logo_transparent.svg new file mode 100644 index 000000000..a1e7b403e --- /dev/null +++ b/app/javascript/images/logo_transparent.svg @@ -0,0 +1 @@ + diff --git a/app/javascript/mastodon/components/animated_number.js b/app/javascript/mastodon/components/animated_number.js index fbe948c5b..b1aebc73e 100644 --- a/app/javascript/mastodon/components/animated_number.js +++ b/app/javascript/mastodon/components/animated_number.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { FormattedNumber } from 'react-intl'; +import ShortNumber from 'mastodon/components/short_number'; import TransitionMotion from 'react-motion/lib/TransitionMotion'; import spring from 'react-motion/lib/spring'; import { reduceMotion } from 'mastodon/initial_state'; @@ -51,7 +51,7 @@ export default class AnimatedNumber extends React.PureComponent { const { direction } = this.state; if (reduceMotion) { - return obfuscate ? obfuscatedCount(value) : ; + return obfuscate ? obfuscatedCount(value) : ; } const styles = [{ @@ -65,7 +65,7 @@ export default class AnimatedNumber extends React.PureComponent { {items => ( {items.map(({ key, data, style }) => ( - 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)` }}>{obfuscate ? obfuscatedCount(data) : } + 0 ? 'absolute' : 'static', transform: `translateY(${style.y * 100}%)` }}>{obfuscate ? obfuscatedCount(data) : } ))} )} diff --git a/app/javascript/mastodon/components/column_header.js b/app/javascript/mastodon/components/column_header.js index 5b2e16627..7850a93ec 100644 --- a/app/javascript/mastodon/components/column_header.js +++ b/app/javascript/mastodon/components/column_header.js @@ -57,7 +57,7 @@ class ColumnHeader extends React.PureComponent { } handleTitleClick = () => { - this.props.onClick(); + this.props.onClick?.(); } handleMoveLeft = () => { @@ -152,7 +152,6 @@ class ColumnHeader extends React.PureComponent { className={collapsibleButtonClassName} title={formatMessage(collapsed ? messages.show : messages.hide)} aria-label={formatMessage(collapsed ? messages.show : messages.hide)} - aria-pressed={collapsed ? 'false' : 'true'} onClick={this.handleToggleClick} > diff --git a/app/javascript/mastodon/components/icon_button.js b/app/javascript/mastodon/components/icon_button.js index 8fd9e10c0..49858f2e2 100644 --- a/app/javascript/mastodon/components/icon_button.js +++ b/app/javascript/mastodon/components/icon_button.js @@ -16,7 +16,6 @@ export default class IconButton extends React.PureComponent { onKeyPress: PropTypes.func, size: PropTypes.number, active: PropTypes.bool, - pressed: PropTypes.bool, expanded: PropTypes.bool, style: PropTypes.object, activeStyle: PropTypes.object, @@ -98,7 +97,6 @@ export default class IconButton extends React.PureComponent { icon, inverted, overlay, - pressed, tabIndex, title, counter, @@ -143,7 +141,6 @@ export default class IconButton extends React.PureComponent { +

{mentionsPlaceholder} diff --git a/app/javascript/mastodon/containers/timeline_container.js b/app/javascript/mastodon/containers/timeline_container.js deleted file mode 100644 index ed8095f90..000000000 --- a/app/javascript/mastodon/containers/timeline_container.js +++ /dev/null @@ -1,62 +0,0 @@ -import React, { Fragment } from 'react'; -import ReactDOM from 'react-dom'; -import { Provider } from 'react-redux'; -import PropTypes from 'prop-types'; -import configureStore from '../store/configureStore'; -import { hydrateStore } from '../actions/store'; -import { IntlProvider, addLocaleData } from 'react-intl'; -import { getLocale } from '../locales'; -import PublicTimeline from '../features/standalone/public_timeline'; -import HashtagTimeline from '../features/standalone/hashtag_timeline'; -import ModalContainer from '../features/ui/containers/modal_container'; -import initialState from '../initial_state'; - -const { localeData, messages } = getLocale(); -addLocaleData(localeData); - -const store = configureStore(); - -if (initialState) { - store.dispatch(hydrateStore(initialState)); -} - -export default class TimelineContainer extends React.PureComponent { - - static propTypes = { - locale: PropTypes.string.isRequired, - hashtag: PropTypes.string, - local: PropTypes.bool, - }; - - static defaultProps = { - local: !initialState.settings.known_fediverse, - }; - - render () { - const { locale, hashtag, local } = this.props; - - let timeline; - - if (hashtag) { - timeline = ; - } else { - timeline = ; - } - - return ( - - - - {timeline} - - {ReactDOM.createPortal( - , - document.getElementById('modal-container'), - )} - - - - ); - } - -} diff --git a/app/javascript/mastodon/features/about/index.js b/app/javascript/mastodon/features/about/index.js index 832836272..15d017642 100644 --- a/app/javascript/mastodon/features/about/index.js +++ b/app/javascript/mastodon/features/about/index.js @@ -183,25 +183,18 @@ class About extends React.PureComponent { <>

- - - - - - - - +
+ {domainBlocks.get('items').map(block => ( +
+
+
{block.get('domain')}
+ {intl.formatMessage(severityMessages[block.get('severity')].title)} +
-
- {domainBlocks.get('items').map(block => ( - - - - - - ))} - -
{block.get('domain')}{intl.formatMessage(severityMessages[block.get('severity')].title)}{block.get('comment')}
+

{block.get('comment').length > 0 ? block.get('comment') : }

+ + ))} + ) : (

diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js index 8d3b3c5e6..c38eea55b 100644 --- a/app/javascript/mastodon/features/account/components/header.js +++ b/app/javascript/mastodon/features/account/components/header.js @@ -53,6 +53,7 @@ const messages = defineMessages({ add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' }, admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' }, languages: { id: 'account.languages', defaultMessage: 'Change subscribed languages' }, + openOriginalPage: { id: 'account.open_original_page', defaultMessage: 'Open original page' }, }); const titleFromAccount = account => { @@ -97,6 +98,7 @@ class Header extends ImmutablePureComponent { onEditAccountNote: PropTypes.func.isRequired, onChangeLanguages: PropTypes.func.isRequired, onInteractionModal: PropTypes.func.isRequired, + onOpenAvatar: PropTypes.func.isRequired, intl: PropTypes.object.isRequired, domain: PropTypes.string.isRequired, hidden: PropTypes.bool, @@ -140,6 +142,13 @@ class Header extends ImmutablePureComponent { } } + handleAvatarClick = e => { + if (e.button === 0 && !(e.ctrlKey || e.metaKey)) { + e.preventDefault(); + this.props.onOpenAvatar(); + } + } + render () { const { account, hidden, intl, domain } = this.props; const { signedIn } = this.context.identity; @@ -148,7 +157,9 @@ class Header extends ImmutablePureComponent { return null; } - const suspended = account.get('suspended'); + const suspended = account.get('suspended'); + const isRemote = account.get('acct') !== account.get('username'); + const remoteDomain = isRemote ? account.get('acct').split('@')[1] : null; let info = []; let actionBtn = ''; @@ -200,6 +211,11 @@ class Header extends ImmutablePureComponent { menu.push(null); } + if (isRemote) { + menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: account.get('url') }); + menu.push(null); + } + if ('share' in navigator) { menu.push({ text: intl.formatMessage(messages.share, { name: account.get('username') }), action: this.handleShare }); menu.push(null); @@ -250,15 +266,13 @@ class Header extends ImmutablePureComponent { menu.push({ text: intl.formatMessage(messages.report, { name: account.get('username') }), action: this.props.onReport }); } - if (signedIn && account.get('acct') !== account.get('username')) { - const domain = account.get('acct').split('@')[1]; - + if (signedIn && isRemote) { menu.push(null); if (account.getIn(['relationship', 'domain_blocking'])) { - menu.push({ text: intl.formatMessage(messages.unblockDomain, { domain }), action: this.props.onUnblockDomain }); + menu.push({ text: intl.formatMessage(messages.unblockDomain, { domain: remoteDomain }), action: this.props.onUnblockDomain }); } else { - menu.push({ text: intl.formatMessage(messages.blockDomain, { domain }), action: this.props.onBlockDomain }); + menu.push({ text: intl.formatMessage(messages.blockDomain, { domain: remoteDomain }), action: this.props.onBlockDomain }); } } @@ -296,7 +310,7 @@ class Header extends ImmutablePureComponent {
- + diff --git a/app/javascript/mastodon/features/account_timeline/components/header.js b/app/javascript/mastodon/features/account_timeline/components/header.js index f31848f41..d67e307ff 100644 --- a/app/javascript/mastodon/features/account_timeline/components/header.js +++ b/app/javascript/mastodon/features/account_timeline/components/header.js @@ -24,6 +24,7 @@ export default class Header extends ImmutablePureComponent { onAddToList: PropTypes.func.isRequired, onChangeLanguages: PropTypes.func.isRequired, onInteractionModal: PropTypes.func.isRequired, + onOpenAvatar: PropTypes.func.isRequired, hideTabs: PropTypes.bool, domain: PropTypes.string.isRequired, hidden: PropTypes.bool, @@ -101,6 +102,10 @@ export default class Header extends ImmutablePureComponent { this.props.onInteractionModal(this.props.account); } + handleOpenAvatar = () => { + this.props.onOpenAvatar(this.props.account); + } + render () { const { account, hidden, hideTabs } = this.props; @@ -129,6 +134,7 @@ export default class Header extends ImmutablePureComponent { onEditAccountNote={this.handleEditAccountNote} onChangeLanguages={this.handleChangeLanguages} onInteractionModal={this.handleInteractionModal} + onOpenAvatar={this.handleOpenAvatar} domain={this.props.domain} hidden={hidden} /> diff --git a/app/javascript/mastodon/features/account_timeline/containers/header_container.js b/app/javascript/mastodon/features/account_timeline/containers/header_container.js index 1d09cd1ef..f53cd2480 100644 --- a/app/javascript/mastodon/features/account_timeline/containers/header_container.js +++ b/app/javascript/mastodon/features/account_timeline/containers/header_container.js @@ -152,6 +152,13 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ })); }, + onOpenAvatar (account) { + dispatch(openModal('IMAGE', { + src: account.get('avatar'), + alt: account.get('acct'), + })); + }, + }); export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Header)); diff --git a/app/javascript/mastodon/features/compose/components/language_dropdown.js b/app/javascript/mastodon/features/compose/components/language_dropdown.js index e48fa60ff..bf56fd0fa 100644 --- a/app/javascript/mastodon/features/compose/components/language_dropdown.js +++ b/app/javascript/mastodon/features/compose/components/language_dropdown.js @@ -51,6 +51,15 @@ class LanguageDropdownMenu extends React.PureComponent { document.addEventListener('click', this.handleDocumentClick, false); document.addEventListener('touchend', this.handleDocumentClick, listenerOptions); this.setState({ mounted: true }); + + // Because of https://github.com/react-bootstrap/react-bootstrap/issues/2614 we need + // to wait for a frame before focusing + requestAnimationFrame(() => { + if (this.node) { + const element = this.node.querySelector('input[type="search"]'); + if (element) element.focus(); + } + }); } componentWillUnmount () { @@ -226,7 +235,7 @@ class LanguageDropdownMenu extends React.PureComponent { // react-overlays
- +
diff --git a/app/javascript/mastodon/features/compose/components/upload.js b/app/javascript/mastodon/features/compose/components/upload.js index 0b2dcf08f..97ac54da9 100644 --- a/app/javascript/mastodon/features/compose/components/upload.js +++ b/app/javascript/mastodon/features/compose/components/upload.js @@ -47,7 +47,7 @@ export default class Upload extends ImmutablePureComponent { {!isEditingStatus && ()}
- {(media.get('description') || '').length === 0 && ( + {(media.get('description') || '').length === 0 && !isEditingStatus && (
diff --git a/app/javascript/mastodon/features/hashtag_timeline/index.js b/app/javascript/mastodon/features/hashtag_timeline/index.js index ec524be8f..b635c3529 100644 --- a/app/javascript/mastodon/features/hashtag_timeline/index.js +++ b/app/javascript/mastodon/features/hashtag_timeline/index.js @@ -194,7 +194,7 @@ class HashtagTimeline extends React.PureComponent { const following = tag.get('following'); followButton = ( - ); diff --git a/app/javascript/mastodon/features/home_timeline/index.js b/app/javascript/mastodon/features/home_timeline/index.js index 749a47e76..ae11ccbe4 100644 --- a/app/javascript/mastodon/features/home_timeline/index.js +++ b/app/javascript/mastodon/features/home_timeline/index.js @@ -130,7 +130,6 @@ class HomeTimeline extends React.PureComponent { className={classNames('column-header__button', { 'active': showAnnouncements })} title={intl.formatMessage(showAnnouncements ? messages.hide_announcements : messages.show_announcements)} aria-label={intl.formatMessage(showAnnouncements ? messages.hide_announcements : messages.show_announcements)} - aria-pressed={showAnnouncements ? 'true' : 'false'} onClick={this.handleToggleAnnouncementsClick} > diff --git a/app/javascript/mastodon/features/interaction_modal/index.js b/app/javascript/mastodon/features/interaction_modal/index.js index 9f7747903..d4535378f 100644 --- a/app/javascript/mastodon/features/interaction_modal/index.js +++ b/app/javascript/mastodon/features/interaction_modal/index.js @@ -150,7 +150,7 @@ class InteractionModal extends React.PureComponent {

-

+

diff --git a/app/javascript/mastodon/features/notifications/components/column_settings.js b/app/javascript/mastodon/features/notifications/components/column_settings.js index d75fa8a02..a38f8d3c2 100644 --- a/app/javascript/mastodon/features/notifications/components/column_settings.js +++ b/app/javascript/mastodon/features/notifications/components/column_settings.js @@ -21,7 +21,7 @@ export default class ColumnSettings extends React.PureComponent { onRequestNotificationPermission: PropTypes.func, alertsEnabled: PropTypes.bool, browserSupport: PropTypes.bool, - browserPermission: PropTypes.bool, + browserPermission: PropTypes.string, }; onPushChange = (path, checked) => { diff --git a/app/javascript/mastodon/features/picture_in_picture/components/footer.js b/app/javascript/mastodon/features/picture_in_picture/components/footer.js index 0beb2e14d..5b875dc30 100644 --- a/app/javascript/mastodon/features/picture_in_picture/components/footer.js +++ b/app/javascript/mastodon/features/picture_in_picture/components/footer.js @@ -182,8 +182,8 @@ class Footer extends ImmutablePureComponent { return (
- - + + {withOpenButton && }
); diff --git a/app/javascript/mastodon/features/status/components/action_bar.js b/app/javascript/mastodon/features/status/components/action_bar.js index fc82aa9c2..c1242754c 100644 --- a/app/javascript/mastodon/features/status/components/action_bar.js +++ b/app/javascript/mastodon/features/status/components/action_bar.js @@ -39,6 +39,7 @@ const messages = defineMessages({ unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' }, unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' }, unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, + openOriginalPage: { id: 'account.open_original_page', defaultMessage: 'Open original page' }, }); const mapStateToProps = (state, { status }) => ({ @@ -174,22 +175,8 @@ class ActionBar extends React.PureComponent { } handleCopy = () => { - const url = this.props.status.get('url'); - const textarea = document.createElement('textarea'); - - textarea.textContent = url; - textarea.style.position = 'fixed'; - - document.body.appendChild(textarea); - - try { - textarea.select(); - document.execCommand('copy'); - } catch (e) { - - } finally { - document.body.removeChild(textarea); - } + const url = this.props.status.get('url'); + navigator.clipboard.writeText(url); } render () { @@ -201,10 +188,15 @@ class ActionBar extends React.PureComponent { const mutingConversation = status.get('muted'); const account = status.get('account'); const writtenByMe = status.getIn(['account', 'id']) === me; + const isRemote = status.getIn(['account', 'username']) !== status.getIn(['account', 'acct']); let menu = []; if (publicStatus) { + if (isRemote) { + menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: status.get('url') }); + } + menu.push({ text: intl.formatMessage(messages.copy), action: this.handleCopy }); menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed }); menu.push(null); diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js index c0ba1f2d6..cb67944c9 100644 --- a/app/javascript/mastodon/features/status/index.js +++ b/app/javascript/mastodon/features/status/index.js @@ -619,7 +619,7 @@ class Status extends ImmutablePureComponent { showBackButton multiColumn={multiColumn} extraButton={( - + )} /> diff --git a/app/javascript/mastodon/features/ui/components/focal_point_modal.js b/app/javascript/mastodon/features/ui/components/focal_point_modal.js index a2e6b3d16..ba8aa8f03 100644 --- a/app/javascript/mastodon/features/ui/components/focal_point_modal.js +++ b/app/javascript/mastodon/features/ui/components/focal_point_modal.js @@ -176,14 +176,14 @@ class FocalPointModal extends ImmutablePureComponent { handleKeyDown = (e) => { if (e.keyCode === 13 && (e.ctrlKey || e.metaKey)) { - e.preventDefault(); - e.stopPropagation(); this.props.onChangeDescription(e.target.value); - this.handleSubmit(); + this.handleSubmit(e); } } - handleSubmit = () => { + handleSubmit = (e) => { + e.preventDefault(); + e.stopPropagation(); this.props.onSave(this.props.description, this.props.focusX, this.props.focusY); } @@ -313,7 +313,7 @@ class FocalPointModal extends ImmutablePureComponent {
-
+
{focals &&

} {thumbnailable && ( @@ -361,12 +361,23 @@ class FocalPointModal extends ImmutablePureComponent {
- +
-
+