From c1b823368c894c80b586d37c85012ee766a32c0e Mon Sep 17 00:00:00 2001 From: emilweth <7402764+emilweth@users.noreply.github.com> Date: Sat, 11 Feb 2023 02:15:07 +0100 Subject: [PATCH 01/28] dot is not allowed (#23519) --- streaming/index.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/streaming/index.js b/streaming/index.js index a8708ec78b..1121c77bf3 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -856,15 +856,15 @@ const startWorker = async (workerId) => { res.write('# TYPE connected_channels gauge\n'); res.write('# HELP connected_channels The number of Redis channels the streaming server is subscribed to\n'); res.write(`connected_channels ${Object.keys(subs).length}.0\n`); - res.write('# TYPE pg.pool.total_connections gauge \n'); - res.write('# HELP pg.pool.total_connections The total number of clients existing within the pool\n'); - res.write(`pg.pool.total_connections ${pgPool.totalCount}.0\n`); - res.write('# TYPE pg.pool.idle_connections gauge \n'); - res.write('# HELP pg.pool.idle_connections The number of clients which are not checked out but are currently idle in the pool\n'); - res.write(`pg.pool.idle_connections ${pgPool.idleCount}.0\n`); - res.write('# TYPE pg.pool.waiting_queries gauge \n'); - res.write('# HELP pg.pool.waiting_queries The number of queued requests waiting on a client when all clients are checked out\n'); - res.write(`pg.pool.waiting_queries ${pgPool.waitingCount}.0\n`); + res.write('# TYPE pg_pool_total_connections gauge \n'); + res.write('# HELP pg_pool_total_connections The total number of clients existing within the pool\n'); + res.write(`pg_pool_total_connections ${pgPool.totalCount}.0\n`); + res.write('# TYPE pg_pool_idle_connections gauge \n'); + res.write('# HELP pg_pool_idle_connections The number of clients which are not checked out but are currently idle in the pool\n'); + res.write(`pg_pool_idle_connections ${pgPool.idleCount}.0\n`); + res.write('# TYPE pg_pool_waiting_queries gauge \n'); + res.write('# HELP pg_pool_waiting_queries The number of queued requests waiting on a client when all clients are checked out\n'); + res.write(`pg_pool_waiting_queries ${pgPool.waitingCount}.0\n`); res.write('# EOF\n'); res.end(); })); From 7c45145430d7f61c01de6a8c6a55b4c8588a67c4 Mon Sep 17 00:00:00 2001 From: emilweth <7402764+emilweth@users.noreply.github.com> Date: Sat, 11 Feb 2023 03:00:44 +0100 Subject: [PATCH 02/28] fix metrics format (#23520) --- streaming/index.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/streaming/index.js b/streaming/index.js index 1121c77bf3..32e3babaa4 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -856,13 +856,13 @@ const startWorker = async (workerId) => { res.write('# TYPE connected_channels gauge\n'); res.write('# HELP connected_channels The number of Redis channels the streaming server is subscribed to\n'); res.write(`connected_channels ${Object.keys(subs).length}.0\n`); - res.write('# TYPE pg_pool_total_connections gauge \n'); + res.write('# TYPE pg_pool_total_connections gauge\n'); res.write('# HELP pg_pool_total_connections The total number of clients existing within the pool\n'); res.write(`pg_pool_total_connections ${pgPool.totalCount}.0\n`); - res.write('# TYPE pg_pool_idle_connections gauge \n'); + res.write('# TYPE pg_pool_idle_connections gauge\n'); res.write('# HELP pg_pool_idle_connections The number of clients which are not checked out but are currently idle in the pool\n'); res.write(`pg_pool_idle_connections ${pgPool.idleCount}.0\n`); - res.write('# TYPE pg_pool_waiting_queries gauge \n'); + res.write('# TYPE pg_pool_waiting_queries gauge\n'); res.write('# HELP pg_pool_waiting_queries The number of queued requests waiting on a client when all clients are checked out\n'); res.write(`pg_pool_waiting_queries ${pgPool.waitingCount}.0\n`); res.write('# EOF\n'); From e7b81d7d9625893b1323e12215a2a98c0f19f58f Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 11 Feb 2023 04:02:07 +0100 Subject: [PATCH 03/28] Bump blurhash from 0.1.6 to 0.1.7 (#23517) --- Gemfile.lock | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 3bd2d591df..2d7ee2df89 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -120,8 +120,7 @@ GEM bindata (2.4.14) binding_of_caller (1.0.0) debug_inspector (>= 0.0.1) - blurhash (0.1.6) - ffi (~> 1.14) + blurhash (0.1.7) bootsnap (1.16.0) msgpack (~> 1.2) brakeman (5.4.0) From c812cfa667764ff3791fb5b5cd0dffc5ba2441da Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Sun, 12 Feb 2023 02:34:17 -0500 Subject: [PATCH 04/28] Enable EditorConfig trailing whitespace trimming (#23543) --- .editorconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/.editorconfig b/.editorconfig index 5f8702cf89..b5217da4af 100644 --- a/.editorconfig +++ b/.editorconfig @@ -10,3 +10,4 @@ insert_final_newline = true charset = utf-8 indent_style = space indent_size = 2 +trim_trailing_whitespace = true From 0c9d455ea5540e854c2d879cd1df015ea493f622 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Sun, 12 Feb 2023 22:57:03 -0500 Subject: [PATCH 05/28] Upgrade to Stylelint 15 with Prettier (#23558) --- .prettierignore | 3 + app/javascript/styles/fonts/roboto-mono.scss | 9 +- app/javascript/styles/fonts/roboto.scss | 24 ++-- .../styles/mastodon-light/diff.scss | 31 ++-- .../styles/mastodon/accessibility.scss | 5 +- app/javascript/styles/mastodon/admin.scss | 23 ++- app/javascript/styles/mastodon/basics.scss | 6 +- .../styles/mastodon/components.scss | 126 +++++++++++----- .../styles/mastodon/emoji_picker.scss | 2 +- app/javascript/styles/mastodon/forms.scss | 48 ++++--- app/javascript/styles/mastodon/modal.scss | 4 +- app/javascript/styles/mastodon/polls.scss | 10 +- app/javascript/styles/mastodon/rtl.scss | 18 ++- app/javascript/styles/mastodon/statuses.scss | 2 +- app/javascript/styles/mastodon/variables.scss | 31 ++-- app/javascript/styles/mastodon/widgets.scss | 2 +- lib/assets/wordmark.light.css | 4 +- package.json | 6 +- stylelint.config.js | 2 - yarn.lock | 134 +++++++++++------- 20 files changed, 311 insertions(+), 179 deletions(-) diff --git a/.prettierignore b/.prettierignore index f72354a42f..8279ac1a45 100644 --- a/.prettierignore +++ b/.prettierignore @@ -70,3 +70,6 @@ docker-compose.override.yml # Ignore locale files /app/javascript/mastodon/locales /config/locales + +# Ignore vendored CSS reset +app/javascript/styles/mastodon/reset.scss diff --git a/app/javascript/styles/fonts/roboto-mono.scss b/app/javascript/styles/fonts/roboto-mono.scss index 3802212a9b..10dd630099 100644 --- a/app/javascript/styles/fonts/roboto-mono.scss +++ b/app/javascript/styles/fonts/roboto-mono.scss @@ -1,11 +1,12 @@ @font-face { font-family: mastodon-font-monospace; - src: - local('Roboto Mono'), + src: local('Roboto Mono'), url('../fonts/roboto-mono/robotomono-regular-webfont.woff2') format('woff2'), url('../fonts/roboto-mono/robotomono-regular-webfont.woff') format('woff'), - url('../fonts/roboto-mono/robotomono-regular-webfont.ttf') format('truetype'), - url('../fonts/roboto-mono/robotomono-regular-webfont.svg#roboto_monoregular') format('svg'); + url('../fonts/roboto-mono/robotomono-regular-webfont.ttf') + format('truetype'), + url('../fonts/roboto-mono/robotomono-regular-webfont.svg#roboto_monoregular') + format('svg'); font-weight: 400; font-display: swap; font-style: normal; diff --git a/app/javascript/styles/fonts/roboto.scss b/app/javascript/styles/fonts/roboto.scss index 6571523807..672eab086c 100644 --- a/app/javascript/styles/fonts/roboto.scss +++ b/app/javascript/styles/fonts/roboto.scss @@ -1,11 +1,11 @@ @font-face { font-family: mastodon-font-sans-serif; - src: - local('Roboto Italic'), + src: local('Roboto Italic'), url('../fonts/roboto/roboto-italic-webfont.woff2') format('woff2'), url('../fonts/roboto/roboto-italic-webfont.woff') format('woff'), url('../fonts/roboto/roboto-italic-webfont.ttf') format('truetype'), - url('../fonts/roboto/roboto-italic-webfont.svg#roboto-italic-webfont') format('svg'); + url('../fonts/roboto/roboto-italic-webfont.svg#roboto-italic-webfont') + format('svg'); font-weight: normal; font-display: swap; font-style: italic; @@ -13,12 +13,12 @@ @font-face { font-family: mastodon-font-sans-serif; - src: - local('Roboto Bold'), + src: local('Roboto Bold'), url('../fonts/roboto/roboto-bold-webfont.woff2') format('woff2'), url('../fonts/roboto/roboto-bold-webfont.woff') format('woff'), url('../fonts/roboto/roboto-bold-webfont.ttf') format('truetype'), - url('../fonts/roboto/roboto-bold-webfont.svg#roboto-bold-webfont') format('svg'); + url('../fonts/roboto/roboto-bold-webfont.svg#roboto-bold-webfont') + format('svg'); font-weight: bold; font-display: swap; font-style: normal; @@ -26,12 +26,12 @@ @font-face { font-family: mastodon-font-sans-serif; - src: - local('Roboto Medium'), + src: local('Roboto Medium'), url('../fonts/roboto/roboto-medium-webfont.woff2') format('woff2'), url('../fonts/roboto/roboto-medium-webfont.woff') format('woff'), url('../fonts/roboto/roboto-medium-webfont.ttf') format('truetype'), - url('../fonts/roboto/roboto-medium-webfont.svg#roboto-medium-webfont') format('svg'); + url('../fonts/roboto/roboto-medium-webfont.svg#roboto-medium-webfont') + format('svg'); font-weight: 500; font-display: swap; font-style: normal; @@ -39,12 +39,12 @@ @font-face { font-family: mastodon-font-sans-serif; - src: - local('Roboto'), + src: local('Roboto'), url('../fonts/roboto/roboto-regular-webfont.woff2') format('woff2'), url('../fonts/roboto/roboto-regular-webfont.woff') format('woff'), url('../fonts/roboto/roboto-regular-webfont.ttf') format('truetype'), - url('../fonts/roboto/roboto-regular-webfont.svg#roboto-regular-webfont') format('svg'); + url('../fonts/roboto/roboto-regular-webfont.svg#roboto-regular-webfont') + format('svg'); font-weight: normal; font-display: swap; font-style: normal; diff --git a/app/javascript/styles/mastodon-light/diff.scss b/app/javascript/styles/mastodon-light/diff.scss index c37100a28f..01725cf968 100644 --- a/app/javascript/styles/mastodon-light/diff.scss +++ b/app/javascript/styles/mastodon-light/diff.scss @@ -152,7 +152,7 @@ html { } .compose-form__autosuggest-wrapper, -.poll__option input[type="text"], +.poll__option input[type='text'], .compose-form .spoiler-input__input, .compose-form__poll-wrapper select, .search__input, @@ -179,7 +179,9 @@ html { } .compose-form__poll-wrapper select { - background: $simple-background-color url("data:image/svg+xml;utf8,") no-repeat right 8px center / auto 16px; + background: $simple-background-color + url("data:image/svg+xml;utf8,") + no-repeat right 8px center / auto 16px; } .compose-form__poll-wrapper, @@ -205,7 +207,9 @@ html { } .drawer__inner__mastodon { - background: $white url('data:image/svg+xml;utf8,') no-repeat bottom / 100% auto; + background: $white + url('data:image/svg+xml;utf8,') + no-repeat bottom / 100% auto; } // Change the colors used in compose-form @@ -332,11 +336,13 @@ html { color: $white; } -.language-dropdown__dropdown__results__item .language-dropdown__dropdown__results__item__common-name { +.language-dropdown__dropdown__results__item + .language-dropdown__dropdown__results__item__common-name { color: lighten($ui-base-color, 8%); } -.language-dropdown__dropdown__results__item.active .language-dropdown__dropdown__results__item__common-name { +.language-dropdown__dropdown__results__item.active + .language-dropdown__dropdown__results__item__common-name { color: darken($ui-base-color, 12%); } @@ -490,7 +496,8 @@ html { background: darken($ui-secondary-color, 10%); } -.react-toggle.react-toggle--checked:hover:not(.react-toggle--disabled) .react-toggle-track { +.react-toggle.react-toggle--checked:hover:not(.react-toggle--disabled) + .react-toggle-track { background: lighten($ui-highlight-color, 10%); } @@ -522,10 +529,10 @@ html { } .simple_form { - input[type="text"], - input[type="number"], - input[type="email"], - input[type="password"], + input[type='text'], + input[type='number'], + input[type='email'], + input[type='password'], textarea { &:hover { border-color: lighten($ui-base-color, 12%); @@ -682,5 +689,7 @@ html { .mute-modal select { border: 1px solid lighten($ui-base-color, 8%); - background: $simple-background-color url("data:image/svg+xml;utf8,") no-repeat right 8px center / auto 16px; + background: $simple-background-color + url("data:image/svg+xml;utf8,") + no-repeat right 8px center / auto 16px; } diff --git a/app/javascript/styles/mastodon/accessibility.scss b/app/javascript/styles/mastodon/accessibility.scss index c5bcb59418..deaa0afdac 100644 --- a/app/javascript/styles/mastodon/accessibility.scss +++ b/app/javascript/styles/mastodon/accessibility.scss @@ -1,4 +1,7 @@ -$emojis-requiring-inversion: 'back' 'copyright' 'curly_loop' 'currency_exchange' 'end' 'heavy_check_mark' 'heavy_division_sign' 'heavy_dollar_sign' 'heavy_minus_sign' 'heavy_multiplication_x' 'heavy_plus_sign' 'on' 'registered' 'soon' 'spider' 'telephone_receiver' 'tm' 'top' 'wavy_dash' !default; +$emojis-requiring-inversion: 'back' 'copyright' 'curly_loop' 'currency_exchange' + 'end' 'heavy_check_mark' 'heavy_division_sign' 'heavy_dollar_sign' + 'heavy_minus_sign' 'heavy_multiplication_x' 'heavy_plus_sign' 'on' + 'registered' 'soon' 'spider' 'telephone_receiver' 'tm' 'top' 'wavy_dash' !default; %emoji-color-inversion { filter: invert(1); diff --git a/app/javascript/styles/mastodon/admin.scss b/app/javascript/styles/mastodon/admin.scss index 674fafbe95..d9e45fb102 100644 --- a/app/javascript/styles/mastodon/admin.scss +++ b/app/javascript/styles/mastodon/admin.scss @@ -1,4 +1,4 @@ -@use "sass:math"; +@use 'sass:math'; $no-columns-breakpoint: 600px; $sidebar-width: 240px; @@ -1131,7 +1131,10 @@ a.name-tag, @for $i from 0 through 10 { &--#{10 * $i} { - background-color: rgba($ui-highlight-color, 1 * (math.div(max(1, $i), 10))); + background-color: rgba( + $ui-highlight-color, + 1 * (math.div(max(1, $i), 10)) + ); } } } @@ -1220,7 +1223,12 @@ a.sparkline { .skeleton { background-color: lighten($ui-base-color, 8%); - background-image: linear-gradient(90deg, lighten($ui-base-color, 8%), lighten($ui-base-color, 12%), lighten($ui-base-color, 8%)); + background-image: linear-gradient( + 90deg, + lighten($ui-base-color, 8%), + lighten($ui-base-color, 12%), + lighten($ui-base-color, 8%) + ); background-size: 200px 100%; background-repeat: no-repeat; border-radius: 4px; @@ -1269,7 +1277,10 @@ a.sparkline { @for $i from 0 through 10 { &--#{10 * $i} { - background-color: rgba($ui-highlight-color, 1 * (math.div(max(1, $i), 10))); + background-color: rgba( + $ui-highlight-color, + 1 * (math.div(max(1, $i), 10)) + ); } } } @@ -1415,7 +1426,7 @@ a.sparkline { &::after { display: block; - content: ""; + content: ''; width: 50px; height: 21px; position: absolute; @@ -1809,7 +1820,7 @@ a.sparkline { &::after { position: absolute; - content: ""; + content: ''; width: 1px; background: $highlight-text-color; bottom: 0; diff --git a/app/javascript/styles/mastodon/basics.scss b/app/javascript/styles/mastodon/basics.scss index 413a1cdd6a..1d08b12e57 100644 --- a/app/javascript/styles/mastodon/basics.scss +++ b/app/javascript/styles/mastodon/basics.scss @@ -14,7 +14,7 @@ body { font-weight: 400; color: $primary-text-color; text-rendering: optimizelegibility; - font-feature-settings: "kern"; + font-feature-settings: 'kern'; text-size-adjust: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0%); -webkit-tap-highlight-color: transparent; @@ -31,7 +31,9 @@ body { // Droid Sans => Older Androids (<4.0) // Helvetica Neue => Older macOS <10.11 // $font-sans-serif => web-font (Roboto) fallback and newer Androids (>=4.0) - font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", $font-sans-serif, sans-serif; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', + Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + $font-sans-serif, sans-serif; } &.app-body { diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss index 493efea305..11c28dbc13 100644 --- a/app/javascript/styles/mastodon/components.scss +++ b/app/javascript/styles/mastodon/components.scss @@ -387,7 +387,7 @@ body > [data-popper-placement] { .ellipsis { &::after { - content: "…"; + content: '…'; } } @@ -404,7 +404,7 @@ body > [data-popper-placement] { color: $highlight-text-color; } - input[type="checkbox"] { + input[type='checkbox'] { display: none; } @@ -423,7 +423,9 @@ body > [data-popper-placement] { &.active { border-color: $highlight-text-color; - background: $highlight-text-color url("data:image/svg+xml;utf8,") center center no-repeat; + background: $highlight-text-color + url("data:image/svg+xml;utf8,") + center center no-repeat; } } } @@ -647,7 +649,12 @@ body > [data-popper-placement] { margin: 5px; &__actions { - background: linear-gradient(180deg, rgba($base-shadow-color, 0.8) 0, rgba($base-shadow-color, 0.35) 80%, transparent); + background: linear-gradient( + 180deg, + rgba($base-shadow-color, 0.8) 0, + rgba($base-shadow-color, 0.35) 80%, + transparent + ); display: flex; align-items: flex-start; justify-content: space-between; @@ -675,7 +682,12 @@ body > [data-popper-placement] { left: 0; right: 0; box-sizing: border-box; - background: linear-gradient(0deg, rgba($base-shadow-color, 0.8) 0, rgba($base-shadow-color, 0.35) 80%, transparent); + background: linear-gradient( + 0deg, + rgba($base-shadow-color, 0.8) 0, + rgba($base-shadow-color, 0.35) 80%, + transparent + ); } } @@ -1080,8 +1092,13 @@ body > [data-popper-placement] { cursor: auto; @keyframes fade { - 0% { opacity: 0; } - 100% { opacity: 1; } + 0% { + opacity: 0; + } + + 100% { + opacity: 1; + } } opacity: 1; @@ -1827,11 +1844,11 @@ a.account__display-name { justify-content: center; flex-direction: column; scrollbar-width: none; /* Firefox */ - -ms-overflow-style: none; /* IE 10+ */ + -ms-overflow-style: none; /* IE 10+ */ * { scrollbar-width: none; /* Firefox */ - -ms-overflow-style: none; /* IE 10+ */ + -ms-overflow-style: none; /* IE 10+ */ } &::-webkit-scrollbar, @@ -2863,7 +2880,9 @@ $ui-header-height: 55px; } .drawer__inner__mastodon { - background: lighten($ui-base-color, 13%) url('data:image/svg+xml;utf8,') no-repeat bottom / 100% auto; + background: lighten($ui-base-color, 13%) + url('data:image/svg+xml;utf8,') + no-repeat bottom / 100% auto; flex: 1; min-height: 47px; display: none; @@ -2918,7 +2937,8 @@ $ui-header-height: 55px; overflow-y: auto; } - @supports (display: grid) { // hack to fix Chrome <57 + @supports (display: grid) { + // hack to fix Chrome <57 contain: strict; } @@ -2939,7 +2959,8 @@ $ui-header-height: 55px; } .scrollable.fullscreen { - @supports (display: grid) { // hack to fix Chrome <57 + @supports (display: grid) { + // hack to fix Chrome <57 contain: none; } } @@ -3043,7 +3064,8 @@ $ui-header-height: 55px; transition: background-color 0.2s ease; } -.react-toggle:is(:hover, :focus-within):not(.react-toggle--disabled) .react-toggle-track { +.react-toggle:is(:hover, :focus-within):not(.react-toggle--disabled) + .react-toggle-track { background-color: darken($ui-base-color, 10%); } @@ -3051,7 +3073,8 @@ $ui-header-height: 55px; background-color: darken($ui-highlight-color, 2%); } -.react-toggle--checked:is(:hover, :focus-within):not(.react-toggle--disabled) .react-toggle-track { +.react-toggle--checked:is(:hover, :focus-within):not(.react-toggle--disabled) + .react-toggle-track { background-color: $ui-highlight-color; } @@ -3646,7 +3669,7 @@ a.status-card.compact:hover { &::before { display: block; - content: ""; + content: ''; position: absolute; bottom: -13px; left: 0; @@ -3656,7 +3679,11 @@ a.status-card.compact:hover { pointer-events: none; height: 28px; z-index: 1; - background: radial-gradient(ellipse, rgba($ui-highlight-color, 0.23) 0%, rgba($ui-highlight-color, 0) 60%); + background: radial-gradient( + ellipse, + rgba($ui-highlight-color, 0.23) 0%, + rgba($ui-highlight-color, 0) 60% + ); } } @@ -4241,7 +4268,8 @@ a.status-card.compact:hover { align-items: center; justify-content: center; - @supports (display: grid) { // hack to fix Chrome <57 + @supports (display: grid) { + // hack to fix Chrome <57 contain: strict; } @@ -5747,7 +5775,9 @@ a.status-card.compact:hover { width: auto; outline: 0; font-family: inherit; - background: $simple-background-color url("data:image/svg+xml;utf8,") no-repeat right 8px center / auto 16px; + background: $simple-background-color + url("data:image/svg+xml;utf8,") + no-repeat right 8px center / auto 16px; border: 1px solid darken($simple-background-color, 14%); border-radius: 4px; padding: 6px 10px; @@ -6154,7 +6184,12 @@ a.status-card.compact:hover { left: 0; right: 0; box-sizing: border-box; - background: linear-gradient(0deg, rgba($base-shadow-color, 0.85) 0, rgba($base-shadow-color, 0.45) 60%, transparent); + background: linear-gradient( + 0deg, + rgba($base-shadow-color, 0.85) 0, + rgba($base-shadow-color, 0.45) 60%, + transparent + ); padding: 0 15px; opacity: 0; transition: opacity 0.1s ease; @@ -6295,7 +6330,7 @@ a.status-card.compact:hover { } &::before { - content: ""; + content: ''; width: 50px; background: rgba($white, 0.35); border-radius: 4px; @@ -6365,7 +6400,7 @@ a.status-card.compact:hover { position: relative; &::before { - content: ""; + content: ''; width: 100%; background: rgba($white, 0.35); border-radius: 4px; @@ -6448,7 +6483,11 @@ a.status-card.compact:hover { } .scrollable .account-card__bio::after { - background: linear-gradient(to left, lighten($ui-base-color, 8%), transparent); + background: linear-gradient( + to left, + lighten($ui-base-color, 8%), + transparent + ); } .account-gallery__container { @@ -6509,7 +6548,7 @@ a.status-card.compact:hover { &::before, &::after { display: block; - content: ""; + content: ''; position: absolute; bottom: 0; left: 50%; @@ -6575,8 +6614,8 @@ a.status-card.compact:hover { text-overflow: ellipsis; cursor: pointer; - input[type="radio"], - input[type="checkbox"] { + input[type='radio'], + input[type='checkbox'] { display: none; } @@ -6635,9 +6674,17 @@ noscript { } @keyframes flicker { - 0% { opacity: 1; } - 30% { opacity: 0.75; } - 100% { opacity: 1; } + 0% { + opacity: 1; + } + + 30% { + opacity: 0.75; + } + + 100% { + opacity: 1; + } } @media screen and (max-width: 630px) and (max-height: 400px) { @@ -6658,7 +6705,9 @@ noscript { .navigation-bar { & > a:first-child { will-change: margin-top, margin-left, margin-right, width; - transition: margin-top $duration $delay, margin-left $duration ($duration + $delay), margin-right $duration ($duration + $delay); + transition: margin-top $duration $delay, + margin-left $duration ($duration + $delay), + margin-right $duration ($duration + $delay); } & > .navigation-bar__profile-edit { @@ -6669,15 +6718,12 @@ noscript { .navigation-bar__actions { & > .icon-button.close { will-change: opacity transform; - transition: - opacity $duration * 0.5 $delay, - transform $duration $delay; + transition: opacity $duration * 0.5 $delay, transform $duration $delay; } & > .compose__action-bar .icon-button { will-change: opacity transform; - transition: - opacity $duration * 0.5 $delay + $duration * 0.5, + transition: opacity $duration * 0.5 $delay + $duration * 0.5, transform $duration $delay; } } @@ -7677,7 +7723,11 @@ noscript { &.active { transition: all 100ms ease-in; transition-property: background-color, color; - background-color: mix(lighten($ui-base-color, 12%), $ui-highlight-color, 80%); + background-color: mix( + lighten($ui-base-color, 12%), + $ui-highlight-color, + 80% + ); .reactions-bar__item__count { color: lighten($highlight-text-color, 8%); @@ -7730,7 +7780,7 @@ noscript { &.unread { &::before { - content: ""; + content: ''; position: absolute; top: 0; left: 0; @@ -8258,14 +8308,14 @@ noscript { counter-increment: list-counter; &::before { - content: counter(list-counter) "."; + content: counter(list-counter) '.'; position: absolute; left: 0; } } ul > li::before { - content: ""; + content: ''; position: absolute; background-color: $darker-text-color; border-radius: 50%; diff --git a/app/javascript/styles/mastodon/emoji_picker.scss b/app/javascript/styles/mastodon/emoji_picker.scss index 1042ddda89..0d7a7df2ee 100644 --- a/app/javascript/styles/mastodon/emoji_picker.scss +++ b/app/javascript/styles/mastodon/emoji_picker.scss @@ -174,7 +174,7 @@ &:hover::before { z-index: -1; - content: ""; + content: ''; position: absolute; top: 0; left: 0; diff --git a/app/javascript/styles/mastodon/forms.scss b/app/javascript/styles/mastodon/forms.scss index 1841dc8bfd..e4539deffe 100644 --- a/app/javascript/styles/mastodon/forms.scss +++ b/app/javascript/styles/mastodon/forms.scss @@ -299,7 +299,7 @@ code { max-width: 100%; height: auto; border-radius: 4px; - background: url("images/void.png"); + background: url('images/void.png'); &:last-child { margin-bottom: 0; @@ -384,7 +384,7 @@ code { flex: 1 1 auto; } - input[type="checkbox"] { + input[type='checkbox'] { position: absolute; left: 0; top: 5px; @@ -400,12 +400,12 @@ code { border-radius: 4px; } - input[type="text"], - input[type="number"], - input[type="email"], - input[type="password"], - input[type="url"], - input[type="datetime-local"], + input[type='text'], + input[type='number'], + input[type='email'], + input[type='password'], + input[type='url'], + input[type='datetime-local'], textarea { box-sizing: border-box; font-size: 16px; @@ -443,11 +443,11 @@ code { } } - input[type="text"], - input[type="number"], - input[type="email"], - input[type="password"], - input[type="datetime-local"] { + input[type='text'], + input[type='number'], + input[type='email'], + input[type='password'], + input[type='datetime-local'] { &:focus:invalid:not(:placeholder-shown), &:required:invalid:not(:placeholder-shown) { border-color: lighten($error-red, 12%); @@ -459,11 +459,11 @@ code { color: lighten($error-red, 12%); } - input[type="text"], - input[type="number"], - input[type="email"], - input[type="password"], - input[type="datetime-local"], + input[type='text'], + input[type='number'], + input[type='email'], + input[type='password'], + input[type='datetime-local'], textarea, select { border-color: lighten($error-red, 12%); @@ -567,7 +567,9 @@ code { outline: 0; font-family: inherit; resize: vertical; - background: darken($ui-base-color, 10%) url("data:image/svg+xml;utf8,") no-repeat right 8px center / auto 16px; + background: darken($ui-base-color, 10%) + url("data:image/svg+xml;utf8,") + no-repeat right 8px center / auto 16px; border: 1px solid darken($ui-base-color, 14%); border-radius: 4px; padding-left: 10px; @@ -607,7 +609,11 @@ code { right: 0; bottom: 1px; width: 5px; - background-image: linear-gradient(to right, rgba(darken($ui-base-color, 10%), 0), darken($ui-base-color, 10%)); + background-image: linear-gradient( + to right, + rgba(darken($ui-base-color, 10%), 0), + darken($ui-base-color, 10%) + ); } } } @@ -995,7 +1001,7 @@ code { flex: 1 1 auto; } - input[type="text"] { + input[type='text'] { background: transparent; border: 0; padding: 10px; diff --git a/app/javascript/styles/mastodon/modal.scss b/app/javascript/styles/mastodon/modal.scss index a333926dd1..6170877b22 100644 --- a/app/javascript/styles/mastodon/modal.scss +++ b/app/javascript/styles/mastodon/modal.scss @@ -1,5 +1,7 @@ .modal-layout { - background: $ui-base-color url('data:image/svg+xml;utf8,') repeat-x bottom fixed; + background: $ui-base-color + url('data:image/svg+xml;utf8,') + repeat-x bottom fixed; display: flex; flex-direction: column; height: 100vh; diff --git a/app/javascript/styles/mastodon/polls.scss b/app/javascript/styles/mastodon/polls.scss index 03d2cb4b2d..b30932e04c 100644 --- a/app/javascript/styles/mastodon/polls.scss +++ b/app/javascript/styles/mastodon/polls.scss @@ -64,8 +64,8 @@ max-width: calc(100% - 45px - 25px); } - input[type="radio"], - input[type="checkbox"] { + input[type='radio'], + input[type='checkbox'] { display: none; } @@ -73,7 +73,7 @@ flex: 1 1 auto; } - input[type="text"] { + input[type='text'] { display: block; box-sizing: border-box; width: 100%; @@ -263,7 +263,9 @@ width: auto; outline: 0; font-family: inherit; - background: $simple-background-color url("data:image/svg+xml;utf8,") no-repeat right 8px center / auto 16px; + background: $simple-background-color + url("data:image/svg+xml;utf8,") + no-repeat right 8px center / auto 16px; border: 1px solid darken($simple-background-color, 14%); border-radius: 4px; padding: 6px 10px; diff --git a/app/javascript/styles/mastodon/rtl.scss b/app/javascript/styles/mastodon/rtl.scss index 39f4653bbd..e60087dab0 100644 --- a/app/javascript/styles/mastodon/rtl.scss +++ b/app/javascript/styles/mastodon/rtl.scss @@ -229,8 +229,8 @@ body.rtl { padding-right: 0; } - .simple_form .check_boxes .checkbox input[type="checkbox"], - .simple_form .input.boolean input[type="checkbox"] { + .simple_form .check_boxes .checkbox input[type='checkbox'], + .simple_form .input.boolean input[type='checkbox'] { left: auto; right: 0; } @@ -268,12 +268,18 @@ body.rtl { &::after { right: auto; left: 0; - background-image: linear-gradient(to left, rgba(darken($ui-base-color, 10%), 0), darken($ui-base-color, 10%)); + background-image: linear-gradient( + to left, + rgba(darken($ui-base-color, 10%), 0), + darken($ui-base-color, 10%) + ); } } .simple_form select { - background: darken($ui-base-color, 10%) url("data:image/svg+xml;utf8,") no-repeat left 8px center / auto 16px; + background: darken($ui-base-color, 10%) + url("data:image/svg+xml;utf8,") + no-repeat left 8px center / auto 16px; } .table th, @@ -320,11 +326,11 @@ body.rtl { } .fa-chevron-left::before { - content: "\F054"; + content: '\F054'; } .fa-chevron-right::before { - content: "\F053"; + content: '\F053'; } .column-back-button__icon { diff --git a/app/javascript/styles/mastodon/statuses.scss b/app/javascript/styles/mastodon/statuses.scss index ce71d11e4e..a42f1f42c0 100644 --- a/app/javascript/styles/mastodon/statuses.scss +++ b/app/javascript/styles/mastodon/statuses.scss @@ -138,7 +138,7 @@ a.button.logo-button { } .embed { - .status__content[data-spoiler="folded"] { + .status__content[data-spoiler='folded'] { .e-content { display: none; } diff --git a/app/javascript/styles/mastodon/variables.scss b/app/javascript/styles/mastodon/variables.scss index 2f6c41d5f2..7de25f8fd4 100644 --- a/app/javascript/styles/mastodon/variables.scss +++ b/app/javascript/styles/mastodon/variables.scss @@ -1,18 +1,18 @@ // Commonly used web colors -$black: #000000; // Black -$white: #ffffff; // White -$success-green: #79bd9a !default; // Padua -$error-red: #df405a !default; // Cerise -$warning-red: #ff5050 !default; // Sunset Orange -$gold-star: #ca8f04 !default; // Dark Goldenrod +$black: #000000; // Black +$white: #ffffff; // White +$success-green: #79bd9a !default; // Padua +$error-red: #df405a !default; // Cerise +$warning-red: #ff5050 !default; // Sunset Orange +$gold-star: #ca8f04 !default; // Dark Goldenrod $red-bookmark: $warning-red; // Values from the classic Mastodon UI -$classic-base-color: #282c37; // Midnight Express -$classic-primary-color: #9baec8; // Echo Blue -$classic-secondary-color: #d9e1e8; // Pattens Blue -$classic-highlight-color: #6364ff; // Brand purple +$classic-base-color: #282c37; // Midnight Express +$classic-primary-color: #9baec8; // Echo Blue +$classic-secondary-color: #d9e1e8; // Pattens Blue +$classic-highlight-color: #6364ff; // Brand purple // Variables for defaults in UI $base-shadow-color: $black !default; @@ -23,10 +23,13 @@ $valid-value-color: $success-green !default; $error-value-color: $error-red !default; // Tell UI to use selected colors -$ui-base-color: $classic-base-color !default; // Darkest -$ui-base-lighter-color: lighten($ui-base-color, 26%) !default; // Lighter darkest -$ui-primary-color: $classic-primary-color !default; // Lighter -$ui-secondary-color: $classic-secondary-color !default; // Lightest +$ui-base-color: $classic-base-color !default; // Darkest +$ui-base-lighter-color: lighten( + $ui-base-color, + 26% +) !default; // Lighter darkest +$ui-primary-color: $classic-primary-color !default; // Lighter +$ui-secondary-color: $classic-secondary-color !default; // Lightest $ui-highlight-color: $classic-highlight-color !default; // Variables for texts diff --git a/app/javascript/styles/mastodon/widgets.scss b/app/javascript/styles/mastodon/widgets.scss index 7a25d121bb..ef7bfc6de4 100644 --- a/app/javascript/styles/mastodon/widgets.scss +++ b/app/javascript/styles/mastodon/widgets.scss @@ -1,4 +1,4 @@ -@use "sass:math"; +@use 'sass:math'; .hero-widget { margin-bottom: 10px; diff --git a/lib/assets/wordmark.light.css b/lib/assets/wordmark.light.css index 9a601f9725..b8c9993fd8 100644 --- a/lib/assets/wordmark.light.css +++ b/lib/assets/wordmark.light.css @@ -1 +1,3 @@ -use { color: #000 !important; } +use { + color: #000 !important; +} diff --git a/package.json b/package.json index 96f1e7b0e6..9fc84f01d8 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ "test": "${npm_execpath} run test:lint:js && ${npm_execpath} run test:jest", "test:lint": "${npm_execpath} run test:lint:js && ${npm_execpath} run test:lint:sass", "test:lint:js": "eslint --ext=js . --cache --report-unused-disable-directives", - "test:lint:sass": "stylelint \"**/*.{css,scss}\"", + "test:lint:sass": "stylelint \"**/*.{css,scss}\" && prettier --check \"**/*.{css,scss}\"", "test:jest": "cross-env NODE_ENV=test jest", "format": "prettier --write \"**/*.{json,yml}\"", "format-check": "prettier --check \"**/*.{json,yml}\"" @@ -157,8 +157,8 @@ "raf": "^3.4.1", "react-intl-translations-manager": "^5.0.3", "react-test-renderer": "^16.14.0", - "stylelint": "^14.16.1", - "stylelint-config-standard-scss": "^6.1.0", + "stylelint": "^15.1.0", + "stylelint-config-standard-scss": "^7.0.0", "webpack-dev-server": "^3.11.3", "yargs": "^17.6.2" }, diff --git a/stylelint.config.js b/stylelint.config.js index 0f8267a81f..c8c07a05bc 100644 --- a/stylelint.config.js +++ b/stylelint.config.js @@ -10,7 +10,6 @@ module.exports = { 'color-function-notation': null, 'color-hex-length': null, 'declaration-block-no-redundant-longhand-properties': null, - 'max-line-length': null, 'no-descending-specificity': null, 'no-duplicate-selectors': null, 'number-max-precision': 8, @@ -18,7 +17,6 @@ module.exports = { 'property-no-vendor-prefix': null, 'selector-class-pattern': null, 'selector-id-pattern': null, - 'string-quotes': null, 'value-keyword-case': null, 'value-no-vendor-prefix': null, diff --git a/yarn.lock b/yarn.lock index cd14ee89a8..b94daa0893 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1076,10 +1076,25 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@csstools/selector-specificity@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz#1bfafe4b7ed0f3e4105837e056e0a89b108ebe36" - integrity sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg== +"@csstools/css-parser-algorithms@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.0.1.tgz#ff02629c7c95d1f4f8ea84d5ef1173461610535e" + integrity sha512-B9/8PmOtU6nBiibJg0glnNktQDZ3rZnGn/7UmDfrm2vMtrdlXO3p7ErE95N0up80IRk9YEtB5jyj/TmQ1WH3dw== + +"@csstools/css-tokenizer@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-2.0.1.tgz#cb1e11752db57e69d9aa0e84c3105a25845d4055" + integrity sha512-sYD3H7ReR88S/4+V5VbKiBEUJF4FqvG+8aNJkxqoPAnbhFziDG22IDZc4+h+xA63SfgM+h15lq5OnLeCxQ9nPA== + +"@csstools/media-query-list-parser@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@csstools/media-query-list-parser/-/media-query-list-parser-2.0.1.tgz#d85a366811563a5d002755ed10e5212a1613c91d" + integrity sha512-X2/OuzEbjaxhzm97UJ+95GrMeT29d1Ib+Pu+paGLuRWZnWRK9sI9r3ikmKXPWGA1C4y4JEdBEFpp9jEqCvLeRA== + +"@csstools/selector-specificity@^2.1.1": + version "2.1.1" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz#c9c61d9fe5ca5ac664e1153bb0aa0eba1c6d6308" + integrity sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw== "@emotion/babel-plugin@^11.7.1": version "11.9.2" @@ -3562,7 +3577,7 @@ cosmiconfig@^6.0.0: path-type "^4.0.0" yaml "^1.7.2" -cosmiconfig@^7.0.0, cosmiconfig@^7.1.0: +cosmiconfig@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== @@ -3573,6 +3588,16 @@ cosmiconfig@^7.0.0, cosmiconfig@^7.1.0: path-type "^4.0.0" yaml "^1.10.0" +cosmiconfig@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.0.0.tgz#e9feae014eab580f858f8a0288f38997a7bebe97" + integrity sha512-da1EafcpH6b/TD8vDRaWV7xFINlHlF6zKsGwS1TsuVJTZRkquaS5HTMq7uq6h31619QjbsYl21gVDOm32KM1vQ== + dependencies: + import-fresh "^3.2.1" + js-yaml "^4.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + create-ecdh@^4.0.0: version "4.0.4" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" @@ -3718,6 +3743,14 @@ css-tree@1.0.0-alpha.39: mdn-data "2.0.6" source-map "^0.6.1" +css-tree@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" + integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== + dependencies: + mdn-data "2.0.30" + source-map-js "^1.0.1" + css-what@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.3.0.tgz#10fec696a9ece2e591ac772d759aacabac38cd39" @@ -5734,7 +5767,7 @@ iferr@^0.1.5: resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" integrity sha1-xg7taebY/bazEEofy8ocGS3FtQE= -ignore@^5.2.0, ignore@^5.2.1: +ignore@^5.2.0, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== @@ -7316,6 +7349,11 @@ md5.js@^1.3.4: inherits "^2.0.1" safe-buffer "^5.1.2" +mdn-data@2.0.30: + version "2.0.30" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" + integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== + mdn-data@2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" @@ -8706,7 +8744,7 @@ postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.27, postcss@^7.0.32: source-map "^0.6.1" supports-color "^6.1.0" -postcss@^8.2.15, postcss@^8.4.19, postcss@^8.4.21: +postcss@^8.2.15, postcss@^8.4.21: version "8.4.21" resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4" integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== @@ -10029,7 +10067,7 @@ source-list-map@^2.0.0: resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.2: +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== @@ -10426,39 +10464,39 @@ stylehacks@^4.0.0: postcss "^7.0.0" postcss-selector-parser "^3.0.0" -stylelint-config-recommended-scss@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-8.0.0.tgz#1c1e93e619fe2275d4c1067928d92e0614f7d64f" - integrity sha512-BxjxEzRaZoQb7Iinc3p92GS6zRdRAkIuEu2ZFLTxJK2e1AIcCb5B5MXY9KOXdGTnYFZ+KKx6R4Fv9zU6CtMYPQ== +stylelint-config-recommended-scss@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-9.0.0.tgz#e755cf3654f3a3a6d7bdf84fe0a814595754a386" + integrity sha512-5e9pn3Ztfncd8s9OqvvCW7tZpYe+vGmPi7VEXX7XEp+Kj38PnKCrvFCBL+hQ7rkD4d5QzjB3BxlFEyo/30UWUw== dependencies: postcss-scss "^4.0.2" - stylelint-config-recommended "^9.0.0" - stylelint-scss "^4.0.0" + stylelint-config-recommended "^10.0.1" + stylelint-scss "^4.4.0" -stylelint-config-recommended@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz#1c9e07536a8cd875405f8ecef7314916d94e7e40" - integrity sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ== +stylelint-config-recommended@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/stylelint-config-recommended/-/stylelint-config-recommended-10.0.1.tgz#25a8828acf6cde87dac6db2950c8c4ed82a69ae1" + integrity sha512-TQ4xQ48tW4QSlODcti7pgSRqBZcUaBzuh0jPpfiMhwJKBPkqzTIAU+IrSWL/7BgXlOM90DjB7YaNgFpx8QWhuA== -stylelint-config-standard-scss@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/stylelint-config-standard-scss/-/stylelint-config-standard-scss-6.1.0.tgz#a6cddd2a9430578b92fc89726a59474d5548a444" - integrity sha512-iZ2B5kQT2G3rUzx+437cEpdcnFOQkwnwqXuY8Z0QUwIHQVE8mnYChGAquyKFUKZRZ0pRnrciARlPaR1RBtPb0Q== +stylelint-config-standard-scss@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/stylelint-config-standard-scss/-/stylelint-config-standard-scss-7.0.0.tgz#c7076bf5afa705d9e5ddc3ede39da7a684fa0f60" + integrity sha512-rHgydRJxN4Q9lDcwrLFoiFA3S8CRqsUcyBBCLwEMjIwzJViluFfsOKFPSomx6hScVQgQ4//Fx0hRKiSHyO0ihw== dependencies: - stylelint-config-recommended-scss "^8.0.0" - stylelint-config-standard "^29.0.0" + stylelint-config-recommended-scss "^9.0.0" + stylelint-config-standard "^30.0.1" -stylelint-config-standard@^29.0.0: - version "29.0.0" - resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-29.0.0.tgz#4cc0e0f05512a39bb8b8e97853247d3a95d66fa2" - integrity sha512-uy8tZLbfq6ZrXy4JKu3W+7lYLgRQBxYTUUB88vPgQ+ZzAxdrvcaSUW9hOMNLYBnwH+9Kkj19M2DHdZ4gKwI7tg== +stylelint-config-standard@^30.0.1: + version "30.0.1" + resolved "https://registry.yarnpkg.com/stylelint-config-standard/-/stylelint-config-standard-30.0.1.tgz#a84d57c240c37f7db47023ab9d2e64c49090e1eb" + integrity sha512-NbeHOmpRQhjZh5XB1B/S4MLRWvz4xxAxeDBjzl0tY2xEcayNhLbaRGF0ZQzq+DQZLCcPpOHeS2Ru1ydbkhkmLg== dependencies: - stylelint-config-recommended "^9.0.0" + stylelint-config-recommended "^10.0.1" -stylelint-scss@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-4.2.0.tgz#e25fd390ee38a7e89fcfaec2a8f9dce2ec6ddee8" - integrity sha512-HHHMVKJJ5RM9pPIbgJ/XA67h9H0407G68Rm69H4fzFbFkyDMcTV1Byep3qdze5+fJ3c0U7mJrbj6S0Fg072uZA== +stylelint-scss@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/stylelint-scss/-/stylelint-scss-4.4.0.tgz#87ce9d049eff1ce67cce788780fbfda63099017e" + integrity sha512-Qy66a+/30aylFhPmUArHhVsHOun1qrO93LGT15uzLuLjWS7hKDfpFm34mYo1ndR4MCo8W4bEZM1+AlJRJORaaw== dependencies: lodash "^4.17.21" postcss-media-query-parser "^0.2.3" @@ -10466,16 +10504,20 @@ stylelint-scss@^4.0.0: postcss-selector-parser "^6.0.6" postcss-value-parser "^4.1.0" -stylelint@^14.16.1: - version "14.16.1" - resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-14.16.1.tgz#b911063530619a1bbe44c2b875fd8181ebdc742d" - integrity sha512-ErlzR/T3hhbV+a925/gbfc3f3Fep9/bnspMiJPorfGEmcBbXdS+oo6LrVtoUZ/w9fqD6o6k7PtUlCOsCRdjX/A== +stylelint@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/stylelint/-/stylelint-15.1.0.tgz#24d7cbe06250ceca3b276393bfdeaaaba4356195" + integrity sha512-Tw8OyIiYhxnIHUzgoLlCyWgCUKsPYiP3TDgs7M1VbayS+q5qZly2yxABg+YPe/hFRWiu0cOtptCtpyrn1CrnYw== dependencies: - "@csstools/selector-specificity" "^2.0.2" + "@csstools/css-parser-algorithms" "^2.0.1" + "@csstools/css-tokenizer" "^2.0.1" + "@csstools/media-query-list-parser" "^2.0.1" + "@csstools/selector-specificity" "^2.1.1" balanced-match "^2.0.0" colord "^2.9.3" - cosmiconfig "^7.1.0" + cosmiconfig "^8.0.0" css-functions-list "^3.1.0" + css-tree "^2.3.1" debug "^4.3.4" fast-glob "^3.2.12" fastest-levenshtein "^1.0.16" @@ -10484,7 +10526,7 @@ stylelint@^14.16.1: globby "^11.1.0" globjoin "^0.1.4" html-tags "^3.2.0" - ignore "^5.2.1" + ignore "^5.2.4" import-lazy "^4.0.0" imurmurhash "^0.1.4" is-plain-object "^5.0.0" @@ -10494,7 +10536,7 @@ stylelint@^14.16.1: micromatch "^4.0.5" normalize-path "^3.0.0" picocolors "^1.0.0" - postcss "^8.4.19" + postcss "^8.4.21" postcss-media-query-parser "^0.2.3" postcss-resolve-nested-selector "^0.1.1" postcss-safe-parser "^6.0.0" @@ -10508,7 +10550,7 @@ stylelint@^14.16.1: svg-tags "^1.0.0" table "^6.8.1" v8-compile-cache "^2.3.0" - write-file-atomic "^4.0.2" + write-file-atomic "^5.0.0" stylis@4.0.13: version "4.0.13" @@ -11778,14 +11820,6 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -write-file-atomic@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" - integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^3.0.7" - write-file-atomic@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.0.tgz#54303f117e109bf3d540261125c8ea5a7320fab0" From a1c0573bc6f4e4778c10f1d08f0bc35260d620ed Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Sun, 12 Feb 2023 22:57:51 -0500 Subject: [PATCH 06/28] Yarn cache cleanup right after install in Docker (#23557) --- Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index ce7f4d7186..35c7ae4410 100644 --- a/Dockerfile +++ b/Dockerfile @@ -37,7 +37,8 @@ RUN apt-get update && \ bundle config set --local without 'development test' && \ bundle config set silence_root_warning true && \ bundle install -j"$(nproc)" && \ - yarn install --pure-lockfile --network-timeout 600000 + yarn install --pure-lockfile --network-timeout 600000 && \ + yarn cache clean FROM node:${NODE_VERSION} @@ -91,8 +92,7 @@ USER mastodon WORKDIR /opt/mastodon # Precompile assets -RUN OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder rails assets:precompile && \ - yarn cache clean +RUN OTP_SECRET=precompile_placeholder SECRET_KEY_BASE=precompile_placeholder rails assets:precompile # Set the work dir and the container entry point ENTRYPOINT ["/usr/bin/tini", "--"] From c6b7e0412061770f26c4eb5700fb1f515c8f9a53 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Sun, 12 Feb 2023 22:58:37 -0500 Subject: [PATCH 07/28] Sync Node.js to 16.19 patch release (#23554) --- .circleci/config.yml | 2 +- .nvmrc | 2 +- Dockerfile | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index a373d685e0..fabb6967e7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -221,5 +221,5 @@ workflows: pkg-manager: yarn requires: - build - version: '16.18' + version: '16.19' yarn-run: test:jest diff --git a/.nvmrc b/.nvmrc index b6a7d89c68..030fcd56bf 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16 +16.19 diff --git a/Dockerfile b/Dockerfile index 35c7ae4410..fbb8871411 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:1.4 # This needs to be bullseye-slim because the Ruby image is built on bullseye-slim -ARG NODE_VERSION="16.18.1-bullseye-slim" +ARG NODE_VERSION="16.19-bullseye-slim" FROM ghcr.io/moritzheiber/ruby-jemalloc:3.0.4-slim as ruby FROM node:${NODE_VERSION} as build From d874877b27321682be7b208326f098d6750ec8db Mon Sep 17 00:00:00 2001 From: Takeshi Umeda Date: Mon, 13 Feb 2023 12:58:56 +0900 Subject: [PATCH 08/28] Update SECURITY.md (#23545) Co-authored-by: Eugen Rochko Co-authored-by: Nick Schonning --- SECURITY.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/SECURITY.md b/SECURITY.md index ccc7c10346..234172999d 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -11,7 +11,8 @@ A "vulnerability in Mastodon" is a vulnerability in the code distributed through ## Supported Versions | Version | Supported | -| ------- | ----------| +| ------- | --------- | +| 4.1.x | Yes | | 4.0.x | Yes | | 3.5.x | Yes | | < 3.5 | No | From 7c5d396fcad1267872dd7ed00204f076e52c689c Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Sun, 12 Feb 2023 22:59:30 -0500 Subject: [PATCH 09/28] Replace hamlit-rails with haml-rails (#23542) --- Gemfile | 4 ++-- Gemfile.lock | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Gemfile b/Gemfile index 6e5292d824..9849b36eaf 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,7 @@ gem 'sprockets', '~> 3.7.2' gem 'thor', '~> 1.2' gem 'rack', '~> 2.2.6' -gem 'hamlit-rails', '~> 0.2' +gem 'haml-rails', '~>2.0' gem 'pg', '~> 1.4' gem 'makara', '~> 0.5' gem 'pghero' @@ -122,7 +122,7 @@ group :test do gem 'climate_control', '~> 0.2' gem 'faker', '~> 3.1' gem 'json-schema', '~> 3.0' - gem 'rack-test', '~> 2.0' + gem 'rack-test', '~> 2.0' gem 'rails-controller-testing', '~> 1.0' gem 'rspec_junit_formatter', '~> 0.6' gem 'rspec-sidekiq', '~> 3.1' diff --git a/Gemfile.lock b/Gemfile.lock index 2d7ee2df89..8e6e5a28f7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -284,15 +284,15 @@ GEM openid_connect (~> 1.2) globalid (1.1.0) activesupport (>= 5.0) - hamlit (2.13.0) + haml (6.1.1) temple (>= 0.8.2) thor tilt - hamlit-rails (0.2.3) - actionpack (>= 4.0.1) - activesupport (>= 4.0.1) - hamlit (>= 1.2.0) - railties (>= 4.0.1) + haml-rails (2.1.0) + actionpack (>= 5.1) + activesupport (>= 5.1) + haml (>= 4.0.6) + railties (>= 5.1) hashdiff (1.0.1) hashie (5.0.0) highline (2.0.3) @@ -683,7 +683,7 @@ GEM activesupport (>= 3) attr_required (>= 0.0.5) httpclient (>= 2.4) - temple (0.8.2) + temple (0.10.0) terminal-table (3.0.2) unicode-display_width (>= 1.1.1, < 3) terrapin (0.6.0) @@ -799,7 +799,7 @@ DEPENDENCIES fog-openstack (~> 0.3) fuubar (~> 2.5) gitlab-omniauth-openid-connect (~> 0.10.1) - hamlit-rails (~> 0.2) + haml-rails (~> 2.0) hiredis (~> 0.6) htmlentities (~> 4.3) http (~> 5.1) From c55568c75a2754d1a2d9383b4e4e7147ea2e9ed5 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 13 Feb 2023 13:23:59 +0100 Subject: [PATCH 10/28] Add tests for `REST::AccountSerializer` (#23319) --- .../rest/account_serializer_spec.rb | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 spec/serializers/rest/account_serializer_spec.rb diff --git a/spec/serializers/rest/account_serializer_spec.rb b/spec/serializers/rest/account_serializer_spec.rb new file mode 100644 index 0000000000..ce29df3a76 --- /dev/null +++ b/spec/serializers/rest/account_serializer_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe REST::AccountSerializer do + let(:role) { Fabricate(:user_role, name: 'Role', highlighted: true) } + let(:user) { Fabricate(:user, role: role) } + let(:account) { user.account} + + subject { JSON.parse(ActiveModelSerializers::SerializableResource.new(account, serializer: REST::AccountSerializer).to_json) } + + context 'when the account is suspended' do + before do + account.suspend! + end + + it 'returns empty roles' do + expect(subject['roles']).to eq [] + end + end + + context 'when the account has a highlighted role' do + let(:role) { Fabricate(:user_role, name: 'Role', highlighted: true) } + + it 'returns the expected role' do + expect(subject['roles'].first).to include({ 'name' => 'Role' }) + end + end + + context 'when the account has a non-highlighted role' do + let(:role) { Fabricate(:user_role, name: 'Role', highlighted: false) } + + it 'returns empty roles' do + expect(subject['roles']).to eq [] + end + end +end From 31352f0d2ce2fbfaa0a4cef4cbf61cf45fa0f2ad Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Feb 2023 13:31:42 +0100 Subject: [PATCH 11/28] Bump sidekiq-scheduler from 4.0.3 to 5.0.0 (#23212) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Claire --- Gemfile | 2 +- Gemfile.lock | 9 ++--- config/sidekiq.yml | 98 +++++++++++++++++++++++----------------------- 3 files changed, 54 insertions(+), 55 deletions(-) diff --git a/Gemfile b/Gemfile index 9849b36eaf..d64451589b 100644 --- a/Gemfile +++ b/Gemfile @@ -81,7 +81,7 @@ gem 'ruby-progressbar', '~> 1.11' gem 'sanitize', '~> 6.0' gem 'scenic', '~> 1.7' gem 'sidekiq', '~> 6.5' -gem 'sidekiq-scheduler', '~> 4.0' +gem 'sidekiq-scheduler', '~> 5.0' gem 'sidekiq-unique-jobs', '~> 7.1' gem 'sidekiq-bulk', '~> 0.2.0' gem 'simple-navigation', '~> 4.4' diff --git a/Gemfile.lock b/Gemfile.lock index 8e6e5a28f7..3bf7699d66 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -272,7 +272,7 @@ GEM fog-json (>= 1.0) ipaddress (>= 0.8) formatador (0.3.0) - fugit (1.7.1) + fugit (1.8.1) et-orbi (~> 1, >= 1.2.7) raabro (~> 1.4) fuubar (2.5.1) @@ -640,10 +640,9 @@ GEM redis (>= 4.5.0, < 5) sidekiq-bulk (0.2.0) sidekiq - sidekiq-scheduler (4.0.3) - redis (>= 4.2.0) + sidekiq-scheduler (5.0.0) rufus-scheduler (~> 3.2) - sidekiq (>= 4, < 7) + sidekiq (>= 4, < 8) tilt (>= 1.4.0) sidekiq-unique-jobs (7.1.29) brpoplpush-redis_script (> 0.1.1, <= 2.0.0) @@ -867,7 +866,7 @@ DEPENDENCIES scenic (~> 1.7) sidekiq (~> 6.5) sidekiq-bulk (~> 0.2.0) - sidekiq-scheduler (~> 4.0) + sidekiq-scheduler (~> 5.0) sidekiq-unique-jobs (~> 7.1) simple-navigation (~> 4.4) simple_form (~> 5.2) diff --git a/config/sidekiq.yml b/config/sidekiq.yml index b8739aab33..2278329a56 100644 --- a/config/sidekiq.yml +++ b/config/sidekiq.yml @@ -9,52 +9,52 @@ - [scheduler] :scheduler: :listened_queues_only: true -:schedule: - scheduled_statuses_scheduler: - every: '5m' - class: Scheduler::ScheduledStatusesScheduler - queue: scheduler - trends_refresh_scheduler: - every: '5m' - class: Scheduler::Trends::RefreshScheduler - queue: scheduler - trends_review_notifications_scheduler: - every: '6h' - class: Scheduler::Trends::ReviewNotificationsScheduler - queue: scheduler - indexing_scheduler: - every: '5m' - class: Scheduler::IndexingScheduler - queue: scheduler - vacuum_scheduler: - cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *' - class: Scheduler::VacuumScheduler - queue: scheduler - follow_recommendations_scheduler: - cron: '<%= Random.rand(0..59) %> <%= Random.rand(6..9) %> * * *' - class: Scheduler::FollowRecommendationsScheduler - queue: scheduler - user_cleanup_scheduler: - cron: '<%= Random.rand(0..59) %> <%= Random.rand(4..6) %> * * *' - class: Scheduler::UserCleanupScheduler - queue: scheduler - ip_cleanup_scheduler: - cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *' - class: Scheduler::IpCleanupScheduler - queue: scheduler - pghero_scheduler: - cron: '0 0 * * *' - class: Scheduler::PgheroScheduler - queue: scheduler - instance_refresh_scheduler: - cron: '0 * * * *' - class: Scheduler::InstanceRefreshScheduler - queue: scheduler - accounts_statuses_cleanup_scheduler: - interval: 1 minute - class: Scheduler::AccountsStatusesCleanupScheduler - queue: scheduler - suspended_user_cleanup_scheduler: - interval: 1 minute - class: Scheduler::SuspendedUserCleanupScheduler - queue: scheduler + :schedule: + scheduled_statuses_scheduler: + every: '5m' + class: Scheduler::ScheduledStatusesScheduler + queue: scheduler + trends_refresh_scheduler: + every: '5m' + class: Scheduler::Trends::RefreshScheduler + queue: scheduler + trends_review_notifications_scheduler: + every: '6h' + class: Scheduler::Trends::ReviewNotificationsScheduler + queue: scheduler + indexing_scheduler: + every: '5m' + class: Scheduler::IndexingScheduler + queue: scheduler + vacuum_scheduler: + cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *' + class: Scheduler::VacuumScheduler + queue: scheduler + follow_recommendations_scheduler: + cron: '<%= Random.rand(0..59) %> <%= Random.rand(6..9) %> * * *' + class: Scheduler::FollowRecommendationsScheduler + queue: scheduler + user_cleanup_scheduler: + cron: '<%= Random.rand(0..59) %> <%= Random.rand(4..6) %> * * *' + class: Scheduler::UserCleanupScheduler + queue: scheduler + ip_cleanup_scheduler: + cron: '<%= Random.rand(0..59) %> <%= Random.rand(3..5) %> * * *' + class: Scheduler::IpCleanupScheduler + queue: scheduler + pghero_scheduler: + cron: '0 0 * * *' + class: Scheduler::PgheroScheduler + queue: scheduler + instance_refresh_scheduler: + cron: '0 * * * *' + class: Scheduler::InstanceRefreshScheduler + queue: scheduler + accounts_statuses_cleanup_scheduler: + interval: 1 minute + class: Scheduler::AccountsStatusesCleanupScheduler + queue: scheduler + suspended_user_cleanup_scheduler: + interval: 1 minute + class: Scheduler::SuspendedUserCleanupScheduler + queue: scheduler From 66f2ad483c621cac783e639f68842e770f425b11 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Feb 2023 13:55:55 +0100 Subject: [PATCH 12/28] Bump sidekiq-scheduler from 5.0.0 to 5.0.1 (#23569) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 3bf7699d66..f325a7df86 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -640,7 +640,7 @@ GEM redis (>= 4.5.0, < 5) sidekiq-bulk (0.2.0) sidekiq - sidekiq-scheduler (5.0.0) + sidekiq-scheduler (5.0.1) rufus-scheduler (~> 3.2) sidekiq (>= 4, < 8) tilt (>= 1.4.0) From cc92c65d832a7920cc4dcd55ce703022c0a19632 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 13 Feb 2023 14:36:07 +0100 Subject: [PATCH 13/28] Add dependency on net-http (#23571) --- Gemfile | 2 ++ Gemfile.lock | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/Gemfile b/Gemfile index d64451589b..5bb81e3d55 100644 --- a/Gemfile +++ b/Gemfile @@ -158,3 +158,5 @@ gem 'concurrent-ruby', require: false gem 'connection_pool', require: false gem 'xorcist', '~> 1.1' gem 'cocoon', '~> 1.2' + +gem 'net-http', '~> 0.3.2' diff --git a/Gemfile.lock b/Gemfile.lock index f325a7df86..38f6ce65f2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -410,6 +410,8 @@ GEM msgpack (1.6.0) multi_json (1.15.0) multipart-post (2.1.1) + net-http (0.3.2) + uri net-imap (0.3.4) date net-protocol @@ -716,6 +718,7 @@ GEM unf_ext (0.0.8.2) unicode-display_width (2.4.2) uniform_notifier (1.16.0) + uri (0.12.0) validate_email (0.1.6) activemodel (>= 3.0) mail (>= 2.2.5) @@ -819,6 +822,7 @@ DEPENDENCIES mario-redis-lock (~> 1.2) memory_profiler mime-types (~> 3.4.1) + net-http (~> 0.3.2) net-ldap (~> 0.17) nokogiri (~> 1.14) nsa (~> 0.2) From 93d7c26fa5224aea9d0cd10838dbd2d2a1fc5156 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Feb 2023 14:38:43 +0100 Subject: [PATCH 14/28] Bump rubocop from 1.44.1 to 1.45.1 (#23523) Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 38f6ce65f2..1c692ed0d7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -465,7 +465,7 @@ GEM orm_adapter (0.5.0) ox (2.14.14) parallel (1.22.1) - parser (3.2.0.0) + parser (3.2.1.0) ast (~> 2.4.1) parslet (2.0.0) pastel (0.8.0) @@ -561,7 +561,7 @@ GEM redis (>= 4) redlock (1.3.2) redis (>= 3.0.0, < 6.0) - regexp_parser (2.6.2) + regexp_parser (2.7.0) request_store (1.5.1) rack (>= 1.4) responders (3.0.1) @@ -596,7 +596,7 @@ GEM rspec-support (3.11.1) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (1.44.1) + rubocop (1.45.1) json (~> 2.3) parallel (~> 1.10) parser (>= 3.2.0.0) From 5f56818f9ed23ff902b6a53bba01574f97980abc Mon Sep 17 00:00:00 2001 From: Jeong Arm Date: Mon, 13 Feb 2023 22:39:00 +0900 Subject: [PATCH 15/28] Change followed_by link to location=all if account is local on /admin/accounts/:id page (#23467) --- app/views/admin/accounts/show.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml index db5c255c91..c8a9d33a70 100644 --- a/app/views/admin/accounts/show.html.haml +++ b/app/views/admin/accounts/show.html.haml @@ -37,7 +37,7 @@ .dashboard__counters__num= number_to_human_size @account.media_attachments.sum('file_file_size') .dashboard__counters__label= t 'admin.accounts.media_attachments' %div - = link_to admin_account_relationships_path(@account.id, location: 'local', relationship: 'followed_by') do + = link_to admin_account_relationships_path(@account.id, location: @account.local? ? nil : 'local', relationship: 'followed_by') do .dashboard__counters__num= number_with_delimiter @account.local_followers_count .dashboard__counters__label= t 'admin.accounts.followers' %div From 841263a548fa04d953bc47bd3a18474f0daecf9a Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Mon, 13 Feb 2023 08:39:24 -0500 Subject: [PATCH 16/28] Update Ruby to 3.0.5 (#23544) --- .ruby-version | 2 +- Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.ruby-version b/.ruby-version index b0f2dcb32f..eca690e737 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.0.4 +3.0.5 diff --git a/Dockerfile b/Dockerfile index fbb8871411..04e3b58b1e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # This needs to be bullseye-slim because the Ruby image is built on bullseye-slim ARG NODE_VERSION="16.19-bullseye-slim" -FROM ghcr.io/moritzheiber/ruby-jemalloc:3.0.4-slim as ruby +FROM ghcr.io/moritzheiber/ruby-jemalloc:3.0.5-slim as ruby FROM node:${NODE_VERSION} as build COPY --link --from=ruby /opt/ruby /opt/ruby From 4da5f77d929d6b83c134cae1eefbc8ba2db752f8 Mon Sep 17 00:00:00 2001 From: Dean Bassett Date: Mon, 13 Feb 2023 05:54:08 -0800 Subject: [PATCH 17/28] Fix case-sensitive check for previously used hashtags (#23526) --- app/javascript/mastodon/reducers/compose.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/javascript/mastodon/reducers/compose.js b/app/javascript/mastodon/reducers/compose.js index 783d748ae3..842b7af518 100644 --- a/app/javascript/mastodon/reducers/compose.js +++ b/app/javascript/mastodon/reducers/compose.js @@ -186,11 +186,12 @@ const ignoreSuggestion = (state, position, token, completion, path) => { }; const sortHashtagsByUse = (state, tags) => { - const personalHistory = state.get('tagHistory'); + const personalHistory = state.get('tagHistory').map(tag => tag.toLowerCase()); - return tags.sort((a, b) => { - const usedA = personalHistory.includes(a.name); - const usedB = personalHistory.includes(b.name); + const tagsWithLowercase = tags.map(t => ({ ...t, lowerName: t.name.toLowerCase() })); + const sorted = tagsWithLowercase.sort((a, b) => { + const usedA = personalHistory.includes(a.lowerName); + const usedB = personalHistory.includes(b.lowerName); if (usedA === usedB) { return 0; @@ -200,6 +201,8 @@ const sortHashtagsByUse = (state, tags) => { return 1; } }); + sorted.forEach(tag => delete tag.lowerName); + return sorted; }; const insertEmoji = (state, position, emojiData, needsSpace) => { From db2c58d47ae0db8490a30cd3846f30e615c382b5 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Mon, 13 Feb 2023 09:12:14 -0500 Subject: [PATCH 18/28] Enable ESLint no-useless-escape (#23311) --- .eslintrc.js | 1 - .../mastodon/actions/push_notifications/registerer.js | 2 +- app/javascript/mastodon/components/status.js | 2 +- .../mastodon/features/account_gallery/components/media_item.js | 2 +- .../mastodon/features/compose/containers/warning_container.js | 2 +- app/javascript/mastodon/features/compose/util/counter.js | 2 +- app/javascript/mastodon/features/emoji/emoji_utils.js | 2 +- .../features/follow_recommendations/components/account.js | 2 +- .../mastodon/features/picture_in_picture/components/footer.js | 2 +- .../mastodon/features/status/components/detailed_status.js | 2 +- app/javascript/mastodon/features/ui/components/boost_modal.js | 2 +- config/webpack/shared.js | 2 +- 12 files changed, 11 insertions(+), 12 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index ca7fc83eb9..ef52818b06 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -98,7 +98,6 @@ module.exports = { ignoreRestSiblings: true, }, ], - 'no-useless-escape': 'off', 'object-curly-spacing': ['error', 'always'], 'padded-blocks': [ 'error', diff --git a/app/javascript/mastodon/actions/push_notifications/registerer.js b/app/javascript/mastodon/actions/push_notifications/registerer.js index b0f42b6a20..b491f85c24 100644 --- a/app/javascript/mastodon/actions/push_notifications/registerer.js +++ b/app/javascript/mastodon/actions/push_notifications/registerer.js @@ -8,7 +8,7 @@ import { me } from '../../initial_state'; const urlBase64ToUint8Array = (base64String) => { const padding = '='.repeat((4 - base64String.length % 4) % 4); const base64 = (base64String + padding) - .replace(/\-/g, '+') + .replace(/-/g, '+') .replace(/_/g, '/'); return decodeBase64(base64); diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js index 6b89226085..f02910f5ac 100644 --- a/app/javascript/mastodon/components/status.js +++ b/app/javascript/mastodon/components/status.js @@ -511,7 +511,7 @@ class Status extends ImmutablePureComponent {
- + {status.get('edited_at') && *} diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.js index 80e164af89..d6d60ebda7 100644 --- a/app/javascript/mastodon/features/account_gallery/components/media_item.js +++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js @@ -130,7 +130,7 @@ export default class MediaItem extends ImmutablePureComponent { return (
- + { '))', 'iu', ); } catch { - return /(?:^|[^\/\)\w])#(\w*[a-zA-Z·]\w*)/i; + return /(?:^|[^/)\w])#(\w*[a-zA-Z·]\w*)/i; } }; diff --git a/app/javascript/mastodon/features/compose/util/counter.js b/app/javascript/mastodon/features/compose/util/counter.js index 5a68bad992..ec2431096b 100644 --- a/app/javascript/mastodon/features/compose/util/counter.js +++ b/app/javascript/mastodon/features/compose/util/counter.js @@ -5,5 +5,5 @@ const urlPlaceholder = '$2xxxxxxxxxxxxxxxxxxxxxxx'; export function countableText(inputText) { return inputText .replace(urlRegex, urlPlaceholder) - .replace(/(^|[^\/\w])@(([a-z0-9_]+)@[a-z0-9\.\-]+[a-z0-9]+)/ig, '$1@$3'); + .replace(/(^|[^/\w])@(([a-z0-9_]+)@[a-z0-9.-]+[a-z0-9]+)/ig, '$1@$3'); } diff --git a/app/javascript/mastodon/features/emoji/emoji_utils.js b/app/javascript/mastodon/features/emoji/emoji_utils.js index 571907a509..be793526d0 100644 --- a/app/javascript/mastodon/features/emoji/emoji_utils.js +++ b/app/javascript/mastodon/features/emoji/emoji_utils.js @@ -73,7 +73,7 @@ const stringFromCodePoint = _String.fromCodePoint || function () { const _JSON = JSON; -const COLONS_REGEX = /^(?:\:([^\:]+)\:)(?:\:skin-tone-(\d)\:)?$/; +const COLONS_REGEX = /^(?::([^:]+):)(?::skin-tone-(\d):)?$/; const SKINS = [ '1F3FA', '1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF', diff --git a/app/javascript/mastodon/features/follow_recommendations/components/account.js b/app/javascript/mastodon/features/follow_recommendations/components/account.js index daaa2f99ee..ddd0c8baab 100644 --- a/app/javascript/mastodon/features/follow_recommendations/components/account.js +++ b/app/javascript/mastodon/features/follow_recommendations/components/account.js @@ -27,7 +27,7 @@ const makeMapStateToProps = () => { }; const getFirstSentence = str => { - const arr = str.split(/(([\.\?!]+\s)|[.。?!\n•])/); + const arr = str.split(/(([.?!]+\s)|[.。?!\n•])/); return arr[0]; }; 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 3f59b891b8..0ee6d06c7f 100644 --- a/app/javascript/mastodon/features/picture_in_picture/components/footer.js +++ b/app/javascript/mastodon/features/picture_in_picture/components/footer.js @@ -184,7 +184,7 @@ class Footer extends ImmutablePureComponent { - {withOpenButton && } + {withOpenButton && }
); } diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js index 116d9f6b27..064231ffe3 100644 --- a/app/javascript/mastodon/features/status/components/detailed_status.js +++ b/app/javascript/mastodon/features/status/components/detailed_status.js @@ -276,7 +276,7 @@ class DetailedStatus extends ImmutablePureComponent { {media}
- + {edited}{visibilityLink}{applicationLink}{reblogLink} · {favouriteLink}
diff --git a/app/javascript/mastodon/features/ui/components/boost_modal.js b/app/javascript/mastodon/features/ui/components/boost_modal.js index 087eadba2e..d6a6cea31e 100644 --- a/app/javascript/mastodon/features/ui/components/boost_modal.js +++ b/app/javascript/mastodon/features/ui/components/boost_modal.js @@ -98,7 +98,7 @@ class BoostModal extends ImmutablePureComponent {
- + diff --git a/config/webpack/shared.js b/config/webpack/shared.js index 3447e711c1..78f660cfcd 100644 --- a/config/webpack/shared.js +++ b/config/webpack/shared.js @@ -55,7 +55,7 @@ module.exports = { chunks: 'all', minChunks: 2, minSize: 0, - test: /^(?!.*[\\\/]node_modules[\\\/]react-intl[\\\/]).+$/, + test: /^(?!.*[\\/]node_modules[\\/]react-intl[\\/]).+$/, }, }, }, From eddfb33dfea6a17e71377d95498b557dd0194477 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Mon, 13 Feb 2023 09:12:31 -0500 Subject: [PATCH 19/28] Enable ESLint import recommended rules (#23315) --- .eslintrc.js | 3 ++- .../mastodon/features/audio/index.js | 6 ++--- .../compose/containers/poll_form_container.js | 5 ++++- .../compose/containers/upload_container.js | 3 +-- .../components/announcements.js | 3 +-- .../containers/column_settings_container.js | 3 +-- .../mastodon/features/status/index.js | 22 +++++++++---------- 7 files changed, 22 insertions(+), 23 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index ef52818b06..4d81aa47e0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,6 +5,7 @@ module.exports = { 'eslint:recommended', 'plugin:react/recommended', 'plugin:jsx-a11y/recommended', + 'plugin:import/recommended', ], env: { @@ -177,6 +178,7 @@ module.exports = { }, ], + // See https://github.com/import-js/eslint-plugin-import/blob/main/config/recommended.js 'import/extensions': [ 'error', 'always', @@ -195,7 +197,6 @@ module.exports = { ], }, ], - 'import/no-unresolved': 'error', 'import/no-webpack-loader-syntax': 'error', 'promise/catch-or-return': [ diff --git a/app/javascript/mastodon/features/audio/index.js b/app/javascript/mastodon/features/audio/index.js index a556583608..bf954c06d4 100644 --- a/app/javascript/mastodon/features/audio/index.js +++ b/app/javascript/mastodon/features/audio/index.js @@ -1,12 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; -import { formatTime } from 'mastodon/features/video'; +import { formatTime, getPointerPosition, fileNameFromURL } from 'mastodon/features/video'; import Icon from 'mastodon/components/icon'; import classNames from 'classnames'; -import { throttle } from 'lodash'; -import { getPointerPosition, fileNameFromURL } from 'mastodon/features/video'; -import { debounce } from 'lodash'; +import { throttle, debounce } from 'lodash'; import Visualizer from './visualizer'; import { displayMedia, useBlurhash } from '../../initial_state'; import Blurhash from '../../components/blurhash'; diff --git a/app/javascript/mastodon/features/compose/containers/poll_form_container.js b/app/javascript/mastodon/features/compose/containers/poll_form_container.js index c47fc75006..479117e915 100644 --- a/app/javascript/mastodon/features/compose/containers/poll_form_container.js +++ b/app/javascript/mastodon/features/compose/containers/poll_form_container.js @@ -1,7 +1,10 @@ import { connect } from 'react-redux'; import PollForm from '../components/poll_form'; -import { addPollOption, removePollOption, changePollOption, changePollSettings } from '../../../actions/compose'; import { + addPollOption, + removePollOption, + changePollOption, + changePollSettings, clearComposeSuggestions, fetchComposeSuggestions, selectComposeSuggestion, diff --git a/app/javascript/mastodon/features/compose/containers/upload_container.js b/app/javascript/mastodon/features/compose/containers/upload_container.js index 05cd2ecc1f..5a8a64931c 100644 --- a/app/javascript/mastodon/features/compose/containers/upload_container.js +++ b/app/javascript/mastodon/features/compose/containers/upload_container.js @@ -1,7 +1,6 @@ import { connect } from 'react-redux'; import Upload from '../components/upload'; -import { undoUploadCompose, initMediaEditModal } from '../../../actions/compose'; -import { submitCompose } from '../../../actions/compose'; +import { undoUploadCompose, initMediaEditModal, submitCompose } from '../../../actions/compose'; const mapStateToProps = (state, { id }) => ({ media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id), diff --git a/app/javascript/mastodon/features/getting_started/components/announcements.js b/app/javascript/mastodon/features/getting_started/components/announcements.js index d4afbabe36..0cae0bd1fe 100644 --- a/app/javascript/mastodon/features/getting_started/components/announcements.js +++ b/app/javascript/mastodon/features/getting_started/components/announcements.js @@ -6,9 +6,8 @@ import PropTypes from 'prop-types'; import IconButton from 'mastodon/components/icon_button'; import Icon from 'mastodon/components/icon'; import { defineMessages, injectIntl, FormattedMessage, FormattedDate } from 'react-intl'; -import { autoPlayGif, reduceMotion, disableSwiping } from 'mastodon/initial_state'; +import { autoPlayGif, reduceMotion, disableSwiping, mascot } from 'mastodon/initial_state'; import elephantUIPlane from 'mastodon/../images/elephant_ui_plane.svg'; -import { mascot } from 'mastodon/initial_state'; import unicodeMapping from 'mastodon/features/emoji/emoji_unicode_mapping_light'; import classNames from 'classnames'; import EmojiPickerDropdown from 'mastodon/features/compose/containers/emoji_picker_dropdown_container'; diff --git a/app/javascript/mastodon/features/notifications/containers/column_settings_container.js b/app/javascript/mastodon/features/notifications/containers/column_settings_container.js index 9a70bd4f36..515afaca96 100644 --- a/app/javascript/mastodon/features/notifications/containers/column_settings_container.js +++ b/app/javascript/mastodon/features/notifications/containers/column_settings_container.js @@ -2,8 +2,7 @@ import { connect } from 'react-redux'; import { defineMessages, injectIntl } from 'react-intl'; import ColumnSettings from '../components/column_settings'; import { changeSetting } from '../../../actions/settings'; -import { setFilter } from '../../../actions/notifications'; -import { clearNotifications, requestBrowserPermission } from '../../../actions/notifications'; +import { setFilter, clearNotifications, requestBrowserPermission } from '../../../actions/notifications'; import { changeAlerts as changePushNotifications } from '../../../actions/push_notifications'; import { openModal } from '../../../actions/modal'; import { showAlert } from '../../../actions/alerts'; diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js index 38bbc6895b..2c6728fc05 100644 --- a/app/javascript/mastodon/features/status/index.js +++ b/app/javascript/mastodon/features/status/index.js @@ -5,7 +5,17 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { createSelector } from 'reselect'; -import { fetchStatus } from '../../actions/statuses'; +import { + fetchStatus, + muteStatus, + unmuteStatus, + deleteStatus, + editStatus, + hideStatus, + revealStatus, + translateStatus, + undoStatusTranslation, +} from '../../actions/statuses'; import MissingIndicator from '../../components/missing_indicator'; import LoadingIndicator from 'mastodon/components/loading_indicator'; import DetailedStatus from './components/detailed_status'; @@ -26,16 +36,6 @@ import { mentionCompose, directCompose, } from '../../actions/compose'; -import { - muteStatus, - unmuteStatus, - deleteStatus, - editStatus, - hideStatus, - revealStatus, - translateStatus, - undoStatusTranslation, -} from '../../actions/statuses'; import { unblockAccount, unmuteAccount, From f553b064e09fd9005c61b910f7be9f7e2955197b Mon Sep 17 00:00:00 2001 From: Stan Hu Date: Mon, 13 Feb 2023 09:47:50 -0500 Subject: [PATCH 20/28] Switch OpenID Connect gems (#23223) Co-authored-by: Claire --- Gemfile | 2 +- Gemfile.lock | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 5bb81e3d55..961926c534 100644 --- a/Gemfile +++ b/Gemfile @@ -40,7 +40,7 @@ end gem 'net-ldap', '~> 0.17' gem 'omniauth-cas', '~> 2.0' gem 'omniauth-saml', '~> 1.10' -gem 'gitlab-omniauth-openid-connect', '~>0.10.1', require: 'omniauth_openid_connect' +gem 'omniauth_openid_connect', '~> 0.6.0' gem 'omniauth', '~> 1.9' gem 'omniauth-rails_csrf_protection', '~> 0.1' diff --git a/Gemfile.lock b/Gemfile.lock index 1c692ed0d7..df50ee38f4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -278,10 +278,6 @@ GEM fuubar (2.5.1) rspec-core (~> 3.0) ruby-progressbar (~> 1.4) - gitlab-omniauth-openid-connect (0.10.1) - addressable (~> 2.7) - omniauth (>= 1.9, < 3) - openid_connect (~> 1.2) globalid (1.1.0) activesupport (>= 5.0) haml (6.1.1) @@ -448,6 +444,9 @@ GEM omniauth-saml (1.10.3) omniauth (~> 1.3, >= 1.3.2) ruby-saml (~> 1.9) + omniauth_openid_connect (0.6.0) + omniauth (>= 1.9, < 3) + openid_connect (~> 1.1) openid_connect (1.4.2) activemodel attr_required (>= 1.0.0) @@ -800,7 +799,6 @@ DEPENDENCIES fog-core (<= 2.4.0) fog-openstack (~> 0.3) fuubar (~> 2.5) - gitlab-omniauth-openid-connect (~> 0.10.1) haml-rails (~> 2.0) hiredis (~> 0.6) htmlentities (~> 4.3) @@ -831,6 +829,7 @@ DEPENDENCIES omniauth-cas (~> 2.0) omniauth-rails_csrf_protection (~> 0.1) omniauth-saml (~> 1.10) + omniauth_openid_connect (~> 0.6.0) ox (~> 2.14) parslet pg (~> 1.4) From 45e2936c89870de7cd2fd0ce159e195745d8fddc Mon Sep 17 00:00:00 2001 From: Varun Sharma Date: Mon, 13 Feb 2023 20:34:26 +0530 Subject: [PATCH 21/28] Add tests to indicate inclusion of self replies in statuses endpoint (#23266) --- .../v1/accounts/statuses_controller_spec.rb | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/spec/controllers/api/v1/accounts/statuses_controller_spec.rb b/spec/controllers/api/v1/accounts/statuses_controller_spec.rb index b962b3398f..01d745fc0f 100644 --- a/spec/controllers/api/v1/accounts/statuses_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/statuses_controller_spec.rb @@ -1,3 +1,4 @@ +# frozen_string_literal: true require 'rails_helper' describe Api::V1::Accounts::StatusesController do @@ -15,7 +16,12 @@ describe Api::V1::Accounts::StatusesController do it 'returns http success' do get :index, params: { account_id: user.account.id, limit: 1 } - expect(response).to have_http_status(200) + expect(response).to have_http_status(:ok) + end + + it 'returns expected headers' do + get :index, params: { account_id: user.account.id, limit: 1 } + expect(response.headers['Link'].links.size).to eq(2) end @@ -23,19 +29,29 @@ describe Api::V1::Accounts::StatusesController do it 'returns http success' do get :index, params: { account_id: user.account.id, only_media: true } - expect(response).to have_http_status(200) + expect(response).to have_http_status(:ok) end end context 'with exclude replies' do + let!(:older_statuses) { user.account.statuses.destroy_all } + let!(:status) { Fabricate(:status, account: user.account) } + let!(:status_self_reply) { Fabricate(:status, account: user.account, thread: status) } + before do - Fabricate(:status, account: user.account, thread: Fabricate(:status)) + Fabricate(:status, account: user.account, thread: Fabricate(:status)) # Reply to another user + get :index, params: { account_id: user.account.id, exclude_replies: true } end it 'returns http success' do - get :index, params: { account_id: user.account.id, exclude_replies: true } + expect(response).to have_http_status(:ok) + end - expect(response).to have_http_status(200) + it 'returns posts along with self replies' do + json = body_as_json + post_ids = json.map { |item| item[:id].to_i }.sort + + expect(post_ids).to eq [status.id, status_self_reply.id] end end @@ -47,7 +63,7 @@ describe Api::V1::Accounts::StatusesController do it 'returns http success' do get :index, params: { account_id: user.account.id, pinned: true } - expect(response).to have_http_status(200) + expect(response).to have_http_status(:ok) end end @@ -55,12 +71,15 @@ describe Api::V1::Accounts::StatusesController do let(:account) { Fabricate(:account, username: 'bob', domain: 'example.com') } let(:status) { Fabricate(:status, account: account) } let(:private_status) { Fabricate(:status, account: account, visibility: :private) } - let!(:pin) { Fabricate(:status_pin, account: account, status: status) } - let!(:private_pin) { Fabricate(:status_pin, account: account, status: private_status) } + + before do + Fabricate(:status_pin, account: account, status: status) + Fabricate(:status_pin, account: account, status: private_status) + end it 'returns http success' do get :index, params: { account_id: account.id, pinned: true } - expect(response).to have_http_status(200) + expect(response).to have_http_status(:ok) end context 'when user does not follow account' do From c84f38abc4b82d77c5d832399d5746fe51de3c67 Mon Sep 17 00:00:00 2001 From: Shlee Date: Mon, 13 Feb 2023 15:33:34 +0000 Subject: [PATCH 22/28] chewy from 7.2.4 to 7.2.7 (#23572) --- Gemfile.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index df50ee38f4..4c6801047c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -164,7 +164,7 @@ GEM activesupport cbor (0.5.9.6) charlock_holmes (0.7.7) - chewy (7.2.4) + chewy (7.2.7) activesupport (>= 5.2) elasticsearch (>= 7.12.0, < 7.14.0) elasticsearch-dsl @@ -230,7 +230,7 @@ GEM fabrication (2.30.0) faker (3.1.1) i18n (>= 1.8.11, < 2) - faraday (1.9.3) + faraday (1.10.3) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -246,8 +246,8 @@ GEM faraday-em_synchrony (1.0.0) faraday-excon (1.1.0) faraday-httpclient (1.0.1) - faraday-multipart (1.0.3) - multipart-post (>= 1.2, < 3) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) faraday-net_http_persistent (1.2.0) faraday-patron (1.0.0) @@ -405,7 +405,7 @@ GEM minitest (5.17.0) msgpack (1.6.0) multi_json (1.15.0) - multipart-post (2.1.1) + multipart-post (2.3.0) net-http (0.3.2) uri net-imap (0.3.4) @@ -754,7 +754,7 @@ GEM xorcist (1.1.3) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.6) + zeitwerk (2.6.7) PLATFORMS ruby From d6930b3847405dc9f8c1a54fb74d488a3c9a775e Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 13 Feb 2023 16:36:29 +0100 Subject: [PATCH 23/28] Add API parameter to safeguard unexpect mentions in new posts (#18350) --- app/controllers/api/v1/statuses_controller.rb | 8 ++++++ app/services/post_status_service.rb | 28 +++++++++++++++++-- app/services/process_mentions_service.rb | 19 +++++++------ .../api/v1/statuses_controller_spec.rb | 17 +++++++++++ spec/services/post_status_service_spec.rb | 21 +++++++++++++- .../services/process_mentions_service_spec.rb | 13 +++++++++ 6 files changed, 94 insertions(+), 12 deletions(-) diff --git a/app/controllers/api/v1/statuses_controller.rb b/app/controllers/api/v1/statuses_controller.rb index 9a8c0c1619..fadd1b0451 100644 --- a/app/controllers/api/v1/statuses_controller.rb +++ b/app/controllers/api/v1/statuses_controller.rb @@ -63,11 +63,18 @@ class Api::V1::StatusesController < Api::BaseController scheduled_at: status_params[:scheduled_at], application: doorkeeper_token.application, poll: status_params[:poll], + allowed_mentions: status_params[:allowed_mentions], idempotency: request.headers['Idempotency-Key'], with_rate_limit: true ) render json: @status, serializer: @status.is_a?(ScheduledStatus) ? REST::ScheduledStatusSerializer : REST::StatusSerializer + rescue PostStatusService::UnexpectedMentionsError => e + unexpected_accounts = ActiveModel::Serializer::CollectionSerializer.new( + e.accounts, + serializer: REST::AccountSerializer + ) + render json: { error: e.message, unexpected_accounts: unexpected_accounts }, status: 422 end def update @@ -128,6 +135,7 @@ class Api::V1::StatusesController < Api::BaseController :visibility, :language, :scheduled_at, + allowed_mentions: [], media_ids: [], media_attributes: [ :id, diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb index bd3b696329..258af8827e 100644 --- a/app/services/post_status_service.rb +++ b/app/services/post_status_service.rb @@ -6,6 +6,15 @@ class PostStatusService < BaseService MIN_SCHEDULE_OFFSET = 5.minutes.freeze + class UnexpectedMentionsError < StandardError + attr_reader :accounts + + def initialize(message, accounts) + super(message) + @accounts = accounts + end + end + # Post a text status update, fetch and notify remote users mentioned # @param [Account] account Account from which to post # @param [Hash] options @@ -21,6 +30,7 @@ class PostStatusService < BaseService # @option [Doorkeeper::Application] :application # @option [String] :idempotency Optional idempotency key # @option [Boolean] :with_rate_limit + # @option [Enumerable] :allowed_mentions Optional array of expected mentioned account IDs, raises `UnexpectedMentionsError` if unexpected accounts end up in mentions # @return [Status] def call(account, options = {}) @account = account @@ -63,14 +73,27 @@ class PostStatusService < BaseService end def process_status! + @status = @account.statuses.new(status_attributes) + process_mentions_service.call(@status, save_records: false) + safeguard_mentions!(@status) + # The following transaction block is needed to wrap the UPDATEs to # the media attachments when the status is created - ApplicationRecord.transaction do - @status = @account.statuses.create!(status_attributes) + @status.save! end end + def safeguard_mentions!(status) + return if @options[:allowed_mentions].nil? + expected_account_ids = @options[:allowed_mentions].map(&:to_i) + + unexpected_accounts = status.mentions.map(&:account).to_a.reject { |mentioned_account| expected_account_ids.include?(mentioned_account.id) } + return if unexpected_accounts.empty? + + raise UnexpectedMentionsError.new('Post would be sent to unexpected accounts', unexpected_accounts) + end + def schedule_status! status_for_validation = @account.statuses.build(status_attributes) @@ -93,7 +116,6 @@ class PostStatusService < BaseService def postprocess_status! process_hashtags_service.call(@status) - process_mentions_service.call(@status) Trends.tags.register(@status) LinkCrawlWorker.perform_async(@status.id) DistributionWorker.perform_async(@status.id) diff --git a/app/services/process_mentions_service.rb b/app/services/process_mentions_service.rb index b117db8c25..93a96667e0 100644 --- a/app/services/process_mentions_service.rb +++ b/app/services/process_mentions_service.rb @@ -3,12 +3,13 @@ class ProcessMentionsService < BaseService include Payloadable - # Scan status for mentions and fetch remote mentioned users, create - # local mention pointers, send Salmon notifications to mentioned - # remote users + # Scan status for mentions and fetch remote mentioned users, + # and create local mention pointers # @param [Status] status - def call(status) + # @param [Boolean] save_records Whether to save records in database + def call(status, save_records: true) @status = status + @save_records = save_records return unless @status.local? @@ -55,14 +56,15 @@ class ProcessMentionsService < BaseService next match if mention_undeliverable?(mentioned_account) || mentioned_account&.suspended? mention = @previous_mentions.find { |x| x.account_id == mentioned_account.id } - mention ||= mentioned_account.mentions.new(status: @status) + mention ||= @current_mentions.find { |x| x.account_id == mentioned_account.id } + mention ||= @status.mentions.new(account: mentioned_account) @current_mentions << mention "@#{mentioned_account.acct}" end - @status.save! + @status.save! if @save_records end def assign_mentions! @@ -73,11 +75,12 @@ class ProcessMentionsService < BaseService mentioned_account_ids = @current_mentions.map(&:account_id) blocked_account_ids = Set.new(@status.account.block_relationships.where(target_account_id: mentioned_account_ids).pluck(:target_account_id)) - @current_mentions.select! { |mention| !(blocked_account_ids.include?(mention.account_id) || blocked_domains.include?(mention.account.domain)) } + dropped_mentions, @current_mentions = @current_mentions.partition { |mention| blocked_account_ids.include?(mention.account_id) || blocked_domains.include?(mention.account.domain) } + dropped_mentions.each(&:destroy) end @current_mentions.each do |mention| - mention.save if mention.new_record? + mention.save if mention.new_record? && @save_records end # If previous mentions are no longer contained in the text, convert them diff --git a/spec/controllers/api/v1/statuses_controller_spec.rb b/spec/controllers/api/v1/statuses_controller_spec.rb index 24810a5d27..bd8b8013a6 100644 --- a/spec/controllers/api/v1/statuses_controller_spec.rb +++ b/spec/controllers/api/v1/statuses_controller_spec.rb @@ -133,6 +133,23 @@ RSpec.describe Api::V1::StatusesController, type: :controller do end end + context 'with a safeguard' do + let!(:alice) { Fabricate(:account, username: 'alice') } + let!(:bob) { Fabricate(:account, username: 'bob') } + + before do + post :create, params: { status: '@alice hm, @bob is really annoying lately', allowed_mentions: [alice.id] } + end + + it 'returns http unprocessable entity' do + expect(response).to have_http_status(422) + end + + it 'returns serialized extra accounts in body' do + expect(body_as_json[:unexpected_accounts].map { |a| a.slice(:id, :acct) }).to eq [{ id: bob.id.to_s, acct: bob.acct }] + end + end + context 'with missing parameters' do before do post :create, params: {} diff --git a/spec/services/post_status_service_spec.rb b/spec/services/post_status_service_spec.rb index d21270c793..28f20e9c70 100644 --- a/spec/services/post_status_service_spec.rb +++ b/spec/services/post_status_service_spec.rb @@ -138,7 +138,26 @@ RSpec.describe PostStatusService, type: :service do status = subject.call(account, text: "test status update") expect(ProcessMentionsService).to have_received(:new) - expect(mention_service).to have_received(:call).with(status) + expect(mention_service).to have_received(:call).with(status, save_records: false) + end + + it 'safeguards mentions' do + account = Fabricate(:account) + mentioned_account = Fabricate(:account, username: 'alice') + unexpected_mentioned_account = Fabricate(:account, username: 'bob') + + expect do + subject.call(account, text: '@alice hm, @bob is really annoying lately', allowed_mentions: [mentioned_account.id]) + end.to raise_error(an_instance_of(PostStatusService::UnexpectedMentionsError).and having_attributes(accounts: [unexpected_mentioned_account])) + end + + it 'processes duplicate mentions correctly' do + account = Fabricate(:account) + mentioned_account = Fabricate(:account, username: 'alice') + + expect do + subject.call(account, text: '@alice @alice @alice hey @alice') + end.not_to raise_error end it 'processes hashtags' do diff --git a/spec/services/process_mentions_service_spec.rb b/spec/services/process_mentions_service_spec.rb index 5b9d17a4c2..0dd62c8070 100644 --- a/spec/services/process_mentions_service_spec.rb +++ b/spec/services/process_mentions_service_spec.rb @@ -47,6 +47,19 @@ RSpec.describe ProcessMentionsService, type: :service do end end + context 'mentioning a user several times when not saving records' do + let!(:remote_user) { Fabricate(:account, username: 'remote_user', protocol: :activitypub, domain: 'example.com', inbox_url: 'http://example.com/inbox') } + let(:status) { Fabricate(:status, account: account, text: "Hello @#{remote_user.acct} @#{remote_user.acct} @#{remote_user.acct}", visibility: :public) } + + before do + subject.call(status, save_records: false) + end + + it 'creates exactly one mention' do + expect(status.mentions.size).to eq 1 + end + end + context 'with an IDN domain' do let!(:remote_user) { Fabricate(:account, username: 'sneak', protocol: :activitypub, domain: 'xn--hresiar-mxa.ch', inbox_url: 'http://example.com/inbox') } let!(:status) { Fabricate(:status, account: account, text: "Hello @sneak@hæresiar.ch") } From 58291b31fa8eff7bb5dd76b605377a33a977fa5a Mon Sep 17 00:00:00 2001 From: Claire Date: Fri, 10 Feb 2023 22:03:35 +0100 Subject: [PATCH 24/28] [Glitch] Fix attached media uploads not being cleared when replying to a post Port bae17ebe5eab02879599ae8516cf6b3f6736b450 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/features/compose/components/upload.js | 5 +++++ app/javascript/flavours/glitch/reducers/compose.js | 2 ++ 2 files changed, 7 insertions(+) diff --git a/app/javascript/flavours/glitch/features/compose/components/upload.js b/app/javascript/flavours/glitch/features/compose/components/upload.js index c82b8d55a0..63582c6367 100644 --- a/app/javascript/flavours/glitch/features/compose/components/upload.js +++ b/app/javascript/flavours/glitch/features/compose/components/upload.js @@ -32,6 +32,11 @@ export default class Upload extends ImmutablePureComponent { render () { const { media } = this.props; + + if (!media) { + return null; + } + const focusX = media.getIn(['meta', 'focus', 'x']); const focusY = media.getIn(['meta', 'focus', 'y']); const x = ((focusX / 2) + .5) * 100; diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js index 57ab36b3d8..c31cc56940 100644 --- a/app/javascript/flavours/glitch/reducers/compose.js +++ b/app/javascript/flavours/glitch/reducers/compose.js @@ -421,6 +421,8 @@ export default function compose(state = initialState, action) { map.set('preselectDate', new Date()); map.set('idempotencyKey', uuid()); + map.update('media_attachments', list => list.filter(media => media.get('unattached'))); + if (action.status.get('language') && !action.status.has('translation')) { map.set('language', action.status.get('language')); } else { From 40fc917a8616898b842ab9f59c81e67a464c3483 Mon Sep 17 00:00:00 2001 From: Dean Bassett Date: Mon, 13 Feb 2023 05:54:08 -0800 Subject: [PATCH 25/28] [Glitch] Fix case-sensitive check for previously used hashtags Port 4da5f77d929d6b83c134cae1eefbc8ba2db752f8 to glitch-soc Signed-off-by: Claire --- app/javascript/flavours/glitch/reducers/compose.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js index c31cc56940..109e4c723f 100644 --- a/app/javascript/flavours/glitch/reducers/compose.js +++ b/app/javascript/flavours/glitch/reducers/compose.js @@ -273,11 +273,12 @@ const ignoreSuggestion = (state, position, token, completion, path) => { }; const sortHashtagsByUse = (state, tags) => { - const personalHistory = state.get('tagHistory'); + const personalHistory = state.get('tagHistory').map(tag => tag.toLowerCase()); - return tags.sort((a, b) => { - const usedA = personalHistory.includes(a.name); - const usedB = personalHistory.includes(b.name); + const tagsWithLowercase = tags.map(t => ({ ...t, lowerName: t.name.toLowerCase() })); + const sorted = tagsWithLowercase.sort((a, b) => { + const usedA = personalHistory.includes(a.lowerName); + const usedB = personalHistory.includes(b.lowerName); if (usedA === usedB) { return 0; @@ -287,6 +288,8 @@ const sortHashtagsByUse = (state, tags) => { return 1; } }); + sorted.forEach(tag => delete tag.lowerName); + return sorted; }; const insertEmoji = (state, position, emojiData) => { From 587f6b3b066360da37066063d659194d43fd7a59 Mon Sep 17 00:00:00 2001 From: Claire Date: Mon, 13 Feb 2023 20:09:01 +0100 Subject: [PATCH 26/28] [Glitch] Enable ESLint import recommended rules Port eddfb33dfea6a17e71377d95498b557dd0194477 to glitch-soc --- .../flavours/glitch/features/audio/index.js | 6 ++--- .../compose/containers/poll_form_container.js | 5 ++++- .../compose/containers/upload_container.js | 3 +-- .../flavours/glitch/features/compose/index.js | 3 +-- .../components/announcements.js | 3 +-- .../containers/column_settings_container.js | 3 +-- .../flavours/glitch/features/status/index.js | 22 +++++++++---------- .../ui/components/focal_point_modal.js | 3 +-- 8 files changed, 22 insertions(+), 26 deletions(-) diff --git a/app/javascript/flavours/glitch/features/audio/index.js b/app/javascript/flavours/glitch/features/audio/index.js index 1a1d438c0c..c4aa989628 100644 --- a/app/javascript/flavours/glitch/features/audio/index.js +++ b/app/javascript/flavours/glitch/features/audio/index.js @@ -1,12 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { defineMessages, FormattedMessage, injectIntl } from 'react-intl'; -import { formatTime } from 'flavours/glitch/features/video'; +import { formatTime, getPointerPosition, fileNameFromURL } from 'flavours/glitch/features/video'; import Icon from 'flavours/glitch/components/icon'; import classNames from 'classnames'; -import { throttle } from 'lodash'; -import { getPointerPosition, fileNameFromURL } from 'flavours/glitch/features/video'; -import { debounce } from 'lodash'; +import { throttle, debounce } from 'lodash'; import Visualizer from './visualizer'; import { displayMedia, useBlurhash } from 'flavours/glitch/initial_state'; import Blurhash from 'flavours/glitch/components/blurhash'; diff --git a/app/javascript/flavours/glitch/features/compose/containers/poll_form_container.js b/app/javascript/flavours/glitch/features/compose/containers/poll_form_container.js index 1e0058341c..14038b3e8c 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/poll_form_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/poll_form_container.js @@ -1,7 +1,10 @@ import { connect } from 'react-redux'; import PollForm from '../components/poll_form'; -import { addPollOption, removePollOption, changePollOption, changePollSettings } from 'flavours/glitch/actions/compose'; import { + addPollOption, + removePollOption, + changePollOption, + changePollSettings, clearComposeSuggestions, fetchComposeSuggestions, selectComposeSuggestion, diff --git a/app/javascript/flavours/glitch/features/compose/containers/upload_container.js b/app/javascript/flavours/glitch/features/compose/containers/upload_container.js index f3ca4ce7bb..2189c870b1 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/upload_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/upload_container.js @@ -1,7 +1,6 @@ import { connect } from 'react-redux'; import Upload from '../components/upload'; -import { undoUploadCompose, initMediaEditModal } from 'flavours/glitch/actions/compose'; -import { submitCompose } from 'flavours/glitch/actions/compose'; +import { undoUploadCompose, initMediaEditModal, submitCompose } from 'flavours/glitch/actions/compose'; const mapStateToProps = (state, { id }) => ({ media: state.getIn(['compose', 'media_attachments']).find(item => item.get('id') === id), diff --git a/app/javascript/flavours/glitch/features/compose/index.js b/app/javascript/flavours/glitch/features/compose/index.js index 68eb05e2c9..241caa03b3 100644 --- a/app/javascript/flavours/glitch/features/compose/index.js +++ b/app/javascript/flavours/glitch/features/compose/index.js @@ -4,7 +4,7 @@ import NavigationContainer from './containers/navigation_container'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { connect } from 'react-redux'; -import { mountCompose, unmountCompose } from 'flavours/glitch/actions/compose'; +import { mountCompose, unmountCompose, cycleElefriendCompose } from 'flavours/glitch/actions/compose'; import { injectIntl, defineMessages } from 'react-intl'; import classNames from 'classnames'; import SearchContainer from './containers/search_container'; @@ -12,7 +12,6 @@ import Motion from '../ui/util/optional_motion'; import spring from 'react-motion/lib/spring'; import SearchResultsContainer from './containers/search_results_container'; import { me, mascot } from 'flavours/glitch/initial_state'; -import { cycleElefriendCompose } from 'flavours/glitch/actions/compose'; import HeaderContainer from './containers/header_container'; import Column from 'flavours/glitch/components/column'; import { Helmet } from 'react-helmet'; diff --git a/app/javascript/flavours/glitch/features/getting_started/components/announcements.js b/app/javascript/flavours/glitch/features/getting_started/components/announcements.js index 5ff4f0523d..fb90244473 100644 --- a/app/javascript/flavours/glitch/features/getting_started/components/announcements.js +++ b/app/javascript/flavours/glitch/features/getting_started/components/announcements.js @@ -6,9 +6,8 @@ import PropTypes from 'prop-types'; import IconButton from 'flavours/glitch/components/icon_button'; import Icon from 'flavours/glitch/components/icon'; import { defineMessages, injectIntl, FormattedMessage, FormattedDate } from 'react-intl'; -import { autoPlayGif, reduceMotion, disableSwiping } from 'flavours/glitch/initial_state'; +import { autoPlayGif, reduceMotion, disableSwiping, mascot } from 'flavours/glitch/initial_state'; import elephantUIPlane from 'mastodon/../images/elephant_ui_plane.svg'; -import { mascot } from 'flavours/glitch/initial_state'; import unicodeMapping from 'flavours/glitch/features/emoji/emoji_unicode_mapping_light'; import classNames from 'classnames'; import EmojiPickerDropdown from 'flavours/glitch/features/compose/containers/emoji_picker_dropdown_container'; diff --git a/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js b/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js index c2564f44ea..27c2f96fe4 100644 --- a/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js +++ b/app/javascript/flavours/glitch/features/notifications/containers/column_settings_container.js @@ -2,8 +2,7 @@ import { connect } from 'react-redux'; import { defineMessages, injectIntl } from 'react-intl'; import ColumnSettings from '../components/column_settings'; import { changeSetting } from 'flavours/glitch/actions/settings'; -import { setFilter } from 'flavours/glitch/actions/notifications'; -import { clearNotifications, requestBrowserPermission } from 'flavours/glitch/actions/notifications'; +import { setFilter, clearNotifications, requestBrowserPermission } from 'flavours/glitch/actions/notifications'; import { changeAlerts as changePushNotifications } from 'flavours/glitch/actions/push_notifications'; import { openModal } from 'flavours/glitch/actions/modal'; import { showAlert } from 'flavours/glitch/actions/alerts'; diff --git a/app/javascript/flavours/glitch/features/status/index.js b/app/javascript/flavours/glitch/features/status/index.js index 9b49d41e4a..cbab90e81f 100644 --- a/app/javascript/flavours/glitch/features/status/index.js +++ b/app/javascript/flavours/glitch/features/status/index.js @@ -5,7 +5,17 @@ import PropTypes from 'prop-types'; import classNames from 'classnames'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { createSelector } from 'reselect'; -import { fetchStatus } from 'flavours/glitch/actions/statuses'; +import { + fetchStatus, + muteStatus, + unmuteStatus, + deleteStatus, + editStatus, + hideStatus, + revealStatus, + translateStatus, + undoStatusTranslation, +} from 'flavours/glitch/actions/statuses'; import MissingIndicator from 'flavours/glitch/components/missing_indicator'; import LoadingIndicator from 'flavours/glitch/components/loading_indicator'; import DetailedStatus from './components/detailed_status'; @@ -27,16 +37,6 @@ import { directCompose, } from 'flavours/glitch/actions/compose'; import { changeLocalSetting } from 'flavours/glitch/actions/local_settings'; -import { - muteStatus, - unmuteStatus, - deleteStatus, - editStatus, - hideStatus, - revealStatus, - translateStatus, - undoStatusTranslation, -} from 'flavours/glitch/actions/statuses'; import { initMuteModal } from 'flavours/glitch/actions/mutes'; import { initBlockModal } from 'flavours/glitch/actions/blocks'; import { initReport } from 'flavours/glitch/actions/reports'; diff --git a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js index e36657fabc..8e624adb3e 100644 --- a/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/focal_point_modal.js @@ -5,11 +5,10 @@ import ImmutablePureComponent from 'react-immutable-pure-component'; import { connect } from 'react-redux'; import classNames from 'classnames'; import { changeUploadCompose, uploadThumbnail, onChangeMediaDescription, onChangeMediaFocus } from 'flavours/glitch/actions/compose'; -import { getPointerPosition } from 'flavours/glitch/features/video'; +import Video, { getPointerPosition } from 'flavours/glitch/features/video'; import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; import IconButton from 'flavours/glitch/components/icon_button'; import Button from 'flavours/glitch/components/button'; -import Video from 'flavours/glitch/features/video'; import Audio from 'flavours/glitch/features/audio'; import Textarea from 'react-textarea-autosize'; import UploadProgress from 'flavours/glitch/features/compose/components/upload_progress'; From 7e64eef73b62fcb1537181e66bcd3e5e25fcc665 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Mon, 13 Feb 2023 09:12:14 -0500 Subject: [PATCH 27/28] [Glitch] Enable ESLint no-useless-escape Port db2c58d47ae0db8490a30cd3846f30e615c382b5 to glitch-soc Signed-off-by: Claire --- .../flavours/glitch/actions/push_notifications/registerer.js | 2 +- .../glitch/features/compose/containers/warning_container.js | 2 +- app/javascript/flavours/glitch/features/compose/util/counter.js | 2 +- app/javascript/flavours/glitch/features/emoji/emoji_utils.js | 2 +- .../features/follow_recommendations/components/account.js | 2 +- app/javascript/flavours/glitch/utils/hashtag.js | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/app/javascript/flavours/glitch/actions/push_notifications/registerer.js b/app/javascript/flavours/glitch/actions/push_notifications/registerer.js index 762fe260c7..bc5634233f 100644 --- a/app/javascript/flavours/glitch/actions/push_notifications/registerer.js +++ b/app/javascript/flavours/glitch/actions/push_notifications/registerer.js @@ -6,7 +6,7 @@ import { setBrowserSupport, setSubscription, clearSubscription } from './setter' const urlBase64ToUint8Array = (base64String) => { const padding = '='.repeat((4 - base64String.length % 4) % 4); const base64 = (base64String + padding) - .replace(/\-/g, '+') + .replace(/-/g, '+') .replace(/_/g, '/'); const rawData = window.atob(base64); diff --git a/app/javascript/flavours/glitch/features/compose/containers/warning_container.js b/app/javascript/flavours/glitch/features/compose/containers/warning_container.js index 9402601f85..5b48c45e43 100644 --- a/app/javascript/flavours/glitch/features/compose/containers/warning_container.js +++ b/app/javascript/flavours/glitch/features/compose/containers/warning_container.js @@ -25,7 +25,7 @@ const buildHashtagRE = () => { '))', 'iu', ); } catch { - return /(?:^|[^\/\)\w])#(\w*[a-zA-Z·]\w*)/i; + return /(?:^|[^/)\w])#(\w*[a-zA-Z·]\w*)/i; } }; diff --git a/app/javascript/flavours/glitch/features/compose/util/counter.js b/app/javascript/flavours/glitch/features/compose/util/counter.js index 5a68bad992..ec2431096b 100644 --- a/app/javascript/flavours/glitch/features/compose/util/counter.js +++ b/app/javascript/flavours/glitch/features/compose/util/counter.js @@ -5,5 +5,5 @@ const urlPlaceholder = '$2xxxxxxxxxxxxxxxxxxxxxxx'; export function countableText(inputText) { return inputText .replace(urlRegex, urlPlaceholder) - .replace(/(^|[^\/\w])@(([a-z0-9_]+)@[a-z0-9\.\-]+[a-z0-9]+)/ig, '$1@$3'); + .replace(/(^|[^/\w])@(([a-z0-9_]+)@[a-z0-9.-]+[a-z0-9]+)/ig, '$1@$3'); } diff --git a/app/javascript/flavours/glitch/features/emoji/emoji_utils.js b/app/javascript/flavours/glitch/features/emoji/emoji_utils.js index 571907a509..be793526d0 100644 --- a/app/javascript/flavours/glitch/features/emoji/emoji_utils.js +++ b/app/javascript/flavours/glitch/features/emoji/emoji_utils.js @@ -73,7 +73,7 @@ const stringFromCodePoint = _String.fromCodePoint || function () { const _JSON = JSON; -const COLONS_REGEX = /^(?:\:([^\:]+)\:)(?:\:skin-tone-(\d)\:)?$/; +const COLONS_REGEX = /^(?::([^:]+):)(?::skin-tone-(\d):)?$/; const SKINS = [ '1F3FA', '1F3FB', '1F3FC', '1F3FD', '1F3FE', '1F3FF', diff --git a/app/javascript/flavours/glitch/features/follow_recommendations/components/account.js b/app/javascript/flavours/glitch/features/follow_recommendations/components/account.js index 7c8a71879d..81d39bd49b 100644 --- a/app/javascript/flavours/glitch/features/follow_recommendations/components/account.js +++ b/app/javascript/flavours/glitch/features/follow_recommendations/components/account.js @@ -27,7 +27,7 @@ const makeMapStateToProps = () => { }; const getFirstSentence = str => { - const arr = str.split(/(([\.\?!]+\s)|[.。?!\n•])/); + const arr = str.split(/(([.?!]+\s)|[.。?!\n•])/); return arr[0]; }; diff --git a/app/javascript/flavours/glitch/utils/hashtag.js b/app/javascript/flavours/glitch/utils/hashtag.js index 8f5665c466..d91cd5591a 100644 --- a/app/javascript/flavours/glitch/utils/hashtag.js +++ b/app/javascript/flavours/glitch/utils/hashtag.js @@ -1,6 +1,6 @@ export function recoverHashtags (recognizedTags, text) { return recognizedTags.map(tag => { - const re = new RegExp(`(?:^|[^\/)\w])#(${tag.name})`, 'i'); + const re = new RegExp(`(?:^|[^/)\w])#(${tag.name})`, 'i'); const matched_hashtag = text.match(re); return matched_hashtag ? matched_hashtag[1] : null; }, From ea9a1d79df60749eb21fb592c608dcaa4c935c75 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Sun, 12 Feb 2023 22:57:03 -0500 Subject: [PATCH 28/28] [Glitch] Upgrade to Stylelint 15 with Prettier Port 0c9d455ea5540e854c2d879cd1df015ea493f622 to glitch-soc Signed-off-by: Claire --- .prettierignore | 10 +- .../flavours/glitch/styles/_mixins.scss | 5 +- .../flavours/glitch/styles/accessibility.scss | 7 +- .../flavours/glitch/styles/admin.scss | 25 +++-- .../flavours/glitch/styles/basics.scss | 10 +- .../glitch/styles/components/accounts.scss | 34 ++++--- .../styles/components/announcements.scss | 6 +- .../glitch/styles/components/columns.scss | 17 ++-- .../styles/components/compose_form.scss | 99 ++++++++++++++----- .../glitch/styles/components/directory.scss | 10 +- .../glitch/styles/components/doodle.scss | 12 ++- .../glitch/styles/components/drawer.scss | 41 ++++++-- .../glitch/styles/components/emoji.scss | 2 +- .../styles/components/emoji_picker.scss | 8 +- .../glitch/styles/components/index.scss | 36 ++++--- .../styles/components/local_settings.scss | 11 ++- .../glitch/styles/components/media.scss | 18 ++-- .../glitch/styles/components/modal.scss | 12 ++- .../styles/components/privacy_policy.scss | 4 +- .../glitch/styles/components/sensitive.scss | 8 +- .../styles/components/single_column.scss | 2 +- .../glitch/styles/components/status.scss | 73 ++++++++++---- .../glitch/styles/contrast/variables.scss | 2 +- .../flavours/glitch/styles/forms.scss | 48 +++++---- .../glitch/styles/mastodon-light/diff.scss | 43 +++++--- .../flavours/glitch/styles/modal.scss | 4 +- .../flavours/glitch/styles/polls.scss | 12 ++- .../flavours/glitch/styles/rtl.scss | 18 ++-- .../flavours/glitch/styles/statuses.scss | 2 +- .../flavours/glitch/styles/variables.scss | 31 +++--- .../flavours/glitch/styles/widgets.scss | 2 +- 31 files changed, 406 insertions(+), 206 deletions(-) diff --git a/.prettierignore b/.prettierignore index d04207d394..e55c284164 100644 --- a/.prettierignore +++ b/.prettierignore @@ -74,9 +74,15 @@ docker-compose.override.yml # Ignore vendored CSS reset app/javascript/styles/mastodon/reset.scss +# Ignore glitch-soc emoji map file +/app/javascript/flavours/glitch/features/emoji/emoji_map.json + # Ignore glitch-soc locale files /app/javascript/flavours/glitch/locales /config/locales-glitch -# Ignore glitch-soc emoji map file -/app/javascript/flavours/glitch/features/emoji/emoji_map.json +# Ignore glitch-soc vendored CSS reset +app/javascript/flavours/glitch/styles/reset.scss + +# Ignore win95 theme +app/javascript/styles/win95.scss diff --git a/app/javascript/flavours/glitch/styles/_mixins.scss b/app/javascript/flavours/glitch/styles/_mixins.scss index 9f6314f3f4..90f748c51d 100644 --- a/app/javascript/flavours/glitch/styles/_mixins.scss +++ b/app/javascript/flavours/glitch/styles/_mixins.scss @@ -4,7 +4,7 @@ background-clip: padding-box; } -@mixin avatar-size($size:48px) { +@mixin avatar-size($size: 48px) { width: $size; height: $size; background-size: $size $size; @@ -22,7 +22,8 @@ } @mixin limited-single-column($media, $parent: '&') { - .auto-columns #{$parent}, .single-column #{$parent} { + .auto-columns #{$parent}, + .single-column #{$parent} { @media #{$media} { @content; } diff --git a/app/javascript/flavours/glitch/styles/accessibility.scss b/app/javascript/flavours/glitch/styles/accessibility.scss index 7bffb2e264..fb2376abfd 100644 --- a/app/javascript/flavours/glitch/styles/accessibility.scss +++ b/app/javascript/flavours/glitch/styles/accessibility.scss @@ -1,4 +1,7 @@ -$emojis-requiring-inversion: 'back' 'copyright' 'curly_loop' 'currency_exchange' 'end' 'heavy_check_mark' 'heavy_division_sign' 'heavy_dollar_sign' 'heavy_minus_sign' 'heavy_multiplication_x' 'heavy_plus_sign' 'on' 'registered' 'soon' 'spider' 'telephone_receiver' 'tm' 'top' 'wavy_dash' !default; +$emojis-requiring-inversion: 'back' 'copyright' 'curly_loop' 'currency_exchange' + 'end' 'heavy_check_mark' 'heavy_division_sign' 'heavy_dollar_sign' + 'heavy_minus_sign' 'heavy_multiplication_x' 'heavy_plus_sign' 'on' + 'registered' 'soon' 'spider' 'telephone_receiver' 'tm' 'top' 'wavy_dash' !default; %emoji-color-inversion { filter: invert(1); @@ -19,7 +22,7 @@ $emojis-requiring-inversion: 'back' 'copyright' 'curly_loop' 'currency_exchange' &.active::after { position: absolute; - content: "\F00C"; + content: '\F00C'; font-size: 50%; font-family: FontAwesome; right: -0.55em; diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index 9aa2318ce5..61036fc70c 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -1,4 +1,4 @@ -@use "sass:math"; +@use 'sass:math'; $no-columns-breakpoint: 600px; $sidebar-width: 240px; @@ -350,7 +350,7 @@ $content-width: 840px; width: 100%; height: 0; border: 0; - border-bottom: 1px solid rgba($ui-base-lighter-color, .6); + border-bottom: 1px solid rgba($ui-base-lighter-color, 0.6); margin: 20px 0; &.spacer { @@ -1147,7 +1147,10 @@ a.name-tag, @for $i from 0 through 10 { &--#{10 * $i} { - background-color: rgba($ui-highlight-color, 1 * (math.div(max(1, $i), 10))); + background-color: rgba( + $ui-highlight-color, + 1 * (math.div(max(1, $i), 10)) + ); } } } @@ -1236,7 +1239,12 @@ a.sparkline { .skeleton { background-color: lighten($ui-base-color, 8%); - background-image: linear-gradient(90deg, lighten($ui-base-color, 8%), lighten($ui-base-color, 12%), lighten($ui-base-color, 8%)); + background-image: linear-gradient( + 90deg, + lighten($ui-base-color, 8%), + lighten($ui-base-color, 12%), + lighten($ui-base-color, 8%) + ); background-size: 200px 100%; background-repeat: no-repeat; border-radius: 4px; @@ -1285,7 +1293,10 @@ a.sparkline { @for $i from 0 through 10 { &--#{10 * $i} { - background-color: rgba($ui-highlight-color, 1 * (math.div(max(1, $i), 10))); + background-color: rgba( + $ui-highlight-color, + 1 * (math.div(max(1, $i), 10)) + ); } } } @@ -1431,7 +1442,7 @@ a.sparkline { &::after { display: block; - content: ""; + content: ''; width: 50px; height: 21px; position: absolute; @@ -1825,7 +1836,7 @@ a.sparkline { &::after { position: absolute; - content: ""; + content: ''; width: 1px; background: $highlight-text-color; bottom: 0; diff --git a/app/javascript/flavours/glitch/styles/basics.scss b/app/javascript/flavours/glitch/styles/basics.scss index a00b2936f0..25aa68f7e2 100644 --- a/app/javascript/flavours/glitch/styles/basics.scss +++ b/app/javascript/flavours/glitch/styles/basics.scss @@ -2,7 +2,7 @@ @if type-of($color) == 'color' { $color: str-slice(ie-hex-str($color), 4); } - @return '%23' + unquote($color) + @return '%23' + unquote($color); } body { @@ -13,9 +13,9 @@ body { font-weight: 400; color: $primary-text-color; text-rendering: optimizelegibility; - font-feature-settings: "kern"; + font-feature-settings: 'kern'; text-size-adjust: none; - -webkit-tap-highlight-color: rgba(0,0,0,0); + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); -webkit-tap-highlight-color: transparent; &.system-font { @@ -30,7 +30,9 @@ body { // Droid Sans => Older Androids (<4.0) // Helvetica Neue => Older macOS <10.11 // $font-sans-serif => web-font (Roboto) fallback and newer Androids (>=4.0) - font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", $font-sans-serif, sans-serif; + font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', + 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', + 'Helvetica Neue', $font-sans-serif, sans-serif; } &.app-body { diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss index c2a6593b1a..89faaae6ad 100644 --- a/app/javascript/flavours/glitch/styles/components/accounts.scss +++ b/app/javascript/flavours/glitch/styles/components/accounts.scss @@ -30,7 +30,9 @@ border: 0; padding: 0; - & > .account__avatar-wrapper { margin: 0 8px 0 0 } + & > .account__avatar-wrapper { + margin: 0 8px 0 0; + } & > .display-name { height: 24px; @@ -379,7 +381,7 @@ &::before, &::after { display: block; - content: ""; + content: ''; position: absolute; bottom: 0; left: 50%; @@ -710,22 +712,22 @@ padding: 2px 6px; color: $darker-text-color; - &:hover, - &:active, - &:focus { - color: lighten($darker-text-color, 7%); - background-color: rgba($darker-text-color, 0.15); - } + &:hover, + &:active, + &:focus { + color: lighten($darker-text-color, 7%); + background-color: rgba($darker-text-color, 0.15); + } - &:focus { - background-color: rgba($darker-text-color, 0.3); - } + &:focus { + background-color: rgba($darker-text-color, 0.3); + } - &[disabled] { - color: darken($darker-text-color, 13%); - background-color: transparent; - cursor: default; - } + &[disabled] { + color: darken($darker-text-color, 13%); + background-color: transparent; + cursor: default; + } } .flex-spacer { diff --git a/app/javascript/flavours/glitch/styles/components/announcements.scss b/app/javascript/flavours/glitch/styles/components/announcements.scss index 85af9afc83..feaff81f52 100644 --- a/app/javascript/flavours/glitch/styles/components/announcements.scss +++ b/app/javascript/flavours/glitch/styles/components/announcements.scss @@ -181,7 +181,11 @@ &.active { transition: all 100ms ease-in; transition-property: background-color, color; - background-color: mix(lighten($ui-base-color, 12%), $ui-highlight-color, 80%); + background-color: mix( + lighten($ui-base-color, 12%), + $ui-highlight-color, + 80% + ); .reactions-bar__item__count { color: lighten($highlight-text-color, 8%); diff --git a/app/javascript/flavours/glitch/styles/components/columns.scss b/app/javascript/flavours/glitch/styles/components/columns.scss index 42a5919319..263a9ce785 100644 --- a/app/javascript/flavours/glitch/styles/components/columns.scss +++ b/app/javascript/flavours/glitch/styles/components/columns.scss @@ -286,7 +286,7 @@ $ui-header-height: 55px; &::before { display: block; - content: ""; + content: ''; position: absolute; bottom: -13px; left: 0; @@ -296,7 +296,11 @@ $ui-header-height: 55px; pointer-events: none; height: 28px; z-index: 1; - background: radial-gradient(ellipse, rgba($ui-highlight-color, 0.23) 0%, rgba($ui-highlight-color, 0) 60%); + background: radial-gradient( + ellipse, + rgba($ui-highlight-color, 0.23) 0%, + rgba($ui-highlight-color, 0) 60% + ); } } @@ -435,10 +439,10 @@ $ui-header-height: 55px; } } - .layout-single-column .column-header__notif-cleaning-buttons { @media screen and (min-width: $no-gap-breakpoint) { - b, i { + b, + i { margin-right: 5px; } @@ -622,7 +626,8 @@ $ui-header-height: 55px; flex: 1 1 auto; align-items: center; justify-content: center; - @supports(display: grid) { // hack to fix Chrome <57 + @supports (display: grid) { + // hack to fix Chrome <57 contain: strict; } @@ -916,7 +921,7 @@ $ui-header-height: 55px; p { font-size: 16px; - line-height: 24px; + line-height: 24px; font-weight: 400; color: $darker-text-color; } diff --git a/app/javascript/flavours/glitch/styles/components/compose_form.scss b/app/javascript/flavours/glitch/styles/components/compose_form.scss index 40adf28c9d..4b800dcd8f 100644 --- a/app/javascript/flavours/glitch/styles/components/compose_form.scss +++ b/app/javascript/flavours/glitch/styles/components/compose_form.scss @@ -32,12 +32,12 @@ .spoiler-input { height: 0; transform-origin: bottom; - opacity: 0.0; + opacity: 0; &.spoiler-input--visible { height: 36px; margin-bottom: 11px; - opacity: 1.0; + opacity: 1; } input { @@ -59,8 +59,12 @@ color: $dark-text-color; } - &:focus { outline: 0 } - @include single-column('screen and (max-width: 630px)') { font-size: 16px } + &:focus { + outline: 0; + } + @include single-column('screen and (max-width: 630px)') { + font-size: 16px; + } } } @@ -98,7 +102,7 @@ color: $highlight-text-color; } - input[type=checkbox] { + input[type='checkbox'] { display: none; } @@ -118,7 +122,9 @@ &.active { border-color: $highlight-text-color; - background: $highlight-text-color url("data:image/svg+xml;utf8,") center center no-repeat; + background: $highlight-text-color + url("data:image/svg+xml;utf8,") + center center no-repeat; } } } @@ -137,7 +143,9 @@ margin-bottom: 5px; overflow: hidden; - & > .account.small { color: $inverted-text-color; } + & > .account.small { + color: $inverted-text-color; + } } .reply-indicator__cancel { @@ -159,7 +167,9 @@ padding-top: 5px; overflow: hidden; - p, pre, blockquote { + p, + pre, + blockquote { margin-bottom: 20px; white-space: pre-wrap; @@ -168,12 +178,17 @@ } } - h1, h2, h3, h4, h5 { + h1, + h2, + h3, + h4, + h5 { margin-top: 20px; margin-bottom: 20px; } - h1, h2 { + h1, + h2 { font-weight: 700; font-size: 18px; } @@ -182,7 +197,9 @@ font-size: 16px; } - h3, h4, h5 { + h3, + h4, + h5 { font-weight: 500; } @@ -197,11 +214,13 @@ } } - b, strong { + b, + strong { font-weight: 700; } - em, i { + em, + i { font-style: italic; } @@ -215,7 +234,8 @@ vertical-align: super; } - ul, ol { + ul, + ol { margin-left: 1em; p { @@ -235,13 +255,17 @@ color: $lighter-text-color; text-decoration: none; - &:hover { text-decoration: underline } + &:hover { + text-decoration: underline; + } &.mention { &:hover { text-decoration: none; - span { text-decoration: underline } + span { + text-decoration: underline; + } } } } @@ -321,7 +345,7 @@ font-size: 18px; line-height: 24px; text-align: center; - opacity: .8; + opacity: 0.8; } } @@ -358,7 +382,9 @@ &:hover, &:focus, &:active, - &.selected { background: darken($ui-secondary-color, 10%) } + &.selected { + background: darken($ui-secondary-color, 10%); + } > .account, > .emoji, @@ -396,7 +422,9 @@ & > .account.small { .display-name { - & > span { color: $lighter-text-color } + & > span { + color: $lighter-text-color; + } } } } @@ -430,7 +458,9 @@ background-repeat: no-repeat; overflow: hidden; - & > .close { mix-blend-mode: difference } + & > .close { + mix-blend-mode: difference; + } } .icon-button { @@ -455,12 +485,22 @@ left: 0; right: 0; box-sizing: border-box; - background: linear-gradient(0deg, rgba($base-shadow-color, 0.8) 0, rgba($base-shadow-color, 0.35) 80%, transparent); + background: linear-gradient( + 0deg, + rgba($base-shadow-color, 0.8) 0, + rgba($base-shadow-color, 0.35) 80%, + transparent + ); } } .compose-form__upload__actions { - background: linear-gradient(180deg, rgba($base-shadow-color, 0.8) 0, rgba($base-shadow-color, 0.35) 80%, transparent); + background: linear-gradient( + 180deg, + rgba($base-shadow-color, 0.8) 0, + rgba($base-shadow-color, 0.35) 80%, + transparent + ); display: flex; align-items: flex-start; justify-content: space-between; @@ -543,7 +583,8 @@ margin: 0 3px; border-width: 0 0 0 1px; border-style: none none none solid; - border-color: transparent transparent transparent darken($simple-background-color, 24%); + border-color: transparent transparent transparent + darken($simple-background-color, 24%); padding: 0; width: 0; height: 27px; @@ -604,7 +645,9 @@ flex: 1 1 auto; color: $lighter-text-color; - &:not(:first-child) { margin-left: 10px } + &:not(:first-child) { + margin-left: 10px; + } strong { display: block; @@ -621,11 +664,15 @@ .privacy-dropdown__option__content { color: $primary-text-color; - strong { color: $primary-text-color } + strong { + color: $primary-text-color; + } } } - &.active:hover { background: lighten($ui-highlight-color, 4%) } + &.active:hover { + background: lighten($ui-highlight-color, 4%); + } } .compose-form__publish { diff --git a/app/javascript/flavours/glitch/styles/components/directory.scss b/app/javascript/flavours/glitch/styles/components/directory.scss index 803e075c9e..4c914f1638 100644 --- a/app/javascript/flavours/glitch/styles/components/directory.scss +++ b/app/javascript/flavours/glitch/styles/components/directory.scss @@ -11,7 +11,11 @@ } .scrollable .account-card__bio::after { - background: linear-gradient(to left, lighten($ui-base-color, 8%), transparent); + background: linear-gradient( + to left, + lighten($ui-base-color, 8%), + transparent + ); } .filter-form { @@ -39,8 +43,8 @@ text-overflow: ellipsis; cursor: pointer; - input[type=radio], - input[type=checkbox] { + input[type='radio'], + input[type='checkbox'] { display: none; } diff --git a/app/javascript/flavours/glitch/styles/components/doodle.scss b/app/javascript/flavours/glitch/styles/components/doodle.scss index a4a1cfc84d..eddc1a2a81 100644 --- a/app/javascript/flavours/glitch/styles/components/doodle.scss +++ b/app/javascript/flavours/glitch/styles/components/doodle.scss @@ -38,7 +38,8 @@ $doodleBg: #d9e1e8; margin-right: 2px; } - input[type="number"],input[type="text"] { + input[type='number'], + input[type='text'] { width: 40px; } span.val { @@ -52,7 +53,7 @@ $doodleBg: #d9e1e8; .doodle-palette { padding-right: 0 !important; border: 1px solid black; - line-height: .2rem; + line-height: 0.2rem; flex-grow: 0; background: white; @@ -60,14 +61,15 @@ $doodleBg: #d9e1e8; appearance: none; width: 1rem; height: 1rem; - margin: 0; padding: 0; + margin: 0; + padding: 0; text-align: center; color: black; text-shadow: 0 0 1px white; cursor: pointer; - box-shadow: inset 0 0 1px rgba(white, .5); + box-shadow: inset 0 0 1px rgba(white, 0.5); border: 1px solid black; - outline-offset:-1px; + outline-offset: -1px; &.foreground { outline: 1px dashed white; diff --git a/app/javascript/flavours/glitch/styles/components/drawer.scss b/app/javascript/flavours/glitch/styles/components/drawer.scss index cf996fb71c..2c2f251683 100644 --- a/app/javascript/flavours/glitch/styles/components/drawer.scss +++ b/app/javascript/flavours/glitch/styles/components/drawer.scss @@ -34,7 +34,8 @@ } @include single-column('screen and (max-width: 630px)') { - :root & { // Overrides `.wide` for single-column view + :root & { + // Overrides `.wide` for single-column view flex: auto; width: 100%; min-width: 0; @@ -43,7 +44,9 @@ } } - .react-swipeable-view-container & { height: 100% } + .react-swipeable-view-container & { + height: 100%; + } } .drawer--header { @@ -84,8 +87,14 @@ margin-bottom: 10px; flex: none; - @include limited-single-column('screen and (max-width: #{$no-gap-breakpoint})') { margin-bottom: 0 } - @include single-column('screen and (max-width: 630px)') { font-size: 16px } + @include limited-single-column( + 'screen and (max-width: #{$no-gap-breakpoint})' + ) { + margin-bottom: 0; + } + @include single-column('screen and (max-width: 630px)') { + font-size: 16px; + } } .search-popout { @@ -192,7 +201,9 @@ } .drawer__inner__mastodon { - background: lighten($ui-base-color, 13%) url('data:image/svg+xml;utf8,') no-repeat bottom / 100% auto; + background: lighten($ui-base-color, 13%) + url('data:image/svg+xml;utf8,') + no-repeat bottom / 100% auto; flex: 1; min-height: 47px; display: none; @@ -240,13 +251,27 @@ @for $i from 0 through 3 { .mbstobon-#{$i} .drawer__inner__mastodon { @if $i == 3 { - background: url('~flavours/glitch/images/wave-drawer.png') no-repeat bottom / 100% auto, lighten($ui-base-color, 13%); + background: url('~flavours/glitch/images/wave-drawer.png') + no-repeat + bottom / + 100% + auto, + lighten($ui-base-color, 13%); } @else { - background: url('~flavours/glitch/images/wave-drawer-glitched.png') no-repeat bottom / 100% auto, lighten($ui-base-color, 13%); + background: url('~flavours/glitch/images/wave-drawer-glitched.png') + no-repeat + bottom / + 100% + auto, + lighten($ui-base-color, 13%); } & > .mastodon { - background: url("~flavours/glitch/images/mbstobon-ui-#{$i}.png") no-repeat left bottom / contain; + background: url('~flavours/glitch/images/mbstobon-ui-#{$i}.png') + no-repeat + left + bottom / + contain; @if $i != 3 { filter: contrast(50%) brightness(50%); diff --git a/app/javascript/flavours/glitch/styles/components/emoji.scss b/app/javascript/flavours/glitch/styles/components/emoji.scss index c037e03f97..4427f2080d 100644 --- a/app/javascript/flavours/glitch/styles/components/emoji.scss +++ b/app/javascript/flavours/glitch/styles/components/emoji.scss @@ -2,7 +2,7 @@ font-size: inherit; vertical-align: middle; object-fit: contain; - margin: -.2ex .15em .2ex; + margin: -0.2ex 0.15em 0.2ex; width: 16px; height: 16px; diff --git a/app/javascript/flavours/glitch/styles/components/emoji_picker.scss b/app/javascript/flavours/glitch/styles/components/emoji_picker.scss index 790650cfa3..6bb9827b3a 100644 --- a/app/javascript/flavours/glitch/styles/components/emoji_picker.scss +++ b/app/javascript/flavours/glitch/styles/components/emoji_picker.scss @@ -46,7 +46,7 @@ text-align: center; padding: 12px 4px; overflow: hidden; - transition: color .1s ease-out; + transition: color 0.1s ease-out; cursor: pointer; background: transparent; border: 0; @@ -174,7 +174,7 @@ &:hover::before { z-index: 0; - content: ""; + content: ''; position: absolute; top: 0; left: 0; @@ -246,8 +246,8 @@ padding: 5px 6px; padding-top: 70px; - .emoji-mart-no-results-label { - margin-top: .2em; + .emoji-mart-no-results-label { + margin-top: 0.2em; } .emoji-mart-emoji:hover::before { diff --git a/app/javascript/flavours/glitch/styles/components/index.scss b/app/javascript/flavours/glitch/styles/components/index.scss index d4c0d77c84..c52f395120 100644 --- a/app/javascript/flavours/glitch/styles/components/index.scss +++ b/app/javascript/flavours/glitch/styles/components/index.scss @@ -370,7 +370,7 @@ body > [data-popper-placement] { .ellipsis { &::after { - content: "…"; + content: '…'; } } @@ -480,11 +480,11 @@ body > [data-popper-placement] { justify-content: center; flex-direction: column; scrollbar-width: none; /* Firefox */ - -ms-overflow-style: none; /* IE 10+ */ + -ms-overflow-style: none; /* IE 10+ */ * { scrollbar-width: none; /* Firefox */ - -ms-overflow-style: none; /* IE 10+ */ + -ms-overflow-style: none; /* IE 10+ */ } &::-webkit-scrollbar, @@ -950,7 +950,8 @@ body > [data-popper-placement] { overflow-y: auto; } - @supports(display: grid) { // hack to fix Chrome <57 + @supports (display: grid) { + // hack to fix Chrome <57 contain: strict; } @@ -971,7 +972,8 @@ body > [data-popper-placement] { } .scrollable.fullscreen { - @supports(display: grid) { // hack to fix Chrome <57 + @supports (display: grid) { + // hack to fix Chrome <57 contain: none; } } @@ -1014,7 +1016,8 @@ body > [data-popper-placement] { transition: background-color 0.2s ease; } -.react-toggle:is(:hover, :focus-within):not(.react-toggle--disabled) .react-toggle-track { +.react-toggle:is(:hover, :focus-within):not(.react-toggle--disabled) + .react-toggle-track { background-color: darken($ui-base-color, 10%); } @@ -1022,7 +1025,8 @@ body > [data-popper-placement] { background-color: darken($ui-highlight-color, 2%); } -.react-toggle--checked:is(:hover, :focus-within):not(.react-toggle--disabled) .react-toggle-track { +.react-toggle--checked:is(:hover, :focus-within):not(.react-toggle--disabled) + .react-toggle-track { background-color: $ui-highlight-color; } @@ -1654,8 +1658,8 @@ button.icon-button.active i.fa-retweet { .icon-badge { position: absolute; display: block; - right: -.25em; - top: -.25em; + right: -0.25em; + top: -0.25em; background-color: $ui-highlight-color; border-radius: 50%; font-size: 75%; @@ -1688,7 +1692,7 @@ button.icon-button.active i.fa-retweet { border-radius: 50%; width: 0.625rem; height: 0.625rem; - margin: -.1ex .15em .1ex; + margin: -0.1ex 0.15em 0.1ex; } &__content { @@ -1797,9 +1801,15 @@ noscript { } @keyframes flicker { - 0% { opacity: 1; } - 30% { opacity: 0.75; } - 100% { opacity: 1; } + 0% { + opacity: 1; + } + 30% { + opacity: 0.75; + } + 100% { + opacity: 1; + } } @import 'boost'; diff --git a/app/javascript/flavours/glitch/styles/components/local_settings.scss b/app/javascript/flavours/glitch/styles/components/local_settings.scss index f36b21e1cd..cd441a0c03 100644 --- a/app/javascript/flavours/glitch/styles/components/local_settings.scss +++ b/app/javascript/flavours/glitch/styles/components/local_settings.scss @@ -11,12 +11,14 @@ max-height: 450px; overflow: hidden; - label, legend { + label, + legend { display: block; font-size: 14px; } - .boolean label, .radio_buttons label { + .boolean label, + .radio_buttons label { position: relative; padding-left: 28px; padding-top: 3px; @@ -58,7 +60,7 @@ cursor: pointer; text-decoration: none; outline: none; - transition: background .3s; + transition: background 0.3s; .text-icon-button { color: inherit; @@ -74,7 +76,8 @@ color: $primary-text-color; } - &.close, &.close:hover { + &.close, + &.close:hover { background: $error-value-color; color: $primary-text-color; } diff --git a/app/javascript/flavours/glitch/styles/components/media.scss b/app/javascript/flavours/glitch/styles/components/media.scss index 9776e22659..0216daa127 100644 --- a/app/javascript/flavours/glitch/styles/components/media.scss +++ b/app/javascript/flavours/glitch/styles/components/media.scss @@ -348,7 +348,7 @@ padding: 0; border: 0; font-size: 0; - transition: opacity .2s ease-in-out; + transition: opacity 0.2s ease-in-out; &.active { opacity: 1; @@ -372,7 +372,6 @@ .video-player__volume__handle { bottom: 23px; } - } .audio-player { @@ -506,10 +505,15 @@ left: 0; right: 0; box-sizing: border-box; - background: linear-gradient(0deg, rgba($base-shadow-color, 0.85) 0, rgba($base-shadow-color, 0.45) 60%, transparent); + background: linear-gradient( + 0deg, + rgba($base-shadow-color, 0.85) 0, + rgba($base-shadow-color, 0.45) 60%, + transparent + ); padding: 0 15px; opacity: 0; - transition: opacity .1s ease; + transition: opacity 0.1s ease; &.active { opacity: 1; @@ -655,7 +659,7 @@ } &::before { - content: ""; + content: ''; width: 50px; background: rgba($white, 0.35); border-radius: 4px; @@ -725,7 +729,7 @@ position: relative; &::before { - content: ""; + content: ''; width: 100%; background: rgba($white, 0.35); border-radius: 4px; @@ -762,7 +766,7 @@ box-shadow: 1px 2px 6px rgba($base-shadow-color, 0.2); .no-reduce-motion & { - transition: opacity .1s ease; + transition: opacity 0.1s ease; } &.active { diff --git a/app/javascript/flavours/glitch/styles/components/modal.scss b/app/javascript/flavours/glitch/styles/components/modal.scss index 69d237dec6..fc9ba3a189 100644 --- a/app/javascript/flavours/glitch/styles/components/modal.scss +++ b/app/javascript/flavours/glitch/styles/components/modal.scss @@ -269,7 +269,8 @@ } .onboarding-modal__page__wrapper-0 { - background: url('~images/elephant_ui_greeting.svg') no-repeat left bottom / auto 250px; + background: url('~images/elephant_ui_greeting.svg') no-repeat left bottom / + auto 250px; height: 100%; padding: 0; } @@ -989,7 +990,8 @@ font-size: 14px; - label, input { + label, + input { vertical-align: middle; } } @@ -1020,7 +1022,9 @@ width: auto; outline: 0; font-family: inherit; - background: $simple-background-color url("data:image/svg+xml;utf8,") no-repeat right 8px center / auto 16px; + background: $simple-background-color + url("data:image/svg+xml;utf8,") + no-repeat right 8px center / auto 16px; border: 1px solid darken($simple-background-color, 14%); border-radius: 4px; padding: 6px 10px; @@ -1280,7 +1284,7 @@ text-decoration: none; &:hover { - text-decoration: underline + text-decoration: underline; } } } diff --git a/app/javascript/flavours/glitch/styles/components/privacy_policy.scss b/app/javascript/flavours/glitch/styles/components/privacy_policy.scss index 96cf067422..c99e99131d 100644 --- a/app/javascript/flavours/glitch/styles/components/privacy_policy.scss +++ b/app/javascript/flavours/glitch/styles/components/privacy_policy.scss @@ -85,14 +85,14 @@ counter-increment: list-counter; &::before { - content: counter(list-counter) "."; + content: counter(list-counter) '.'; position: absolute; left: 0; } } ul > li::before { - content: ""; + content: ''; position: absolute; background-color: $darker-text-color; border-radius: 50%; diff --git a/app/javascript/flavours/glitch/styles/components/sensitive.scss b/app/javascript/flavours/glitch/styles/components/sensitive.scss index 67b01c886a..490951fb4c 100644 --- a/app/javascript/flavours/glitch/styles/components/sensitive.scss +++ b/app/javascript/flavours/glitch/styles/components/sensitive.scss @@ -17,8 +17,10 @@ font-size: 12px; line-height: 18px; text-transform: uppercase; - opacity: .9; - transition: opacity .1s ease; + opacity: 0.9; + transition: opacity 0.1s ease; - .media-gallery:hover & { opacity: 1 } + .media-gallery:hover & { + opacity: 1; + } } diff --git a/app/javascript/flavours/glitch/styles/components/single_column.scss b/app/javascript/flavours/glitch/styles/components/single_column.scss index 74e5d0884c..036b3f6ef1 100644 --- a/app/javascript/flavours/glitch/styles/components/single_column.scss +++ b/app/javascript/flavours/glitch/styles/components/single_column.scss @@ -140,7 +140,7 @@ .scrollable { overflow: visible; - @supports(display: grid) { + @supports (display: grid) { contain: content; } } diff --git a/app/javascript/flavours/glitch/styles/components/status.scss b/app/javascript/flavours/glitch/styles/components/status.scss index bb5bbc0ac6..9280ef8365 100644 --- a/app/javascript/flavours/glitch/styles/components/status.scss +++ b/app/javascript/flavours/glitch/styles/components/status.scss @@ -67,7 +67,9 @@ margin: -3px 0 0; } - p, pre, blockquote { + p, + pre, + blockquote { margin-bottom: 20px; white-space: pre-wrap; unicode-bidi: plaintext; @@ -86,12 +88,17 @@ margin-bottom: 20px; } - h1, h2, h3, h4, h5 { + h1, + h2, + h3, + h4, + h5 { margin-top: 20px; margin-bottom: 20px; } - h1, h2 { + h1, + h2 { font-weight: 700; font-size: 1.2em; } @@ -100,7 +107,9 @@ font-size: 1.1em; } - h3, h4, h5 { + h3, + h4, + h5 { font-weight: 500; } @@ -115,11 +124,13 @@ } } - b, strong { + b, + strong { font-weight: 700; } - em, i { + em, + i { font-style: italic; } @@ -133,7 +144,8 @@ vertical-align: super; } - ul, ol { + ul, + ol { margin-left: 2em; p { @@ -317,8 +329,12 @@ } @keyframes fade { - 0% { opacity: 0; } - 100% { opacity: 1; } + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } } opacity: 1; @@ -381,9 +397,14 @@ right: 0; top: 0; bottom: 0; - background-image: linear-gradient(to bottom, rgba($base-shadow-color, .75), rgba($base-shadow-color, .65) 24px, rgba($base-shadow-color, .8)); + background-image: linear-gradient( + to bottom, + rgba($base-shadow-color, 0.75), + rgba($base-shadow-color, 0.65) 24px, + rgba($base-shadow-color, 0.8) + ); pointer-events: none; - content: ""; + content: ''; } .display-name:hover .display-name__html { @@ -397,25 +418,34 @@ padding-top: 0; &:after { - content: ""; + content: ''; position: absolute; top: 0; bottom: 0; left: 0; right: 0; - background: linear-gradient(rgba($ui-base-color, 0), rgba($ui-base-color, 1)); + background: linear-gradient( + rgba($ui-base-color, 0), + rgba($ui-base-color, 1) + ); pointer-events: none; } - + a:hover { text-decoration: none; } } &:focus > .status__content:after { - background: linear-gradient(rgba(lighten($ui-base-color, 4%), 0), rgba(lighten($ui-base-color, 4%), 1)); + background: linear-gradient( + rgba(lighten($ui-base-color, 4%), 0), + rgba(lighten($ui-base-color, 4%), 1) + ); } &.status-direct > .status__content:after { - background: linear-gradient(rgba(lighten($ui-base-color, 8%), 0), rgba(lighten($ui-base-color, 8%), 1)); + background: linear-gradient( + rgba(lighten($ui-base-color, 8%), 0), + rgba(lighten($ui-base-color, 8%), 1) + ); } .notification__message { @@ -832,7 +862,8 @@ a.status__display-name, bottom: -1px; } - a .fa, a:hover .fa { + a .fa, + a:hover .fa { color: inherit; } } @@ -850,9 +881,9 @@ a.status-card { cursor: zoom-in; display: block; text-decoration: none; - width: 100%; - height: auto; - margin: 0; + width: 100%; + height: auto; + margin: 0; } .status-card-video { @@ -1063,7 +1094,7 @@ a.status-card.compact:hover { &.unread { &::before { - content: ""; + content: ''; position: absolute; top: 0; left: 0; diff --git a/app/javascript/flavours/glitch/styles/contrast/variables.scss b/app/javascript/flavours/glitch/styles/contrast/variables.scss index e272b6ca3f..e38d24b271 100644 --- a/app/javascript/flavours/glitch/styles/contrast/variables.scss +++ b/app/javascript/flavours/glitch/styles/contrast/variables.scss @@ -18,5 +18,5 @@ $highlight-text-color: lighten($ui-highlight-color, 10%) !default; $action-button-color: lighten($ui-base-color, 50%); $inverted-text-color: $black !default; -$lighter-text-color: darken($ui-base-color,6%) !default; +$lighter-text-color: darken($ui-base-color, 6%) !default; $light-text-color: darken($ui-primary-color, 40%) !default; diff --git a/app/javascript/flavours/glitch/styles/forms.scss b/app/javascript/flavours/glitch/styles/forms.scss index 6a73b3a2ce..602de9002e 100644 --- a/app/javascript/flavours/glitch/styles/forms.scss +++ b/app/javascript/flavours/glitch/styles/forms.scss @@ -300,7 +300,7 @@ code { max-width: 100%; height: auto; border-radius: 4px; - background: url("images/void.png"); + background: url('images/void.png'); &:last-child { margin-bottom: 0; @@ -385,7 +385,7 @@ code { flex: 1 1 auto; } - input[type=checkbox] { + input[type='checkbox'] { position: absolute; left: 0; top: 5px; @@ -401,12 +401,12 @@ code { border-radius: 4px; } - input[type=text], - input[type=number], - input[type=email], - input[type=password], - input[type=url], - input[type=datetime-local], + input[type='text'], + input[type='number'], + input[type='email'], + input[type='password'], + input[type='url'], + input[type='datetime-local'], textarea { box-sizing: border-box; font-size: 16px; @@ -444,11 +444,11 @@ code { } } - input[type=text], - input[type=number], - input[type=email], - input[type=password], - input[type=datetime-local] { + input[type='text'], + input[type='number'], + input[type='email'], + input[type='password'], + input[type='datetime-local'] { &:focus:invalid:not(:placeholder-shown), &:required:invalid:not(:placeholder-shown) { border-color: lighten($error-red, 12%); @@ -460,11 +460,11 @@ code { color: lighten($error-red, 12%); } - input[type=text], - input[type=number], - input[type=email], - input[type=password], - input[type=datetime-local], + input[type='text'], + input[type='number'], + input[type='email'], + input[type='password'], + input[type='datetime-local'], textarea, select { border-color: lighten($error-red, 12%); @@ -568,7 +568,9 @@ code { outline: 0; font-family: inherit; resize: vertical; - background: darken($ui-base-color, 10%) url("data:image/svg+xml;utf8,") no-repeat right 8px center / auto 16px; + background: darken($ui-base-color, 10%) + url("data:image/svg+xml;utf8,") + no-repeat right 8px center / auto 16px; border: 1px solid darken($ui-base-color, 14%); border-radius: 4px; padding-left: 10px; @@ -608,7 +610,11 @@ code { right: 0; bottom: 1px; width: 5px; - background-image: linear-gradient(to right, rgba(darken($ui-base-color, 10%), 0), darken($ui-base-color, 10%)); + background-image: linear-gradient( + to right, + rgba(darken($ui-base-color, 10%), 0), + darken($ui-base-color, 10%) + ); } } } @@ -996,7 +1002,7 @@ code { flex: 1 1 auto; } - input[type=text] { + input[type='text'] { background: transparent; border: 0; padding: 10px; diff --git a/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss b/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss index b97c6c5ad6..bb97ecb5f4 100644 --- a/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss +++ b/app/javascript/flavours/glitch/styles/mastodon-light/diff.scss @@ -152,7 +152,7 @@ html { } .compose-form__autosuggest-wrapper, -.poll__option input[type="text"], +.poll__option input[type='text'], .compose-form .spoiler-input__input, .compose-form__poll-wrapper select, .search__input, @@ -179,7 +179,9 @@ html { } .compose-form__poll-wrapper select { - background: $simple-background-color url("data:image/svg+xml;utf8,") no-repeat right 8px center / auto 16px; + background: $simple-background-color + url("data:image/svg+xml;utf8,") + no-repeat right 8px center / auto 16px; } .compose-form__poll-wrapper, @@ -205,7 +207,9 @@ html { } .drawer__inner__mastodon { - background: $white url('data:image/svg+xml;utf8,') no-repeat bottom / 100% auto; + background: $white + url('data:image/svg+xml;utf8,') + no-repeat bottom / 100% auto; } // Change the colors used in compose-form @@ -332,11 +336,13 @@ html { color: $white; } -.language-dropdown__dropdown__results__item .language-dropdown__dropdown__results__item__common-name { +.language-dropdown__dropdown__results__item + .language-dropdown__dropdown__results__item__common-name { color: lighten($ui-base-color, 8%); } -.language-dropdown__dropdown__results__item.active .language-dropdown__dropdown__results__item__common-name { +.language-dropdown__dropdown__results__item.active + .language-dropdown__dropdown__results__item__common-name { color: darken($ui-base-color, 12%); } @@ -490,7 +496,8 @@ html { background: darken($ui-secondary-color, 10%); } -.react-toggle.react-toggle--checked:hover:not(.react-toggle--disabled) .react-toggle-track { +.react-toggle.react-toggle--checked:hover:not(.react-toggle--disabled) + .react-toggle-track { background: lighten($ui-highlight-color, 10%); } @@ -522,10 +529,10 @@ html { } .simple_form { - input[type="text"], - input[type="number"], - input[type="email"], - input[type="password"], + input[type='text'], + input[type='number'], + input[type='email'], + input[type='password'], textarea { &:hover { border-color: lighten($ui-base-color, 12%); @@ -682,7 +689,9 @@ html { .mute-modal select { border: 1px solid lighten($ui-base-color, 8%); - background: $simple-background-color url("data:image/svg+xml;utf8,") no-repeat right 8px center / auto 16px; + background: $simple-background-color + url("data:image/svg+xml;utf8,") + no-repeat right 8px center / auto 16px; } // Glitch-soc-specific changes @@ -729,7 +738,8 @@ html { color: $white; } - &.close, &.close:hover { + &.close, + &.close:hover { background: $error-value-color; color: $primary-text-color; } @@ -746,11 +756,16 @@ html { } .status.collapsed .status__content:after { - background: linear-gradient(rgba(darken($ui-base-color, 13%), 0), rgba(darken($ui-base-color, 13%), 1)); + background: linear-gradient( + rgba(darken($ui-base-color, 13%), 0), + rgba(darken($ui-base-color, 13%), 1) + ); } .drawer__inner__mastodon { - background: $white url('data:image/svg+xml;utf8,') no-repeat bottom / 100% auto !important; + background: $white + url('data:image/svg+xml;utf8,') + no-repeat bottom / 100% auto !important; .mastodon { filter: contrast(75%) brightness(75%) !important; diff --git a/app/javascript/flavours/glitch/styles/modal.scss b/app/javascript/flavours/glitch/styles/modal.scss index a333926dd1..6170877b22 100644 --- a/app/javascript/flavours/glitch/styles/modal.scss +++ b/app/javascript/flavours/glitch/styles/modal.scss @@ -1,5 +1,7 @@ .modal-layout { - background: $ui-base-color url('data:image/svg+xml;utf8,') repeat-x bottom fixed; + background: $ui-base-color + url('data:image/svg+xml;utf8,') + repeat-x bottom fixed; display: flex; flex-direction: column; height: 100vh; diff --git a/app/javascript/flavours/glitch/styles/polls.scss b/app/javascript/flavours/glitch/styles/polls.scss index 407d718880..5b40aaebee 100644 --- a/app/javascript/flavours/glitch/styles/polls.scss +++ b/app/javascript/flavours/glitch/styles/polls.scss @@ -70,8 +70,8 @@ max-width: calc(100% - 45px - 25px); } - input[type=radio], - input[type=checkbox] { + input[type='radio'], + input[type='checkbox'] { display: none; } @@ -79,7 +79,7 @@ flex: 1 1 auto; } - input[type=text] { + input[type='text'] { display: block; box-sizing: border-box; width: 100%; @@ -205,7 +205,7 @@ &:active, &:focus { - background-color: rgba($dark-text-color, .1); + background-color: rgba($dark-text-color, 0.1); } } @@ -273,7 +273,9 @@ width: auto; outline: 0; font-family: inherit; - background: $simple-background-color url("data:image/svg+xml;utf8,") no-repeat right 8px center / auto 16px; + background: $simple-background-color + url("data:image/svg+xml;utf8,") + no-repeat right 8px center / auto 16px; border: 1px solid darken($simple-background-color, 14%); border-radius: 4px; padding: 6px 10px; diff --git a/app/javascript/flavours/glitch/styles/rtl.scss b/app/javascript/flavours/glitch/styles/rtl.scss index c14c07cb90..64a5c2c03d 100644 --- a/app/javascript/flavours/glitch/styles/rtl.scss +++ b/app/javascript/flavours/glitch/styles/rtl.scss @@ -255,8 +255,8 @@ body.rtl { padding-right: 0; } - .simple_form .check_boxes .checkbox input[type="checkbox"], - .simple_form .input.boolean input[type="checkbox"] { + .simple_form .check_boxes .checkbox input[type='checkbox'], + .simple_form .input.boolean input[type='checkbox'] { left: auto; right: 0; } @@ -294,12 +294,18 @@ body.rtl { &::after { right: auto; left: 0; - background-image: linear-gradient(to left, rgba(darken($ui-base-color, 10%), 0), darken($ui-base-color, 10%)); + background-image: linear-gradient( + to left, + rgba(darken($ui-base-color, 10%), 0), + darken($ui-base-color, 10%) + ); } } .simple_form select { - background: darken($ui-base-color, 10%) url("data:image/svg+xml;utf8,") no-repeat left 8px center / auto 16px; + background: darken($ui-base-color, 10%) + url("data:image/svg+xml;utf8,") + no-repeat left 8px center / auto 16px; } .table th, @@ -346,11 +352,11 @@ body.rtl { } .fa-chevron-left::before { - content: "\F054"; + content: '\F054'; } .fa-chevron-right::before { - content: "\F053"; + content: '\F053'; } .column-back-button__icon { diff --git a/app/javascript/flavours/glitch/styles/statuses.scss b/app/javascript/flavours/glitch/styles/statuses.scss index 88fa3ffa07..f7037d9dc5 100644 --- a/app/javascript/flavours/glitch/styles/statuses.scss +++ b/app/javascript/flavours/glitch/styles/statuses.scss @@ -134,7 +134,7 @@ a.button.logo-button { } .embed { - .status__content[data-spoiler=folded] { + .status__content[data-spoiler='folded'] { .e-content { display: none; } diff --git a/app/javascript/flavours/glitch/styles/variables.scss b/app/javascript/flavours/glitch/styles/variables.scss index b865b5a2d1..25658bb0c8 100644 --- a/app/javascript/flavours/glitch/styles/variables.scss +++ b/app/javascript/flavours/glitch/styles/variables.scss @@ -1,18 +1,18 @@ // Commonly used web colors -$black: #000000; // Black -$white: #ffffff; // White -$success-green: #79bd9a; // Padua -$error-red: #df405a; // Cerise -$warning-red: #ff5050; // Sunset Orange -$gold-star: #ca8f04; // Dark Goldenrod +$black: #000000; // Black +$white: #ffffff; // White +$success-green: #79bd9a; // Padua +$error-red: #df405a; // Cerise +$warning-red: #ff5050; // Sunset Orange +$gold-star: #ca8f04; // Dark Goldenrod $red-bookmark: $warning-red; // Values from the classic Mastodon UI -$classic-base-color: #282c37; // Midnight Express -$classic-primary-color: #9baec8; // Echo Blue -$classic-secondary-color: #d9e1e8; // Pattens Blue -$classic-highlight-color: #6364ff; // Brand purple +$classic-base-color: #282c37; // Midnight Express +$classic-primary-color: #9baec8; // Echo Blue +$classic-secondary-color: #d9e1e8; // Pattens Blue +$classic-highlight-color: #6364ff; // Brand purple // Variables for defaults in UI $base-shadow-color: $black !default; @@ -23,10 +23,13 @@ $valid-value-color: $success-green !default; $error-value-color: $error-red !default; // Tell UI to use selected colors -$ui-base-color: $classic-base-color !default; // Darkest -$ui-base-lighter-color: lighten($ui-base-color, 26%) !default; // Lighter darkest -$ui-primary-color: $classic-primary-color !default; // Lighter -$ui-secondary-color: $classic-secondary-color !default; // Lightest +$ui-base-color: $classic-base-color !default; // Darkest +$ui-base-lighter-color: lighten( + $ui-base-color, + 26% +) !default; // Lighter darkest +$ui-primary-color: $classic-primary-color !default; // Lighter +$ui-secondary-color: $classic-secondary-color !default; // Lightest $ui-highlight-color: $classic-highlight-color !default; // Variables for texts diff --git a/app/javascript/flavours/glitch/styles/widgets.scss b/app/javascript/flavours/glitch/styles/widgets.scss index fd091ee894..0f2b7ac5b3 100644 --- a/app/javascript/flavours/glitch/styles/widgets.scss +++ b/app/javascript/flavours/glitch/styles/widgets.scss @@ -1,4 +1,4 @@ -@use "sass:math"; +@use 'sass:math'; .hero-widget { margin-bottom: 10px;