From 8f3402b1f08963cc1514d496aa5ee0ba1589a75d Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Mon, 7 May 2018 15:09:49 +0200 Subject: Port Sylvhem's mastodon-light to glitch flavour --- .../flavours/glitch/styles/mastodon-light.scss | 216 +++++++++++++++++++++ 1 file changed, 216 insertions(+) create mode 100644 app/javascript/flavours/glitch/styles/mastodon-light.scss (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/mastodon-light.scss b/app/javascript/flavours/glitch/styles/mastodon-light.scss new file mode 100644 index 000000000..46f88c994 --- /dev/null +++ b/app/javascript/flavours/glitch/styles/mastodon-light.scss @@ -0,0 +1,216 @@ +// Set variables +$ui-base-color: #d9e1e8; +$ui-base-lighter-color: darken($ui-base-color, 57%); +$ui-highlight-color: #2b90d9; +$ui-primary-color: darken($ui-highlight-color, 28%); +$ui-secondary-color: #282c37; + +$primary-text-color: black; +$base-overlay-background: $ui-base-color; + +$login-button-color: white; +$account-background-color: white; + +// Import defaults +@import 'index'; + +// Change the color of the log in button +.button { + &.button-alternative-2 { + color: $login-button-color; + } +} + +// Change columns' default background colors +.column { + > .scrollable { + background: lighten($ui-base-color, 13%); + } +} + +.status.collapsed .status__content:after { + background: linear-gradient(rgba(lighten($ui-base-color, 13%), 0), rgba(lighten($ui-base-color, 13%), 1)); +} + +.drawer__inner { + background: $ui-base-color; +} + +.drawer > .contents { + background: $ui-base-color url('data:image/svg+xml;utf8,') no-repeat bottom / 100% auto !important; + + .mastodon { + filter: contrast(75%) brightness(75%) !important; + } +} + +// Change the default appearance of the content warning button +.status__content { + + .status__content__spoiler-link { + + background: darken($ui-base-color, 30%); + + &:hover { + background: darken($ui-base-color, 35%); + text-decoration: none; + } + + } + +} + +// Change the default appearance of the action buttons +.icon-button { + + &:hover, + &:active, + &:focus { + color: darken($ui-base-color, 40%); + transition: color 200ms ease-out; + } + + &.disabled { + color: darken($ui-base-color, 30%); + } + +} + +.status { + &.status-direct { + .icon-button.disabled { + color: darken($ui-base-color, 30%); + } + } +} + +// Change the colors used in the dropdown menu +.dropdown-menu { + background: $ui-base-color; +} + +.dropdown-menu__arrow { + + &.left { + border-left-color: $ui-base-color; + } + + &.top { + border-top-color: $ui-base-color; + } + + &.bottom { + border-bottom-color: $ui-base-color; + } + + &.right { + border-right-color: $ui-base-color; + } + +} + +.dropdown-menu__item { + a { + background: $ui-base-color; + color: $ui-secondary-color; + } +} + +// Change the default color of several parts of the compose form +.composer { + + .composer--spoiler input, .composer--textarea textarea { + color: darken($ui-base-color, 80%); + + &::placeholder { + color: darken($ui-base-color, 70%); + } + } + + strong { + color: lighten($ui-secondary-color, 65%); + } + + .composer--options { + background: darken($ui-base-color, 10%); + box-shadow: unset; + } + + .composer--options--dropdown--content--item { + color: $ui-primary-color; + + strong { + color: $ui-primary-color; + } + + } + +} + +// Change the default color used for the text in an empty column or on the error column +.empty-column-indicator, +.error-column { + color: darken($ui-base-color, 60%); +} + +// Change the default colors used on some parts of the profile pages +.activity-stream-tabs { + + background: $account-background-color; + + a { + &.active { + color: $ui-primary-color; + } + } + +} + +.activity-stream { + + .entry { + background: $account-background-color; + } + + .status.light { + + .status__content { + color: $primary-text-color; + } + + .display-name { + strong { + color: $primary-text-color; + } + } + + } + +} + +.accounts-grid { + .account-grid-card { + + .controls { + .icon-button { + color: $ui-secondary-color; + } + } + + .name { + a { + color: $primary-text-color; + } + } + + .username { + color: $ui-secondary-color; + } + + .account__header__content { + color: $primary-text-color; + } + + } +} + -- cgit From 30bb530c7062f001e8198d0eaca6b7f78acbadad Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 9 May 2018 22:11:59 +0200 Subject: Update glitch-soc style to match new bio fields markup --- .../glitch/styles/components/metadata.scss | 32 ++++++------- .../flavours/glitch/styles/metadata.scss | 55 +++++++++++++--------- 2 files changed, 50 insertions(+), 37 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/components/metadata.scss b/app/javascript/flavours/glitch/styles/components/metadata.scss index fa1a4bc34..29a6330e9 100644 --- a/app/javascript/flavours/glitch/styles/components/metadata.scss +++ b/app/javascript/flavours/glitch/styles/components/metadata.scss @@ -2,7 +2,6 @@ font-size: 15px; line-height: 20px; overflow: hidden; - border-collapse: collapse; margin: 20px -10px -20px; border-bottom: 0; @@ -14,35 +13,36 @@ } } - tr { + dl { border-top: 1px solid lighten($ui-base-color, 8%); - text-align: center; + display: flex; } - th, td { + dt, + dd { + box-sizing: border-box; padding: 14px 20px; - vertical-align: middle; - - & > div { - max-height: 40px; - overflow-y: auto; - white-space: pre-wrap; - text-overflow: ellipsis; - } + text-align: center; + max-height: 48px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } - th { + dt { color: $darker-text-color; background: lighten($ui-base-color, 13%); - max-width: 120px; + width: 120px; + flex: 0 0 auto; + font-weight: 500; a { color: $primary-text-color; } } - td { - flex: auto; + dd { + flex: 1 1 auto; color: $primary-text-color; background: $ui-base-color; diff --git a/app/javascript/flavours/glitch/styles/metadata.scss b/app/javascript/flavours/glitch/styles/metadata.scss index b66cce3c1..280848959 100644 --- a/app/javascript/flavours/glitch/styles/metadata.scss +++ b/app/javascript/flavours/glitch/styles/metadata.scss @@ -1,43 +1,56 @@ .account__header__fields { $meta-table-border: lighten($ui-base-color, 8%); - - border-collapse: collapse; padding: 0; margin: 15px -15px -15px -15px; border: 0 none; border-top: 1px solid $meta-table-border; border-bottom: 1px solid $meta-table-border; + font-size: 14px; + line-height: 20px; - td, th { - padding: 15px; - border: 0 none; + dl { + display: flex; border-bottom: 1px solid $meta-table-border; - vertical-align: middle; } - tr:last-child { - td, th { - border-bottom: 0 none; - } - } - - td { - color: $ui-primary-color; + dt, + dd { + box-sizing: border-box; + padding: 14px; text-align: center; - width:100%; - padding-left: 0; + max-height: 48px; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; } - th { + dt { padding-left: 15px; - font-weight: bold; + font-weight: 500; text-align: center; - width: 94px; - color: $ui-secondary-color; + width: 120px; + flex: 0 0 auto; + color: $secondary-text-color; background: darken($ui-base-color, 8%); } + dd { + flex: 1 1 auto; + color: $darker-text-color; + } + a { - color: $classic-highlight-color; + color: $highlight-text-color; + text-decoration: none; + + &:hover, + &:focus, + &:active { + text-decoration: underline; + } + } + + dl:last-child { + border-bottom: 0; } } -- cgit From 2f01935cba8b1ac624e4c1f39b6db1b0b96e9323 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 9 May 2018 23:29:14 +0200 Subject: Adapt account fields rendering code in the WebUI to match upstream --- .../glitch/features/account/components/header.js | 42 +++++++++------------- 1 file changed, 16 insertions(+), 26 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 7a0a2dfa9..044155cd8 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -102,35 +102,25 @@ export default class Header extends ImmutablePureComponent {
{fields.size > 0 && ( - - - {fields.map((pair, i) => ( - - - ))} - -
- -
+
+ {fields.map((pair, i) => ( +
+
+
+
+ ))} +
)} {fields.size == 0 && metadata.length && ( - - - {(() => { - let data = []; - for (let i = 0; i < metadata.length; i++) { - data.push( - - - - - ); - } - return data; - })()} - -
+
+ {metadata.map((pair, i) => ( +
+
+
+
+ ))} +
) || null} {info} -- cgit From 5d8052e7156c913a551b923c51d508b1ea8837b3 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 9 May 2018 22:19:10 +0200 Subject: Add bot badge to account headers in the WebUI --- .../flavours/glitch/features/account/components/header.js | 5 +++++ app/javascript/flavours/glitch/styles/components/accounts.scss | 6 ++++++ 2 files changed, 11 insertions(+) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 044155cd8..15bd6b365 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -38,6 +38,8 @@ export default class Header extends ImmutablePureComponent { let displayName = account.get('display_name_html'); let fields = account.get('fields'); + let badge = account.get('bot') ? (
) : null; + let info = ''; let mutingInfo = ''; let actionBtn = ''; @@ -99,6 +101,9 @@ export default class Header extends ImmutablePureComponent { @{account.get('acct')} {account.get('locked') ? : null} + + {badge} +
{fields.size > 0 && ( diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss index 84d3f6ade..5167a507e 100644 --- a/app/javascript/flavours/glitch/styles/components/accounts.scss +++ b/app/javascript/flavours/glitch/styles/components/accounts.scss @@ -509,3 +509,9 @@ margin-bottom: 0; } } + +.account__header .roles { + margin-top: 20px; + margin-bottom: 20px; + padding: 0 15px; +} -- cgit From f6ec8c48210f6bce421d0d7248737d028ae88ee3 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Thu, 10 May 2018 13:04:55 +0200 Subject: [Glitch] Use plaintext value for field value tooltips in web UI Port d185f3ddafc941e280de7efc6d448449ab5ce2c9 to glitch-soc This doesn't change anything for glitch-style fields, but those will go away eventually --- app/javascript/flavours/glitch/actions/notifications.js | 8 +------- .../flavours/glitch/features/account/components/header.js | 2 +- app/javascript/flavours/glitch/reducers/accounts.js | 2 ++ app/javascript/flavours/glitch/util/html.js | 6 ++++++ 4 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 app/javascript/flavours/glitch/util/html.js (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/actions/notifications.js b/app/javascript/flavours/glitch/actions/notifications.js index cf27eff90..0d52100b9 100644 --- a/app/javascript/flavours/glitch/actions/notifications.js +++ b/app/javascript/flavours/glitch/actions/notifications.js @@ -3,6 +3,7 @@ import { List as ImmutableList } from 'immutable'; import IntlMessageFormat from 'intl-messageformat'; import { fetchRelationships } from './accounts'; import { defineMessages } from 'react-intl'; +import { unescapeHTML } from 'flavours/glitch/util/html'; export const NOTIFICATIONS_UPDATE = 'NOTIFICATIONS_UPDATE'; @@ -40,13 +41,6 @@ const fetchRelatedRelationships = (dispatch, notifications) => { } }; -const unescapeHTML = (html) => { - const wrapper = document.createElement('div'); - html = html.replace(/
|
|\n/g, ' '); - wrapper.innerHTML = html; - return wrapper.textContent; -}; - export function updateNotifications(notification, intlMessages, intlLocale) { return (dispatch, getState) => { const showAlert = getState().getIn(['settings', 'notifications', 'alerts', notification.type], true); diff --git a/app/javascript/flavours/glitch/features/account/components/header.js b/app/javascript/flavours/glitch/features/account/components/header.js index 15bd6b365..464c73c9a 100644 --- a/app/javascript/flavours/glitch/features/account/components/header.js +++ b/app/javascript/flavours/glitch/features/account/components/header.js @@ -111,7 +111,7 @@ export default class Header extends ImmutablePureComponent { {fields.map((pair, i) => (
-
+
))}
diff --git a/app/javascript/flavours/glitch/reducers/accounts.js b/app/javascript/flavours/glitch/reducers/accounts.js index 23fbd999c..e8127a871 100644 --- a/app/javascript/flavours/glitch/reducers/accounts.js +++ b/app/javascript/flavours/glitch/reducers/accounts.js @@ -57,6 +57,7 @@ import { STORE_HYDRATE } from 'flavours/glitch/actions/store'; import emojify from 'flavours/glitch/util/emoji'; import { Map as ImmutableMap, fromJS } from 'immutable'; import escapeTextContentForBrowser from 'escape-html'; +import { unescapeHTML } from 'flavours/glitch/util/html'; const normalizeAccount = (state, account) => { account = { ...account }; @@ -74,6 +75,7 @@ const normalizeAccount = (state, account) => { ...pair, name_emojified: emojify(escapeTextContentForBrowser(pair.name)), value_emojified: emojify(pair.value), + value_plain: unescapeHTML(pair.value), })); } diff --git a/app/javascript/flavours/glitch/util/html.js b/app/javascript/flavours/glitch/util/html.js new file mode 100644 index 000000000..0b646ce58 --- /dev/null +++ b/app/javascript/flavours/glitch/util/html.js @@ -0,0 +1,6 @@ +export const unescapeHTML = (html) => { + const wrapper = document.createElement('div'); + html = html.replace(/
|
|\n/g, ' '); + wrapper.innerHTML = html; + return wrapper.textContent; +}; -- cgit From db73c0bc5df552494849446e4bac197cd41b6dcb Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:13:59 +0200 Subject: Update admin page SCSS from upstream --- app/javascript/flavours/glitch/styles/admin.scss | 120 ++++++++++++----------- 1 file changed, 62 insertions(+), 58 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/admin.scss b/app/javascript/flavours/glitch/styles/admin.scss index b077df145..1948a2a23 100644 --- a/app/javascript/flavours/glitch/styles/admin.scss +++ b/app/javascript/flavours/glitch/styles/admin.scss @@ -141,14 +141,15 @@ } hr { - margin: 20px 0; + width: 100%; + height: 0; border: 0; - background: transparent; - border-bottom: 1px solid $ui-base-color; + border-bottom: 1px solid rgba($ui-base-lighter-color, .6); + margin: 20px 0; - &.section-break { - margin: 30px 0; - border-bottom: 2px solid $ui-base-lighter-color; + &.spacer { + height: 1px; + border: 0; } } @@ -273,22 +274,6 @@ } } -.flavour-screen { - display: block; - margin: 10px auto; - max-width: 100%; -} - -.flavour-description { - display: block; - font-size: 16px; - margin: 10px 0; - - & > p { - margin: 10px 0; - } -} - .report-accounts { display: flex; flex-wrap: wrap; @@ -351,34 +336,9 @@ } } -.report-note__comment { - margin-bottom: 20px; -} - -.report-note__form { - margin-bottom: 20px; - - .report-note__textarea { - box-sizing: border-box; - border: 0; - padding: 7px 4px; - margin-bottom: 10px; - font-size: 16px; - color: $inverted-text-color; - display: block; - width: 100%; - outline: 0; - font-family: inherit; - resize: vertical; - } - - .report-note__buttons { - text-align: right; - } - - .report-note__button { - margin: 0 0 5px 5px; - } +.simple_form.new_report_note, +.simple_form.new_account_moderation_note { + max-width: 100%; } .batch-form-box { @@ -406,13 +366,6 @@ } } -.batch-checkbox, -.batch-checkbox-all { - display: flex; - align-items: center; - margin-right: 5px; -} - .back-link { margin-bottom: 10px; font-size: 14px; @@ -432,7 +385,7 @@ } .log-entry { - margin-bottom: 8px; + margin-bottom: 20px; line-height: 20px; &__header { @@ -530,9 +483,12 @@ } } +a.name-tag, .name-tag { display: flex; align-items: center; + text-decoration: none; + color: $secondary-text-color; .avatar { display: block; @@ -544,4 +500,52 @@ .username { font-weight: 500; } + + &.suspended { + .username { + text-decoration: line-through; + color: lighten($error-red, 12%); + } + + .avatar { + filter: grayscale(100%); + opacity: 0.8; + } + } +} + +.speech-bubble { + margin-bottom: 20px; + border-left: 4px solid $ui-highlight-color; + + &.positive { + border-left-color: $success-green; + } + + &.negative { + border-left-color: lighten($error-red, 12%); + } + + &__bubble { + padding: 16px; + padding-left: 14px; + font-size: 15px; + line-height: 20px; + border-radius: 4px 4px 4px 0; + position: relative; + font-weight: 500; + + a { + color: $darker-text-color; + } + } + + &__owner { + padding: 8px; + padding-left: 12px; + } + + time { + color: $dark-text-color; + } } -- cgit From 1a4d735b1dd299daa50db1dfa373ef1ee0e647b3 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:18:52 +0200 Subject: Update SCSS for about/landing page --- app/javascript/flavours/glitch/styles/about.scss | 76 +++++++++++++++++++++--- 1 file changed, 69 insertions(+), 7 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/about.scss b/app/javascript/flavours/glitch/styles/about.scss index 55f31266f..c9c0e3081 100644 --- a/app/javascript/flavours/glitch/styles/about.scss +++ b/app/javascript/flavours/glitch/styles/about.scss @@ -322,6 +322,11 @@ $small-breakpoint: 960px; border: 0; border-bottom: 1px solid rgba($ui-base-lighter-color, .6); margin: 20px 0; + + &.spacer { + height: 1px; + border: 0; + } } .container-alt { @@ -681,6 +686,54 @@ $small-breakpoint: 960px; margin-bottom: 0; } + .account { + border-bottom: 0; + padding: 0; + + &__display-name { + align-items: center; + display: flex; + margin-right: 5px; + } + + div.account__display-name { + &:hover { + .display-name strong { + text-decoration: none; + } + } + + .account__avatar { + cursor: default; + } + } + + &__avatar-wrapper { + margin-left: 0; + flex: 0 0 auto; + } + + &__avatar { + width: 44px; + height: 44px; + background-size: 44px 44px; + } + + .display-name { + font-size: 15px; + + &__account { + font-size: 14px; + } + } + } + + @media screen and (max-width: $small-breakpoint) { + .contact { + margin-top: 30px; + } + } + @media screen and (max-width: $column-breakpoint) { padding: 25px 20px; } @@ -816,6 +869,8 @@ $small-breakpoint: 960px; font-size: 16px; line-height: inherit; font-weight: inherit; + margin: 0; + padding: 0; } .column { @@ -852,8 +907,13 @@ $small-breakpoint: 960px; } &__features { + & > p { + padding-right: 60px; + } + .features-list { - margin: 40px 0 !important; + margin: 40px 0; + margin-top: 30px; } &__action { @@ -862,17 +922,11 @@ $small-breakpoint: 960px; } .features-list { - margin-top: 20px; - .features-list__row { display: flex; padding: 10px 0; justify-content: space-between; - &:first-child { - padding-top: 0; - } - .visual { flex: 0 0 auto; display: flex; @@ -898,6 +952,14 @@ $small-breakpoint: 960px; } } } + + @media screen and (min-width: $small-breakpoint) { + display: grid; + grid-gap: 30px; + grid-template-columns: 1fr 1fr; + grid-auto-columns: 50%; + grid-auto-rows: max-content; + } } .extended-description { -- cgit From 4cd65fe0742457b55e2b1ba793bb7184a9efc9e3 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:20:46 +0200 Subject: Update SCSS to match “Show card modal on public pages” MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/javascript/flavours/glitch/styles/containers.scss | 1 + 1 file changed, 1 insertion(+) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/containers.scss b/app/javascript/flavours/glitch/styles/containers.scss index 9d5ab66a4..c40b38a5a 100644 --- a/app/javascript/flavours/glitch/styles/containers.scss +++ b/app/javascript/flavours/glitch/styles/containers.scss @@ -60,6 +60,7 @@ } } +.card-standalone__body, .media-gallery-standalone__body { overflow: hidden; } -- cgit From e8644f3a4bf7a656d5cf5e43f24b8f0ef15d6b0c Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:31:18 +0200 Subject: Update forms SCSS from upstream --- app/javascript/flavours/glitch/styles/forms.scss | 25 +++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/forms.scss b/app/javascript/flavours/glitch/styles/forms.scss index 0b12742a9..f97890187 100644 --- a/app/javascript/flavours/glitch/styles/forms.scss +++ b/app/javascript/flavours/glitch/styles/forms.scss @@ -280,6 +280,11 @@ code { .actions { margin-top: 30px; display: flex; + + &.actions--top { + margin-top: 0; + margin-bottom: 30px; + } } button, @@ -563,9 +568,27 @@ code { .post-follow-actions { text-align: center; - color: $ui-primary-color; + color: $darker-text-color; div { margin-bottom: 4px; } } + +.alternative-login { + margin-top: 20px; + margin-bottom: 20px; + + h4 { + font-size: 16px; + color: $primary-text-color; + text-align: center; + margin-bottom: 20px; + border: 0; + padding: 0; + } + + .button { + display: block; + } +} -- cgit From 4a1040c4cb32873e461cb3c4f1a15f4df6c9ee68 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:34:23 +0200 Subject: [Glitch] Adjust RTL styles for landing page Port 8bf3e750ab1d4f4ffa7063b088870d7a82ad548c to glitch-soc --- app/javascript/flavours/glitch/styles/rtl.scss | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/rtl.scss b/app/javascript/flavours/glitch/styles/rtl.scss index 77420c84b..e9099a9e9 100644 --- a/app/javascript/flavours/glitch/styles/rtl.scss +++ b/app/javascript/flavours/glitch/styles/rtl.scss @@ -1,6 +1,22 @@ body.rtl { direction: rtl; + .column-header > button { + text-align: right; + padding-left: 0; + padding-right: 15px; + } + + .landing-page__logo { + margin-right: 0; + margin-left: 20px; + } + + .landing-page .features-list .features-list__row .visual { + margin-left: 0; + margin-right: 15px; + } + .column-link__icon, .column-header__icon { margin-right: 0; -- cgit From 8860f14ef06fcd1ce818da9f0a47e669f0c83249 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:43:26 +0200 Subject: Update SCSS for statuses public view --- .../flavours/glitch/styles/stream_entries.scss | 38 +++++++++++++--------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/stream_entries.scss b/app/javascript/flavours/glitch/styles/stream_entries.scss index b505c1580..40963ae84 100644 --- a/app/javascript/flavours/glitch/styles/stream_entries.scss +++ b/app/javascript/flavours/glitch/styles/stream_entries.scss @@ -6,7 +6,8 @@ background: $simple-background-color; .detailed-status.light, - .status.light { + .status.light, + .more.light { border-bottom: 1px solid $ui-secondary-color; animation: none; } @@ -65,6 +66,10 @@ } } + .media-gallery__gifv__label { + bottom: 9px; + } + .status.light { padding: 14px 14px 14px (48px + 14px * 2); position: relative; @@ -145,10 +150,10 @@ a.status__content__spoiler-link { color: $primary-text-color; - background: $ui-primary-color; + background: $ui-base-color; &:hover { - background: lighten($ui-primary-color, 8%); + background: lighten($ui-base-color, 8%); } } } @@ -215,10 +220,10 @@ a.status__content__spoiler-link { color: $primary-text-color; - background: $ui-primary-color; + background: $ui-base-color; &:hover { - background: lighten($ui-primary-color, 8%); + background: lighten($ui-base-color, 8%); } } } @@ -261,16 +266,8 @@ } .media-spoiler { - background: $ui-primary-color; - color: $inverted-text-color; - transition: all 100ms linear; - - &:hover, - &:active, - &:focus { - background: darken($ui-primary-color, 5%); - color: unset; - } + background: $ui-base-color; + color: $darker-text-color; } .pre-header { @@ -299,6 +296,17 @@ text-decoration: underline; } } + + .more { + color: $darker-text-color; + display: block; + padding: 14px; + text-align: center; + + &:not(:hover) { + text-decoration: none; + } + } } .embed { -- cgit From f2e5ed6841bb30581d40bcd6cb954cc8f2e98d71 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 14:48:19 +0200 Subject: Update SCSS for tables --- app/javascript/flavours/glitch/styles/tables.scss | 116 +++++++++++++++++++++- 1 file changed, 113 insertions(+), 3 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/tables.scss b/app/javascript/flavours/glitch/styles/tables.scss index c12d84f1c..fa876e603 100644 --- a/app/javascript/flavours/glitch/styles/tables.scss +++ b/app/javascript/flavours/glitch/styles/tables.scss @@ -11,6 +11,7 @@ vertical-align: top; border-top: 1px solid $ui-base-color; text-align: left; + background: darken($ui-base-color, 4%); } & > thead > tr > th { @@ -48,9 +49,38 @@ } } - &.inline-table > tbody > tr:nth-child(odd) > td, - &.inline-table > tbody > tr:nth-child(odd) > th { - background: transparent; + &.inline-table { + & > tbody > tr:nth-child(odd) { + & > td, + & > th { + background: transparent; + } + } + + & > tbody > tr:first-child { + & > td, + & > th { + border-top: 0; + } + } + } + + &.batch-table { + & > thead > tr > th { + background: $ui-base-color; + border-top: 1px solid darken($ui-base-color, 8%); + border-bottom: 1px solid darken($ui-base-color, 8%); + + &:first-child { + border-radius: 4px 0 0; + border-left: 1px solid darken($ui-base-color, 8%); + } + + &:last-child { + border-radius: 0 4px 0 0; + border-right: 1px solid darken($ui-base-color, 8%); + } + } } } @@ -63,6 +93,13 @@ samp { font-family: 'mastodon-font-monospace', monospace; } +button.table-action-link { + background: transparent; + border: 0; + font: inherit; +} + +button.table-action-link, a.table-action-link { text-decoration: none; display: inline-block; @@ -79,4 +116,77 @@ a.table-action-link { font-weight: 400; margin-right: 5px; } + + &:first-child { + padding-left: 0; + } +} + +.batch-table { + &__toolbar, + &__row { + display: flex; + + &__select { + box-sizing: border-box; + padding: 8px 16px; + cursor: pointer; + min-height: 100%; + + input { + margin-top: 8px; + } + } + + &__actions, + &__content { + padding: 8px 0; + padding-right: 16px; + flex: 1 1 auto; + } + } + + &__toolbar { + border: 1px solid darken($ui-base-color, 8%); + background: $ui-base-color; + border-radius: 4px 0 0; + height: 47px; + align-items: center; + + &__actions { + text-align: right; + padding-right: 16px - 5px; + } + } + + &__row { + border: 1px solid darken($ui-base-color, 8%); + border-top: 0; + background: darken($ui-base-color, 4%); + + &:hover { + background: darken($ui-base-color, 2%); + } + + &:nth-child(even) { + background: $ui-base-color; + + &:hover { + background: lighten($ui-base-color, 2%); + } + } + + &__content { + padding-top: 12px; + padding-bottom: 16px; + } + } + + .status__content { + padding-top: 0; + + strong { + font-weight: 700; + } + } } -- cgit From 62840398327790b868139328324668682cc5b306 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 16:05:47 +0200 Subject: [Glitch] Fix contact info styling on landing page --- app/javascript/flavours/glitch/styles/components/accounts.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/components/accounts.scss b/app/javascript/flavours/glitch/styles/components/accounts.scss index 5167a507e..dadfa6d57 100644 --- a/app/javascript/flavours/glitch/styles/components/accounts.scss +++ b/app/javascript/flavours/glitch/styles/components/accounts.scss @@ -32,7 +32,8 @@ .account__avatar-wrapper { float: left; - margin: 6px 16px 6px 6px; + margin-left: 12px; + margin-right: 12px; } .account__avatar { -- cgit From 769a48495c8eac64a80f10134be5362ddf8ca107 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 22:42:32 +0200 Subject: Fix root modal's keyup handling (Fixes #478) --- app/javascript/flavours/glitch/components/modal_root.js | 3 ++- app/javascript/flavours/glitch/features/ui/components/modal_root.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/components/modal_root.js b/app/javascript/flavours/glitch/components/modal_root.js index 789e117c7..89f81f58e 100644 --- a/app/javascript/flavours/glitch/components/modal_root.js +++ b/app/javascript/flavours/glitch/components/modal_root.js @@ -6,6 +6,7 @@ export default class ModalRoot extends React.PureComponent { static propTypes = { children: PropTypes.node, onClose: PropTypes.func.isRequired, + noEsc: PropTypes.bool, }; state = { @@ -16,7 +17,7 @@ export default class ModalRoot extends React.PureComponent { handleKeyUp = (e) => { if ((e.key === 'Escape' || e.key === 'Esc' || e.keyCode === 27) - && !!this.props.children && !this.props.props.noEsc) { + && !!this.props.children && !this.props.noEsc) { this.props.onClose(); } } diff --git a/app/javascript/flavours/glitch/features/ui/components/modal_root.js b/app/javascript/flavours/glitch/features/ui/components/modal_root.js index 320c039a4..cdb6dc9d0 100644 --- a/app/javascript/flavours/glitch/features/ui/components/modal_root.js +++ b/app/javascript/flavours/glitch/features/ui/components/modal_root.js @@ -59,7 +59,7 @@ export default class ModalRoot extends React.PureComponent { const visible = !!type; return ( - + {visible && ( {(SpecificComponent) => } -- cgit From 971218d1dce176d3b1cdc83c07b96aae7abde58d Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Fri, 11 May 2018 16:45:15 +0200 Subject: Change local settings SCSS to be more consistent with modals --- .../flavours/glitch/styles/components/local_settings.scss | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/components/local_settings.scss b/app/javascript/flavours/glitch/styles/components/local_settings.scss index 9e1606e99..9cd4e1fbe 100644 --- a/app/javascript/flavours/glitch/styles/components/local_settings.scss +++ b/app/javascript/flavours/glitch/styles/components/local_settings.scss @@ -35,8 +35,8 @@ display: block; padding: 15px 20px; color: inherit; - background: $primary-text-color; - border-bottom: 1px $ui-primary-color solid; + background: lighten($ui-secondary-color, 8%); + border-bottom: 1px $ui-secondary-color solid; cursor: pointer; text-decoration: none; outline: none; @@ -58,8 +58,7 @@ } .glitch.local-settings__navigation { - background: $simple-background-color; - color: $inverted-text-color; + background: lighten($ui-secondary-color, 8%); width: 200px; font-size: 15px; line-height: 20px; -- cgit From dfa60cb0a865a6477c92ea8dd3ee0c3aa033a56a Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Tue, 15 May 2018 10:39:12 +0200 Subject: Fix modals testing for props.noEsc (fixes #482) --- app/javascript/flavours/glitch/features/ui/components/modal_root.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/features/ui/components/modal_root.js b/app/javascript/flavours/glitch/features/ui/components/modal_root.js index cdb6dc9d0..7e9980ef7 100644 --- a/app/javascript/flavours/glitch/features/ui/components/modal_root.js +++ b/app/javascript/flavours/glitch/features/ui/components/modal_root.js @@ -59,7 +59,7 @@ export default class ModalRoot extends React.PureComponent { const visible = !!type; return ( - + {visible && ( {(SpecificComponent) => } -- cgit From eb9c9855ce3385bfaefaac36604e6fba8af448fe Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 16 May 2018 19:37:44 +0200 Subject: Fix mastodon-light background color of the composer textarea when posting --- app/javascript/flavours/glitch/styles/mastodon-light.scss | 2 ++ 1 file changed, 2 insertions(+) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/styles/mastodon-light.scss b/app/javascript/flavours/glitch/styles/mastodon-light.scss index 46f88c994..029d5dde2 100644 --- a/app/javascript/flavours/glitch/styles/mastodon-light.scss +++ b/app/javascript/flavours/glitch/styles/mastodon-light.scss @@ -122,6 +122,8 @@ $account-background-color: white; .composer--spoiler input, .composer--textarea textarea { color: darken($ui-base-color, 80%); + &:disabled { background: darken($simple-background-color, 10%) } + &::placeholder { color: darken($ui-base-color, 70%); } -- cgit From a5fac975f3951e954f8a1685150e716250a16a78 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Thu, 29 Mar 2018 21:13:47 +0200 Subject: [Glitch] Feature: Direct message from menu Port d1f34151aee564bb1e60ee48107797681c869a81 to glitch-soc --- app/javascript/flavours/glitch/actions/compose.js | 14 +++++++ .../features/account/components/action_bar.js | 3 ++ .../features/account_timeline/components/header.js | 6 +++ .../containers/header_container.js | 13 +++++- .../features/composer/direct_warning/index.js | 49 ++++++++++++++++++++++ .../flavours/glitch/features/composer/index.js | 2 + app/javascript/flavours/glitch/reducers/compose.js | 7 ++++ 7 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 app/javascript/flavours/glitch/features/composer/direct_warning/index.js (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/actions/compose.js b/app/javascript/flavours/glitch/actions/compose.js index 8a6ca3699..39381faa8 100644 --- a/app/javascript/flavours/glitch/actions/compose.js +++ b/app/javascript/flavours/glitch/actions/compose.js @@ -21,6 +21,7 @@ export const COMPOSE_SUBMIT_SUCCESS = 'COMPOSE_SUBMIT_SUCCESS'; export const COMPOSE_SUBMIT_FAIL = 'COMPOSE_SUBMIT_FAIL'; export const COMPOSE_REPLY = 'COMPOSE_REPLY'; export const COMPOSE_REPLY_CANCEL = 'COMPOSE_REPLY_CANCEL'; +export const COMPOSE_DIRECT = 'COMPOSE_DIRECT'; export const COMPOSE_MENTION = 'COMPOSE_MENTION'; export const COMPOSE_RESET = 'COMPOSE_RESET'; export const COMPOSE_UPLOAD_REQUEST = 'COMPOSE_UPLOAD_REQUEST'; @@ -102,6 +103,19 @@ export function mentionCompose(account, router) { }; }; +export function directCompose(account, router) { + return (dispatch, getState) => { + dispatch({ + type: COMPOSE_DIRECT, + account: account, + }); + + if (!getState().getIn(['compose', 'mounted'])) { + router.push('/statuses/new'); + } + }; +}; + export function submitCompose() { return function (dispatch, getState) { let status = getState().getIn(['compose', 'text'], ''); diff --git a/app/javascript/flavours/glitch/features/account/components/action_bar.js b/app/javascript/flavours/glitch/features/account/components/action_bar.js index fb90722f3..8b95c08f2 100644 --- a/app/javascript/flavours/glitch/features/account/components/action_bar.js +++ b/app/javascript/flavours/glitch/features/account/components/action_bar.js @@ -8,6 +8,7 @@ import { me } from 'flavours/glitch/util/initial_state'; const messages = defineMessages({ mention: { id: 'account.mention', defaultMessage: 'Mention @{name}' }, + direct: { id: 'account.direct', defaultMessage: 'Direct message @{name}' }, edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' }, unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' }, unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' }, @@ -32,6 +33,7 @@ export default class ActionBar extends React.PureComponent { onFollow: PropTypes.func, onBlock: PropTypes.func.isRequired, onMention: PropTypes.func.isRequired, + onDirect: PropTypes.func.isRequired, onReblogToggle: PropTypes.func.isRequired, onReport: PropTypes.func.isRequired, onMute: PropTypes.func.isRequired, @@ -53,6 +55,7 @@ export default class ActionBar extends React.PureComponent { let extraInfo = ''; menu.push({ text: intl.formatMessage(messages.mention, { name: account.get('username') }), action: this.props.onMention }); + menu.push({ text: intl.formatMessage(messages.direct, { name: account.get('username') }), action: this.props.onDirect }); if ('share' in navigator) { menu.push({ text: intl.formatMessage(messages.share, { name: account.get('username') }), action: this.handleShare }); diff --git a/app/javascript/flavours/glitch/features/account_timeline/components/header.js b/app/javascript/flavours/glitch/features/account_timeline/components/header.js index 39a1850d7..a1434b8dd 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/components/header.js +++ b/app/javascript/flavours/glitch/features/account_timeline/components/header.js @@ -16,6 +16,7 @@ export default class Header extends ImmutablePureComponent { onFollow: PropTypes.func.isRequired, onBlock: PropTypes.func.isRequired, onMention: PropTypes.func.isRequired, + onDirect: PropTypes.func.isRequired, onReblogToggle: PropTypes.func.isRequired, onReport: PropTypes.func.isRequired, onMute: PropTypes.func.isRequired, @@ -40,6 +41,10 @@ export default class Header extends ImmutablePureComponent { this.props.onMention(this.props.account, this.context.router.history); } + handleDirect = () => { + this.props.onDirect(this.props.account, this.context.router.history); + } + handleReport = () => { this.props.onReport(this.props.account); } @@ -89,6 +94,7 @@ export default class Header extends ImmutablePureComponent { account={account} onBlock={this.handleBlock} onMention={this.handleMention} + onDirect={this.handleDirect} onReblogToggle={this.handleReblogToggle} onReport={this.handleReport} onMute={this.handleMute} diff --git a/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js b/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js index 848119c63..fb0edfa88 100644 --- a/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js +++ b/app/javascript/flavours/glitch/features/account_timeline/containers/header_container.js @@ -9,7 +9,10 @@ import { unblockAccount, unmuteAccount, } from 'flavours/glitch/actions/accounts'; -import { mentionCompose } from 'flavours/glitch/actions/compose'; +import { + mentionCompose, + directCompose +} from 'flavours/glitch/actions/compose'; import { initMuteModal } from 'flavours/glitch/actions/mutes'; import { initReport } from 'flavours/glitch/actions/reports'; import { openModal } from 'flavours/glitch/actions/modal'; @@ -67,6 +70,14 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ dispatch(mentionCompose(account, router)); }, + onDirect (account, router) { + dispatch(directCompose(account, router)); + }, + + onDirect (account, router) { + dispatch(directCompose(account, router)); + }, + onReblogToggle (account) { if (account.getIn(['relationship', 'showing_reblogs'])) { dispatch(followAccount(account.get('id'), false)); diff --git a/app/javascript/flavours/glitch/features/composer/direct_warning/index.js b/app/javascript/flavours/glitch/features/composer/direct_warning/index.js new file mode 100644 index 000000000..947096aed --- /dev/null +++ b/app/javascript/flavours/glitch/features/composer/direct_warning/index.js @@ -0,0 +1,49 @@ +import React from 'react'; +import Motion from 'flavours/glitch/util/optional_motion'; +import spring from 'react-motion/lib/spring'; +import { defineMessages, FormattedMessage } from 'react-intl'; + +// This is the spring used with our motion. +const motionSpring = spring(1, { damping: 35, stiffness: 400 }); + +// Messages. +const messages = defineMessages({ + disclaimer: { + defaultMessage: 'This toot will only be visible to all the mentioned users.', + id: 'compose_form.direct_message_warning', + }, +}); + +// The component. +export default function ComposerDirectWarning () { + return ( + + {({ opacity, scaleX, scaleY }) => ( +
+ +
+ )} +
+ ); +} + +ComposerDirectWarning.propTypes = {}; diff --git a/app/javascript/flavours/glitch/features/composer/index.js b/app/javascript/flavours/glitch/features/composer/index.js index 3aa283628..de85340a3 100644 --- a/app/javascript/flavours/glitch/features/composer/index.js +++ b/app/javascript/flavours/glitch/features/composer/index.js @@ -39,6 +39,7 @@ import ComposerTextarea from './textarea'; import ComposerUploadForm from './upload_form'; import ComposerWarning from './warning'; import ComposerHashtagWarning from './hashtag_warning'; +import ComposerDirectWarning from './direct_warning'; // Utils. import { countableText } from 'flavours/glitch/util/counter'; @@ -326,6 +327,7 @@ class Composer extends React.Component { onSubmit={handleSubmit} text={spoilerText} /> + {privacy === 'direct' ? : null} {privacy === 'private' && amUnlocked ? : null} {privacy !== 'public' && APPROX_HASHTAG_RE.test(text) ? : null} {replyContent ? ( diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js index 8973c7713..68c7e11f1 100644 --- a/app/javascript/flavours/glitch/reducers/compose.js +++ b/app/javascript/flavours/glitch/reducers/compose.js @@ -5,6 +5,7 @@ import { COMPOSE_CYCLE_ELEFRIEND, COMPOSE_REPLY, COMPOSE_REPLY_CANCEL, + COMPOSE_DIRECT, COMPOSE_MENTION, COMPOSE_SUBMIT_REQUEST, COMPOSE_SUBMIT_SUCCESS, @@ -325,6 +326,12 @@ export default function compose(state = initialState, action) { .update('text', text => `${text}@${action.account.get('acct')} `) .set('focusDate', new Date()) .set('idempotencyKey', uuid()); + case COMPOSE_DIRECT: + return state + .update('text', text => `${text}@${action.account.get('acct')} `) + .set('privacy', 'direct') + .set('focusDate', new Date()) + .set('idempotencyKey', uuid()); case COMPOSE_SUGGESTIONS_CLEAR: return state.update('suggestions', ImmutableList(), list => list.clear()).set('suggestion_token', null); case COMPOSE_SUGGESTIONS_READY: -- cgit From fb6de5310dd2537af6dd94ada7e521d7ab5dfb09 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Mon, 2 Apr 2018 17:15:29 +0200 Subject: [Glitch] Fix issues with sending direct messages from user profile Port 4fd71accd419fb79cc75e0ebf30df374d174ebf5 to glitch-soc --- app/javascript/flavours/glitch/reducers/compose.js | 2 +- app/javascript/flavours/glitch/reducers/search.js | 7 ++++++- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js index 68c7e11f1..bf0395a39 100644 --- a/app/javascript/flavours/glitch/reducers/compose.js +++ b/app/javascript/flavours/glitch/reducers/compose.js @@ -328,7 +328,7 @@ export default function compose(state = initialState, action) { .set('idempotencyKey', uuid()); case COMPOSE_DIRECT: return state - .update('text', text => `${text}@${action.account.get('acct')} `) + .update('text', text => `@${action.account.get('acct')} `) .set('privacy', 'direct') .set('focusDate', new Date()) .set('idempotencyKey', uuid()); diff --git a/app/javascript/flavours/glitch/reducers/search.js b/app/javascript/flavours/glitch/reducers/search.js index f9bf92098..dc6be97e2 100644 --- a/app/javascript/flavours/glitch/reducers/search.js +++ b/app/javascript/flavours/glitch/reducers/search.js @@ -4,7 +4,11 @@ import { SEARCH_FETCH_SUCCESS, SEARCH_SHOW, } from 'flavours/glitch/actions/search'; -import { COMPOSE_MENTION, COMPOSE_REPLY } from 'flavours/glitch/actions/compose'; +import { + COMPOSE_MENTION, + COMPOSE_REPLY, + COMPOSE_DIRECT, +} from 'flavours/glitch/actions/compose'; import { Map as ImmutableMap, List as ImmutableList } from 'immutable'; const initialState = ImmutableMap({ @@ -29,6 +33,7 @@ export default function search(state = initialState, action) { return state.set('hidden', false); case COMPOSE_REPLY: case COMPOSE_MENTION: + case COMPOSE_DIRECT: return state.set('hidden', true); case SEARCH_FETCH_SUCCESS: return state.set('results', ImmutableMap({ -- cgit From 97c69de4162bf9dd5670c68ed03a6bb998e7c53d Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Tue, 10 Apr 2018 21:38:02 +0200 Subject: [Glitch] Feature: Direct message from Statuses Port 904a2479dd2085dfc94f33746ad6f7a755e72609 to glitch-soc --- app/javascript/flavours/glitch/components/status.js | 2 ++ .../flavours/glitch/components/status_action_bar.js | 7 +++++++ .../flavours/glitch/containers/status_container.js | 5 +++++ .../glitch/features/status/components/action_bar.js | 8 ++++++++ .../flavours/glitch/features/status/index.js | 6 ++++++ app/javascript/flavours/glitch/reducers/compose.js | 20 +++++++++++--------- 6 files changed, 39 insertions(+), 9 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/components/status.js b/app/javascript/flavours/glitch/components/status.js index bff396f04..f929d17a6 100644 --- a/app/javascript/flavours/glitch/components/status.js +++ b/app/javascript/flavours/glitch/components/status.js @@ -32,6 +32,8 @@ export default class Status extends ImmutablePureComponent { onFavourite: PropTypes.func, onReblog: PropTypes.func, onDelete: PropTypes.func, + onDirect: PropTypes.func, + onMention: PropTypes.func, onPin: PropTypes.func, onOpenMedia: PropTypes.func, onOpenVideo: PropTypes.func, diff --git a/app/javascript/flavours/glitch/components/status_action_bar.js b/app/javascript/flavours/glitch/components/status_action_bar.js index da6e4e6ba..6ae4bc08d 100644 --- a/app/javascript/flavours/glitch/components/status_action_bar.js +++ b/app/javascript/flavours/glitch/components/status_action_bar.js @@ -10,6 +10,7 @@ import RelativeTimestamp from './relative_timestamp'; const messages = defineMessages({ delete: { id: 'status.delete', defaultMessage: 'Delete' }, + direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' }, mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' }, mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' }, block: { id: 'account.block', defaultMessage: 'Block @{name}' }, @@ -44,6 +45,7 @@ export default class StatusActionBar extends ImmutablePureComponent { onFavourite: PropTypes.func, onReblog: PropTypes.func, onDelete: PropTypes.func, + onDirect: PropTypes.func, onMention: PropTypes.func, onMute: PropTypes.func, onBlock: PropTypes.func, @@ -98,6 +100,10 @@ export default class StatusActionBar extends ImmutablePureComponent { this.props.onMention(this.props.status.get('account'), this.context.router.history); } + handleDirectClick = () => { + this.props.onDirect(this.props.status.get('account'), this.context.router.history); + } + handleMuteClick = () => { this.props.onMute(this.props.status.get('account')); } @@ -157,6 +163,7 @@ export default class StatusActionBar extends ImmutablePureComponent { menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); } else { menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick }); + menu.push({ text: intl.formatMessage(messages.direct, { name: status.getIn(['account', 'username']) }), action: this.handleDirectClick }); menu.push(null); menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick }); menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick }); diff --git a/app/javascript/flavours/glitch/containers/status_container.js b/app/javascript/flavours/glitch/containers/status_container.js index 3fc6a6a79..acec00e12 100644 --- a/app/javascript/flavours/glitch/containers/status_container.js +++ b/app/javascript/flavours/glitch/containers/status_container.js @@ -5,6 +5,7 @@ import { makeGetStatus } from 'flavours/glitch/selectors'; import { replyCompose, mentionCompose, + directCompose, } from 'flavours/glitch/actions/compose'; import { reblog, @@ -131,6 +132,10 @@ const mapDispatchToProps = (dispatch, { intl }) => ({ } }, + onDirect (account, router) { + dispatch(directCompose(account, router)); + }, + onMention (account, router) { dispatch(mentionCompose(account, router)); }, diff --git a/app/javascript/flavours/glitch/features/status/components/action_bar.js b/app/javascript/flavours/glitch/features/status/components/action_bar.js index 1ea0fa421..003f134a8 100644 --- a/app/javascript/flavours/glitch/features/status/components/action_bar.js +++ b/app/javascript/flavours/glitch/features/status/components/action_bar.js @@ -8,6 +8,7 @@ import { me } from 'flavours/glitch/util/initial_state'; const messages = defineMessages({ delete: { id: 'status.delete', defaultMessage: 'Delete' }, + direct: { id: 'status.direct', defaultMessage: 'Direct message @{name}' }, mention: { id: 'status.mention', defaultMessage: 'Mention @{name}' }, reply: { id: 'status.reply', defaultMessage: 'Reply' }, reblog: { id: 'status.reblog', defaultMessage: 'Boost' }, @@ -43,6 +44,7 @@ export default class ActionBar extends React.PureComponent { onMuteConversation: PropTypes.func, onBlock: PropTypes.func, onDelete: PropTypes.func.isRequired, + onDirect: PropTypes.func.isRequired, onMention: PropTypes.func.isRequired, onReport: PropTypes.func, onPin: PropTypes.func, @@ -70,6 +72,10 @@ export default class ActionBar extends React.PureComponent { this.props.onDelete(this.props.status); } + handleDirectClick = () => { + this.props.onDirect(this.props.status.get('account'), this.context.router.history); + } + handleMentionClick = () => { this.props.onMention(this.props.status.get('account'), this.context.router.history); } @@ -115,6 +121,7 @@ export default class ActionBar extends React.PureComponent { if (publicStatus) { menu.push({ text: intl.formatMessage(messages.embed), action: this.handleEmbed }); + menu.push(null); } if (me === status.getIn(['account', 'id'])) { @@ -128,6 +135,7 @@ export default class ActionBar extends React.PureComponent { menu.push({ text: intl.formatMessage(messages.delete), action: this.handleDeleteClick }); } else { menu.push({ text: intl.formatMessage(messages.mention, { name: status.getIn(['account', 'username']) }), action: this.handleMentionClick }); + menu.push({ text: intl.formatMessage(messages.direct, { name: status.getIn(['account', 'username']) }), action: this.handleDirectClick }); menu.push(null); menu.push({ text: intl.formatMessage(messages.mute, { name: status.getIn(['account', 'username']) }), action: this.handleMuteClick }); menu.push({ text: intl.formatMessage(messages.block, { name: status.getIn(['account', 'username']) }), action: this.handleBlockClick }); diff --git a/app/javascript/flavours/glitch/features/status/index.js b/app/javascript/flavours/glitch/features/status/index.js index 7e1658dbb..6c9da8e3e 100644 --- a/app/javascript/flavours/glitch/features/status/index.js +++ b/app/javascript/flavours/glitch/features/status/index.js @@ -21,6 +21,7 @@ import { import { replyCompose, mentionCompose, + directCompose, } from 'flavours/glitch/actions/compose'; import { blockAccount } from 'flavours/glitch/actions/accounts'; import { muteStatus, unmuteStatus, deleteStatus } from 'flavours/glitch/actions/statuses'; @@ -170,6 +171,10 @@ export default class Status extends ImmutablePureComponent { } } + handleDirectClick = (account, router) => { + this.props.dispatch(directCompose(account, router)); + } + handleMentionClick = (account, router) => { this.props.dispatch(mentionCompose(account, router)); } @@ -399,6 +404,7 @@ export default class Status extends ImmutablePureComponent { onReblog={this.handleReblogClick} onBookmark={this.handleBookmarkClick} onDelete={this.handleDeleteClick} + onDirect={this.handleDirectClick} onMention={this.handleMentionClick} onMute={this.handleMuteClick} onMuteConversation={this.handleConversationMuteClick} diff --git a/app/javascript/flavours/glitch/reducers/compose.js b/app/javascript/flavours/glitch/reducers/compose.js index bf0395a39..f79fa63d2 100644 --- a/app/javascript/flavours/glitch/reducers/compose.js +++ b/app/javascript/flavours/glitch/reducers/compose.js @@ -322,16 +322,18 @@ export default function compose(state = initialState, action) { case COMPOSE_UPLOAD_PROGRESS: return state.set('progress', Math.round((action.loaded / action.total) * 100)); case COMPOSE_MENTION: - return state - .update('text', text => `${text}@${action.account.get('acct')} `) - .set('focusDate', new Date()) - .set('idempotencyKey', uuid()); + return state.withMutations(map => { + map.update('text', text => [text.trim(), `@${action.account.get('acct')} `].filter((str) => str.length !== 0).join(' ')); + map.set('focusDate', new Date()); + map.set('idempotencyKey', uuid()); + }); case COMPOSE_DIRECT: - return state - .update('text', text => `@${action.account.get('acct')} `) - .set('privacy', 'direct') - .set('focusDate', new Date()) - .set('idempotencyKey', uuid()); + return state.withMutations(map => { + map.update('text', text => [text.trim(), `@${action.account.get('acct')} `].filter((str) => str.length !== 0).join(' ')); + map.set('privacy', 'direct'); + map.set('focusDate', new Date()); + map.set('idempotencyKey', uuid()); + }); case COMPOSE_SUGGESTIONS_CLEAR: return state.update('suggestions', ImmutableList(), list => list.clear()).set('suggestion_token', null); case COMPOSE_SUGGESTIONS_READY: -- cgit From 784712791da8c7d21afa62a3bf6a8fdac8c27a80 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Wed, 16 May 2018 19:45:02 +0200 Subject: [Glitch] Reword the direct message warning Port 53c2164e9c8e2538de386a526a97db187ecae470 to glitch-soc --- .../flavours/glitch/features/composer/direct_warning/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/features/composer/direct_warning/index.js b/app/javascript/flavours/glitch/features/composer/direct_warning/index.js index 947096aed..804c6538b 100644 --- a/app/javascript/flavours/glitch/features/composer/direct_warning/index.js +++ b/app/javascript/flavours/glitch/features/composer/direct_warning/index.js @@ -9,7 +9,7 @@ const motionSpring = spring(1, { damping: 35, stiffness: 400 }); // Messages. const messages = defineMessages({ disclaimer: { - defaultMessage: 'This toot will only be visible to all the mentioned users.', + defaultMessage: 'This toot will only be sent to all the mentioned users. However, the operators of your instance and any receiving instances may see this message.', id: 'compose_form.direct_message_warning', }, }); -- cgit From ca49ad86c6e1f53279a89e5f3c18a92b7ceb76b2 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Thu, 17 May 2018 15:39:37 +0200 Subject: Remove service worker code that has never been used --- .../flavours/glitch/service_worker/entry.js | 10 -- .../service_worker/web_push_notifications.js | 159 --------------------- 2 files changed, 169 deletions(-) delete mode 100644 app/javascript/flavours/glitch/service_worker/entry.js delete mode 100644 app/javascript/flavours/glitch/service_worker/web_push_notifications.js (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/service_worker/entry.js b/app/javascript/flavours/glitch/service_worker/entry.js deleted file mode 100644 index eea4cfc3c..000000000 --- a/app/javascript/flavours/glitch/service_worker/entry.js +++ /dev/null @@ -1,10 +0,0 @@ -import './web_push_notifications'; - -// Cause a new version of a registered Service Worker to replace an existing one -// that is already installed, and replace the currently active worker on open pages. -self.addEventListener('install', function(event) { - event.waitUntil(self.skipWaiting()); -}); -self.addEventListener('activate', function(event) { - event.waitUntil(self.clients.claim()); -}); diff --git a/app/javascript/flavours/glitch/service_worker/web_push_notifications.js b/app/javascript/flavours/glitch/service_worker/web_push_notifications.js deleted file mode 100644 index f63cff335..000000000 --- a/app/javascript/flavours/glitch/service_worker/web_push_notifications.js +++ /dev/null @@ -1,159 +0,0 @@ -const MAX_NOTIFICATIONS = 5; -const GROUP_TAG = 'tag'; - -// Avoid loading intl-messageformat and dealing with locales in the ServiceWorker -const formatGroupTitle = (message, count) => message.replace('%{count}', count); - -const notify = options => - self.registration.getNotifications().then(notifications => { - if (notifications.length === MAX_NOTIFICATIONS) { - // Reached the maximum number of notifications, proceed with grouping - const group = { - title: formatGroupTitle(options.data.message, notifications.length + 1), - body: notifications - .sort((n1, n2) => n1.timestamp < n2.timestamp) - .map(notification => notification.title).join('\n'), - badge: '/badge.png', - icon: '/android-chrome-192x192.png', - tag: GROUP_TAG, - data: { - url: (new URL('/web/notifications', self.location)).href, - count: notifications.length + 1, - message: options.data.message, - }, - }; - - notifications.forEach(notification => notification.close()); - - return self.registration.showNotification(group.title, group); - } else if (notifications.length === 1 && notifications[0].tag === GROUP_TAG) { - // Already grouped, proceed with appending the notification to the group - const group = cloneNotification(notifications[0]); - - group.title = formatGroupTitle(group.data.message, group.data.count + 1); - group.body = `${options.title}\n${group.body}`; - group.data = { ...group.data, count: group.data.count + 1 }; - - return self.registration.showNotification(group.title, group); - } - - return self.registration.showNotification(options.title, options); - }); - -const handlePush = (event) => { - const options = event.data.json(); - - options.body = options.data.nsfw || options.data.content; - options.dir = options.data.dir; - options.image = options.image || undefined; // Null results in a network request (404) - options.timestamp = options.timestamp && new Date(options.timestamp); - - const expandAction = options.data.actions.find(action => action.todo === 'expand'); - - if (expandAction) { - options.actions = [expandAction]; - options.hiddenActions = options.data.actions.filter(action => action !== expandAction); - options.data.hiddenImage = options.image; - options.image = undefined; - } else { - options.actions = options.data.actions; - } - - event.waitUntil(notify(options)); -}; - -const cloneNotification = (notification) => { - const clone = { }; - - for(var k in notification) { - clone[k] = notification[k]; - } - - return clone; -}; - -const expandNotification = (notification) => { - const nextNotification = cloneNotification(notification); - - nextNotification.body = notification.data.content; - nextNotification.image = notification.data.hiddenImage; - nextNotification.actions = notification.data.actions.filter(action => action.todo !== 'expand'); - - return self.registration.showNotification(nextNotification.title, nextNotification); -}; - -const makeRequest = (notification, action) => - fetch(action.action, { - headers: { - 'Authorization': `Bearer ${notification.data.access_token}`, - 'Content-Type': 'application/json', - }, - method: action.method, - credentials: 'include', - }); - -const findBestClient = clients => { - const focusedClient = clients.find(client => client.focused); - const visibleClient = clients.find(client => client.visibilityState === 'visible'); - - return focusedClient || visibleClient || clients[0]; -}; - -const openUrl = url => - self.clients.matchAll({ type: 'window' }).then(clientList => { - if (clientList.length !== 0) { - const webClients = clientList.filter(client => /\/web\//.test(client.url)); - - if (webClients.length !== 0) { - const client = findBestClient(webClients); - const { pathname } = new URL(url); - - if (pathname.startsWith('/web/')) { - return client.focus().then(client => client.postMessage({ - type: 'navigate', - path: pathname.slice('/web/'.length - 1), - })); - } - } else if ('navigate' in clientList[0]) { // Chrome 42-48 does not support navigate - const client = findBestClient(clientList); - - return client.navigate(url).then(client => client.focus()); - } - } - - return self.clients.openWindow(url); - }); - -const removeActionFromNotification = (notification, action) => { - const actions = notification.actions.filter(act => act.action !== action.action); - const nextNotification = cloneNotification(notification); - - nextNotification.actions = actions; - - return self.registration.showNotification(nextNotification.title, nextNotification); -}; - -const handleNotificationClick = (event) => { - const reactToNotificationClick = new Promise((resolve, reject) => { - if (event.action) { - const action = event.notification.data.actions.find(({ action }) => action === event.action); - - if (action.todo === 'expand') { - resolve(expandNotification(event.notification)); - } else if (action.todo === 'request') { - resolve(makeRequest(event.notification, action) - .then(() => removeActionFromNotification(event.notification, action))); - } else { - reject(`Unknown action: ${action.todo}`); - } - } else { - event.notification.close(); - resolve(openUrl(event.notification.data.url)); - } - }); - - event.waitUntil(reactToNotificationClick); -}; - -self.addEventListener('push', handlePush); -self.addEventListener('notificationclick', handleNotificationClick); -- cgit From 52b2f18b150607f20c246a17ba188c8e78153e35 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Thu, 17 May 2018 15:57:16 +0200 Subject: [Glitch] Enable custom emojis in profiles Port 61a90186070395e133ad2f8e959bdf003a8615ca to glitch-soc --- app/javascript/flavours/glitch/reducers/accounts.js | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/reducers/accounts.js b/app/javascript/flavours/glitch/reducers/accounts.js index e8127a871..86f4970c9 100644 --- a/app/javascript/flavours/glitch/reducers/accounts.js +++ b/app/javascript/flavours/glitch/reducers/accounts.js @@ -59,6 +59,11 @@ import { Map as ImmutableMap, fromJS } from 'immutable'; import escapeTextContentForBrowser from 'escape-html'; import { unescapeHTML } from 'flavours/glitch/util/html'; +const makeEmojiMap = record => record.emojis.reduce((obj, emoji) => { + obj[`:${emoji.shortcode}:`] = emoji; + return obj; +}, {}); + const normalizeAccount = (state, account) => { account = { ...account }; @@ -66,15 +71,16 @@ const normalizeAccount = (state, account) => { delete account.following_count; delete account.statuses_count; + const emojiMap = makeEmojiMap(account); const displayName = account.display_name.length === 0 ? account.username : account.display_name; - account.display_name_html = emojify(escapeTextContentForBrowser(displayName)); - account.note_emojified = emojify(account.note); + account.display_name_html = emojify(escapeTextContentForBrowser(displayName), emojiMap); + account.note_emojified = emojify(account.note, emojiMap); if (account.fields) { account.fields = account.fields.map(pair => ({ ...pair, name_emojified: emojify(escapeTextContentForBrowser(pair.name)), - value_emojified: emojify(pair.value), + value_emojified: emojify(pair.value, emojiMap), value_plain: unescapeHTML(pair.value), })); } -- cgit From dd1d98f9cf405104ef106ee5f376bd09815dac42 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Thu, 17 May 2018 16:45:19 +0200 Subject: [Glitch] Show card modal on public pages Port 16fee0335f2b10b0ce54f71965d2f2acc0e24942 to glitch-soc --- .../flavours/glitch/containers/card_container.js | 18 ------- .../flavours/glitch/containers/cards_container.js | 59 ++++++++++++++++++++++ app/javascript/flavours/glitch/packs/public.js | 15 ++++-- 3 files changed, 69 insertions(+), 23 deletions(-) delete mode 100644 app/javascript/flavours/glitch/containers/card_container.js create mode 100644 app/javascript/flavours/glitch/containers/cards_container.js (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/containers/card_container.js b/app/javascript/flavours/glitch/containers/card_container.js deleted file mode 100644 index dec7df522..000000000 --- a/app/javascript/flavours/glitch/containers/card_container.js +++ /dev/null @@ -1,18 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import Card from 'flavours/glitch/features/status/components/card'; -import { fromJS } from 'immutable'; - -export default class CardContainer extends React.PureComponent { - - static propTypes = { - locale: PropTypes.string, - card: PropTypes.array.isRequired, - }; - - render () { - const { card, ...props } = this.props; - return ; - } - -} diff --git a/app/javascript/flavours/glitch/containers/cards_container.js b/app/javascript/flavours/glitch/containers/cards_container.js new file mode 100644 index 000000000..1cf980f65 --- /dev/null +++ b/app/javascript/flavours/glitch/containers/cards_container.js @@ -0,0 +1,59 @@ +import React, { Fragment } from 'react'; +import ReactDOM from 'react-dom'; +import PropTypes from 'prop-types'; +import { IntlProvider, addLocaleData } from 'react-intl'; +import { getLocale } from '../locales'; +import Card from 'flavours/glitch/features/status/components/card'; +import ModalRoot from 'flavours/glitch/components/modal_root'; +import MediaModal from 'flavours/glitch/features/ui/components/media_modal'; +import { fromJS } from 'immutable'; + +const { localeData, messages } = getLocale(); +addLocaleData(localeData); + +export default class CardsContainer extends React.PureComponent { + + static propTypes = { + locale: PropTypes.string, + cards: PropTypes.object.isRequired, + }; + + state = { + media: null, + }; + + handleOpenCard = (media) => { + document.body.classList.add('card-standalone__body'); + this.setState({ media }); + } + + handleCloseCard = () => { + document.body.classList.remove('card-standalone__body'); + this.setState({ media: null }); + } + + render () { + const { locale, cards } = this.props; + + return ( + + + {[].map.call(cards, container => { + const { card, ...props } = JSON.parse(container.getAttribute('data-props')); + + return ReactDOM.createPortal( + , + container, + ); + })} + + {this.state.media && ( + + )} + + + + ); + } + +} diff --git a/app/javascript/flavours/glitch/packs/public.js b/app/javascript/flavours/glitch/packs/public.js index ed685b6b7..4e621c67f 100644 --- a/app/javascript/flavours/glitch/packs/public.js +++ b/app/javascript/flavours/glitch/packs/public.js @@ -7,7 +7,6 @@ function main() { const { getLocale } = require('locales'); const { localeData } = getLocale(); const VideoContainer = require('flavours/glitch/containers/video_container').default; - const CardContainer = require('flavours/glitch/containers/card_container').default; const React = require('react'); const ReactDOM = require('react-dom'); @@ -57,10 +56,16 @@ function main() { ReactDOM.render(, content); }); - [].forEach.call(document.querySelectorAll('[data-component="Card"]'), (content) => { - const props = JSON.parse(content.getAttribute('data-props')); - ReactDOM.render(, content); - }); + const cards = document.querySelectorAll('[data-component="Card"]'); + + if (cards.length > 0) { + import(/* webpackChunkName: "containers/cards_container" */ '../mastodon/containers/cards_container').then(({ default: CardsContainer }) => { + const content = document.createElement('div'); + + ReactDOM.render(, content); + document.body.appendChild(content); + }).catch(error => console.error(error)); + } const mediaGalleries = document.querySelectorAll('[data-component="MediaGallery"]'); -- cgit From 94db024e4c42027e8c03bf0ecd2aec26ee73a56c Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Thu, 17 May 2018 16:53:58 +0200 Subject: [Glitch] Combine similar components into one on public UI Port f9afd06221baf7f635b346dfbe350652ba6ffbd0 to glitch-soc --- .../flavours/glitch/containers/cards_container.js | 59 ----------------- .../flavours/glitch/containers/media_container.js | 75 ++++++++++++++++++++++ .../glitch/containers/media_galleries_container.js | 68 -------------------- .../flavours/glitch/containers/video_container.js | 26 -------- app/javascript/flavours/glitch/packs/public.js | 34 +++------- .../flavours/glitch/styles/containers.scss | 3 +- 6 files changed, 85 insertions(+), 180 deletions(-) delete mode 100644 app/javascript/flavours/glitch/containers/cards_container.js create mode 100644 app/javascript/flavours/glitch/containers/media_container.js delete mode 100644 app/javascript/flavours/glitch/containers/media_galleries_container.js delete mode 100644 app/javascript/flavours/glitch/containers/video_container.js (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/containers/cards_container.js b/app/javascript/flavours/glitch/containers/cards_container.js deleted file mode 100644 index 1cf980f65..000000000 --- a/app/javascript/flavours/glitch/containers/cards_container.js +++ /dev/null @@ -1,59 +0,0 @@ -import React, { Fragment } from 'react'; -import ReactDOM from 'react-dom'; -import PropTypes from 'prop-types'; -import { IntlProvider, addLocaleData } from 'react-intl'; -import { getLocale } from '../locales'; -import Card from 'flavours/glitch/features/status/components/card'; -import ModalRoot from 'flavours/glitch/components/modal_root'; -import MediaModal from 'flavours/glitch/features/ui/components/media_modal'; -import { fromJS } from 'immutable'; - -const { localeData, messages } = getLocale(); -addLocaleData(localeData); - -export default class CardsContainer extends React.PureComponent { - - static propTypes = { - locale: PropTypes.string, - cards: PropTypes.object.isRequired, - }; - - state = { - media: null, - }; - - handleOpenCard = (media) => { - document.body.classList.add('card-standalone__body'); - this.setState({ media }); - } - - handleCloseCard = () => { - document.body.classList.remove('card-standalone__body'); - this.setState({ media: null }); - } - - render () { - const { locale, cards } = this.props; - - return ( - - - {[].map.call(cards, container => { - const { card, ...props } = JSON.parse(container.getAttribute('data-props')); - - return ReactDOM.createPortal( - , - container, - ); - })} - - {this.state.media && ( - - )} - - - - ); - } - -} diff --git a/app/javascript/flavours/glitch/containers/media_container.js b/app/javascript/flavours/glitch/containers/media_container.js new file mode 100644 index 000000000..b79876419 --- /dev/null +++ b/app/javascript/flavours/glitch/containers/media_container.js @@ -0,0 +1,75 @@ +import React, { PureComponent, Fragment } from 'react'; +import ReactDOM from 'react-dom'; +import PropTypes from 'prop-types'; +import { IntlProvider, addLocaleData } from 'react-intl'; +import { getLocale } from 'mastodon/locales'; +import MediaGallery from 'flavours/glitch/components/media_gallery'; +import Video from 'flavours/glitch/features/video'; +import Card from 'flavours/glitch/features/status/components/card'; +import ModalRoot from 'flavours/glitch/components/modal_root'; +import MediaModal from 'flavours/glitch/features/ui/components/media_modal'; +import { fromJS } from 'immutable'; + +const { localeData, messages } = getLocale(); +addLocaleData(localeData); + +const MEDIA_COMPONENTS = { MediaGallery, Video, Card }; + +export default class MediaContainer extends PureComponent { + + static propTypes = { + locale: PropTypes.string.isRequired, + components: PropTypes.object.isRequired, + }; + + state = { + media: null, + index: null, + }; + + handleOpenMedia = (media, index) => { + document.body.classList.add('media-standalone__body'); + this.setState({ media, index }); + } + + handleCloseMedia = () => { + document.body.classList.remove('media-standalone__body'); + this.setState({ media: null, index: null }); + } + + render () { + const { locale, components } = this.props; + + return ( + + + {[].map.call(components, (component, i) => { + const componentName = component.getAttribute('data-component'); + const Component = MEDIA_COMPONENTS[componentName]; + const { media, card, ...props } = JSON.parse(component.getAttribute('data-props')); + + Object.assign(props, { + ...(media ? { media: fromJS(media) } : {}), + ...(card ? { card: fromJS(card) } : {}), + }); + + return ReactDOM.createPortal( + , + component, + ); + })} + + {this.state.media === null || this.state.index === null ? null : ( + + )} + + + + ); + } + +} diff --git a/app/javascript/flavours/glitch/containers/media_galleries_container.js b/app/javascript/flavours/glitch/containers/media_galleries_container.js deleted file mode 100644 index a69457882..000000000 --- a/app/javascript/flavours/glitch/containers/media_galleries_container.js +++ /dev/null @@ -1,68 +0,0 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import PropTypes from 'prop-types'; -import { IntlProvider, addLocaleData } from 'react-intl'; -import { getLocale } from 'mastodon/locales'; -import MediaGallery from 'flavours/glitch/components/media_gallery'; -import ModalRoot from 'flavours/glitch/components/modal_root'; -import MediaModal from 'flavours/glitch/features/ui/components/media_modal'; -import { fromJS } from 'immutable'; - -const { localeData, messages } = getLocale(); -addLocaleData(localeData); - -export default class MediaGalleriesContainer extends React.PureComponent { - - static propTypes = { - locale: PropTypes.string.isRequired, - galleries: PropTypes.object.isRequired, - }; - - state = { - media: null, - index: null, - }; - - handleOpenMedia = (media, index) => { - document.body.classList.add('media-gallery-standalone__body'); - this.setState({ media, index }); - } - - handleCloseMedia = () => { - document.body.classList.remove('media-gallery-standalone__body'); - this.setState({ media: null, index: null }); - } - - render () { - const { locale, galleries } = this.props; - - return ( - - - {[].map.call(galleries, gallery => { - const { media, ...props } = JSON.parse(gallery.getAttribute('data-props')); - - return ReactDOM.createPortal( - , - gallery - ); - })} - - {this.state.media === null || this.state.index === null ? null : ( - - )} - - - - ); - } - -} diff --git a/app/javascript/flavours/glitch/containers/video_container.js b/app/javascript/flavours/glitch/containers/video_container.js deleted file mode 100644 index b206e9a10..000000000 --- a/app/javascript/flavours/glitch/containers/video_container.js +++ /dev/null @@ -1,26 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { IntlProvider, addLocaleData } from 'react-intl'; -import { getLocale } from 'mastodon/locales'; -import Video from 'flavours/glitch/features/video'; - -const { localeData, messages } = getLocale(); -addLocaleData(localeData); - -export default class VideoContainer extends React.PureComponent { - - static propTypes = { - locale: PropTypes.string.isRequired, - }; - - render () { - const { locale, ...props } = this.props; - - return ( - - - ); - } - -} diff --git a/app/javascript/flavours/glitch/packs/public.js b/app/javascript/flavours/glitch/packs/public.js index 4e621c67f..78e8f1053 100644 --- a/app/javascript/flavours/glitch/packs/public.js +++ b/app/javascript/flavours/glitch/packs/public.js @@ -6,7 +6,6 @@ function main() { const emojify = require('flavours/glitch/util/emoji').default; const { getLocale } = require('locales'); const { localeData } = getLocale(); - const VideoContainer = require('flavours/glitch/containers/video_container').default; const React = require('react'); const ReactDOM = require('react-dom'); @@ -51,30 +50,15 @@ function main() { }); }); - [].forEach.call(document.querySelectorAll('[data-component="Video"]'), (content) => { - const props = JSON.parse(content.getAttribute('data-props')); - ReactDOM.render(, content); - }); - - const cards = document.querySelectorAll('[data-component="Card"]'); - - if (cards.length > 0) { - import(/* webpackChunkName: "containers/cards_container" */ '../mastodon/containers/cards_container').then(({ default: CardsContainer }) => { - const content = document.createElement('div'); - - ReactDOM.render(, content); - document.body.appendChild(content); - }).catch(error => console.error(error)); - } - - const mediaGalleries = document.querySelectorAll('[data-component="MediaGallery"]'); - - if (mediaGalleries.length > 0) { - const MediaGalleriesContainer = require('flavours/glitch/containers/media_galleries_container').default; - const content = document.createElement('div'); - - ReactDOM.render(, content); - document.body.appendChild(content); + const reactComponents = document.querySelectorAll('[data-component]'); + if (reactComponents.length > 0) { + import(/* webpackChunkName: "containers/media_container" */ 'flavours/glitch/containers/media_container') + .then(({ default: MediaContainer }) => { + const content = document.createElement('div'); + ReactDOM.render(, content); + document.body.appendChild(content); + }) + .catch(error => console.error(error)); } }); } diff --git a/app/javascript/flavours/glitch/styles/containers.scss b/app/javascript/flavours/glitch/styles/containers.scss index c40b38a5a..ac648c868 100644 --- a/app/javascript/flavours/glitch/styles/containers.scss +++ b/app/javascript/flavours/glitch/styles/containers.scss @@ -60,8 +60,7 @@ } } -.card-standalone__body, -.media-gallery-standalone__body { +.media-standalone__body { overflow: hidden; } -- cgit From 07baa1ddb59356bf42fff8e61fe104cf0af79bad Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Thu, 17 May 2018 17:10:17 +0200 Subject: [Glitch] Open video modal on public UI Port d9b2f84c92f24067b12be81837240bf6c8930236 to glitch-soc --- .../flavours/glitch/components/status.js | 4 ++-- .../flavours/glitch/containers/media_container.js | 25 +++++++++++++++++----- .../features/status/components/detailed_status.js | 4 ++-- .../glitch/features/ui/components/media_modal.js | 17 +++++++++++++++ .../flavours/glitch/features/video/index.js | 24 +++++++++++++++++++-- .../flavours/glitch/styles/components/media.scss | 4 ++++ 6 files changed, 67 insertions(+), 11 deletions(-) (limited to 'app/javascript/flavours/glitch') diff --git a/app/javascript/flavours/glitch/components/status.js b/app/javascript/flavours/glitch/components/status.js index f929d17a6..c93705266 100644 --- a/app/javascript/flavours/glitch/components/status.js +++ b/app/javascript/flavours/glitch/components/status.js @@ -259,8 +259,8 @@ export default class Status extends ImmutablePureComponent { } }; - handleOpenVideo = startTime => { - this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), startTime); + handleOpenVideo = (media, startTime) => { + this.props.onOpenVideo(media, startTime); } handleHotkeyReply = e => { diff --git a/app/javascript/flavours/glitch/containers/media_container.js b/app/javascript/flavours/glitch/containers/media_container.js index b79876419..0e1904132 100644 --- a/app/javascript/flavours/glitch/containers/media_container.js +++ b/app/javascript/flavours/glitch/containers/media_container.js @@ -8,7 +8,7 @@ import Video from 'flavours/glitch/features/video'; import Card from 'flavours/glitch/features/status/components/card'; import ModalRoot from 'flavours/glitch/components/modal_root'; import MediaModal from 'flavours/glitch/features/ui/components/media_modal'; -import { fromJS } from 'immutable'; +import { List as ImmutableList, fromJS } from 'immutable'; const { localeData, messages } = getLocale(); addLocaleData(localeData); @@ -25,6 +25,7 @@ export default class MediaContainer extends PureComponent { state = { media: null, index: null, + time: null, }; handleOpenMedia = (media, index) => { @@ -32,9 +33,16 @@ export default class MediaContainer extends PureComponent { this.setState({ media, index }); } + handleOpenVideo = (video, time) => { + const media = ImmutableList([video]); + + document.body.classList.add('media-standalone__body'); + this.setState({ media, time }); + } + handleCloseMedia = () => { document.body.classList.remove('media-standalone__body'); - this.setState({ media: null, index: null }); + this.setState({ media: null, index: null, time: null }); } render () { @@ -51,18 +59,25 @@ export default class MediaContainer extends PureComponent { Object.assign(props, { ...(media ? { media: fromJS(media) } : {}), ...(card ? { card: fromJS(card) } : {}), + + ...(componentName === 'Video' ? { + onOpenVideo: this.handleOpenVideo, + } : { + onOpenMedia: this.handleOpenMedia, + }), }); return ReactDOM.createPortal( - , + , component, ); })} - {this.state.media === null || this.state.index === null ? null : ( + {this.state.media && ( )} diff --git a/app/javascript/flavours/glitch/features/status/components/detailed_status.js b/app/javascript/flavours/glitch/features/status/components/detailed_status.js index 16f7ae830..5cfc9dfae 100644 --- a/app/javascript/flavours/glitch/features/status/components/detailed_status.js +++ b/app/javascript/flavours/glitch/features/status/components/detailed_status.js @@ -37,8 +37,8 @@ export default class DetailedStatus extends ImmutablePureComponent { e.stopPropagation(); } - handleOpenVideo = startTime => { - this.props.onOpenVideo(this.props.status.getIn(['media_attachments', 0]), startTime); + handleOpenVideo = (media, startTime) => { + this.props.onOpenVideo(media, startTime); } render () { diff --git a/app/javascript/flavours/glitch/features/ui/components/media_modal.js b/app/javascript/flavours/glitch/features/ui/components/media_modal.js index 6ab6770ed..bffe3b1f7 100644 --- a/app/javascript/flavours/glitch/features/ui/components/media_modal.js +++ b/app/javascript/flavours/glitch/features/ui/components/media_modal.js @@ -2,6 +2,7 @@ import React from 'react'; import ReactSwipeableViews from 'react-swipeable-views'; import ImmutablePropTypes from 'react-immutable-proptypes'; import PropTypes from 'prop-types'; +import Video from 'flavours/glitch/features/video'; import ExtendedVideoPlayer from 'flavours/glitch/components/extended_video_player'; import classNames from 'classnames'; import { defineMessages, injectIntl } from 'react-intl'; @@ -112,6 +113,22 @@ export default class MediaModal extends ImmutablePureComponent { onClick={this.toggleNavigation} /> ); + } else if (image.get('type') === 'video') { + const { time } = this.props; + + return ( +