-
+
{children}
diff --git a/app/javascript/mastodon/features/ui/util/async-components.js b/app/javascript/mastodon/features/ui/util/async-components.js
index 235fd2a073..6e8ed163a5 100644
--- a/app/javascript/mastodon/features/ui/util/async-components.js
+++ b/app/javascript/mastodon/features/ui/util/async-components.js
@@ -129,3 +129,7 @@ export function ListEditor () {
export function ListAdder () {
return import(/*webpackChunkName: "features/list_adder" */'../../list_adder');
}
+
+export function Search () {
+ return import(/*webpackChunkName: "features/search" */'../../search');
+}
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
index 00a63a3d9f..b0c4085277 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.js
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
-import { fromJS } from 'immutable';
+import { fromJS, is } from 'immutable';
import { throttle } from 'lodash';
import classNames from 'classnames';
import { isFullscreen, requestFullscreen, exitFullscreen } from '../ui/util/fullscreen';
@@ -102,6 +102,8 @@ class Video extends React.PureComponent {
detailed: PropTypes.bool,
inline: PropTypes.bool,
cacheWidth: PropTypes.func,
+ visible: PropTypes.bool,
+ onToggleVisibility: PropTypes.func,
intl: PropTypes.object.isRequired,
blurhash: PropTypes.string,
link: PropTypes.node,
@@ -117,7 +119,7 @@ class Video extends React.PureComponent {
fullscreen: false,
hovered: false,
muted: false,
- revealed: displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all',
+ revealed: this.props.visible !== undefined ? this.props.visible : (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all'),
};
// hard coded in components.scss
@@ -280,7 +282,16 @@ class Video extends React.PureComponent {
document.removeEventListener('MSFullscreenChange', this.handleFullscreenChange, true);
}
- componentDidUpdate (prevProps) {
+ componentWillReceiveProps (nextProps) {
+ if (!is(nextProps.visible, this.props.visible) && nextProps.visible !== undefined) {
+ this.setState({ revealed: nextProps.visible });
+ }
+ }
+
+ componentDidUpdate (prevProps, prevState) {
+ if (prevState.revealed && !this.state.revealed && this.video) {
+ this.video.pause();
+ }
if (prevProps.blurhash !== this.props.blurhash && this.props.blurhash) {
this._decode();
}
@@ -316,11 +327,11 @@ class Video extends React.PureComponent {
}
toggleReveal = () => {
- if (this.state.revealed) {
- this.video.pause();
+ if (this.props.onToggleVisibility) {
+ this.props.onToggleVisibility();
+ } else {
+ this.setState({ revealed: !this.state.revealed });
}
-
- this.setState({ revealed: !this.state.revealed });
}
handleLoadedData = () => {
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js
index d74f5ceb13..4e0ecef944 100644
--- a/app/javascript/mastodon/initial_state.js
+++ b/app/javascript/mastodon/initial_state.js
@@ -20,5 +20,6 @@ export const version = getMeta('version');
export const mascot = getMeta('mascot');
export const profile_directory = getMeta('profile_directory');
export const isStaff = getMeta('is_staff');
+export const forceSingleColumn = !getMeta('advanced_layout');
export default initialState;
diff --git a/app/javascript/mastodon/reducers/settings.js b/app/javascript/mastodon/reducers/settings.js
index 419c313af3..a0eea137f1 100644
--- a/app/javascript/mastodon/reducers/settings.js
+++ b/app/javascript/mastodon/reducers/settings.js
@@ -14,8 +14,6 @@ const initialState = ImmutableMap({
skinTone: 1,
- forceSingleColumn: false,
-
home: ImmutableMap({
shows: ImmutableMap({
reblog: true,
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index fe3c55755f..6b8b89a031 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -710,7 +710,7 @@
white-space: pre-wrap;
&:last-child {
- margin-bottom: 0;
+ margin-bottom: 2px;
}
}
@@ -1801,7 +1801,12 @@ a.account__display-name {
display: flex;
justify-content: flex-end;
+ &--start {
+ justify-content: flex-start;
+ }
+
&__inner {
+ width: 285px;
pointer-events: auto;
height: 100%;
}
@@ -1925,6 +1930,7 @@ a.account__display-name {
display: block;
flex: 1 1 auto;
padding: 15px 10px;
+ padding-bottom: 13px;
color: $primary-text-color;
text-decoration: none;
text-align: center;
@@ -1949,6 +1955,7 @@ a.account__display-name {
&:active {
@media screen and (min-width: 631px) {
background: lighten($ui-base-color, 14%);
+ border-bottom-color: lighten($ui-base-color, 14%);
}
}
@@ -1978,11 +1985,21 @@ a.account__display-name {
padding: 0;
}
- .search__input,
.autosuggest-textarea__textarea {
font-size: 16px;
}
+ .search__input {
+ line-height: 18px;
+ font-size: 16px;
+ padding: 15px;
+ padding-right: 30px;
+ }
+
+ .search__icon .fa {
+ top: 15px;
+ }
+
@media screen and (min-width: 360px) {
padding: 10px 0;
}
@@ -2038,6 +2055,58 @@ a.account__display-name {
margin-top: 10px;
}
}
+
+ .account {
+ padding: 15px 10px;
+ }
+
+ .notification {
+ &__message {
+ margin-left: 48px + 15px * 2;
+ padding-top: 15px;
+ }
+
+ &__favourite-icon-wrapper {
+ left: -32px;
+ }
+
+ .status {
+ padding-top: 8px;
+ }
+
+ .account {
+ padding-top: 8px;
+ }
+
+ .account__avatar-wrapper {
+ margin-left: 17px;
+ margin-right: 15px;
+ }
+ }
+ }
+}
+
+.floating-action-button {
+ position: fixed;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 3.9375rem;
+ height: 3.9375rem;
+ bottom: 1.3125rem;
+ right: 1.3125rem;
+ background: darken($ui-highlight-color, 3%);
+ color: $white;
+ border-radius: 50%;
+ font-size: 21px;
+ line-height: 21px;
+ text-decoration: none;
+ box-shadow: 2px 3px 9px rgba($base-shadow-color, 0.4);
+
+ &:hover,
+ &:focus,
+ &:active {
+ background: lighten($ui-highlight-color, 7%);
}
}
@@ -2059,12 +2128,41 @@ a.account__display-name {
}
}
+@media screen and (max-width: 600px + (285px * 1) + (10px * 1)) {
+ .columns-area__panels__pane--compositional {
+ display: none;
+ }
+}
+
+@media screen and (min-width: 600px + (285px * 1) + (10px * 1)) {
+ .floating-action-button,
+ .tabs-bar__link.optional {
+ display: none;
+ }
+
+ .search-page .search {
+ display: none;
+ }
+}
+
+@media screen and (max-width: 600px + (285px * 2) + (10px * 2)) {
+ .columns-area__panels__pane--navigational {
+ display: none;
+ }
+}
+
+@media screen and (min-width: 600px + (285px * 2) + (10px * 2)) {
+ .tabs-bar {
+ display: none;
+ }
+}
+
.icon-with-badge {
position: relative;
&__badge {
position: absolute;
- right: -13px;
+ left: 9px;
top: -13px;
background: $ui-highlight-color;
border: 2px solid lighten($ui-base-color, 8%);
@@ -2077,6 +2175,57 @@ a.account__display-name {
}
}
+.column-link--transparent .icon-with-badge__badge {
+ border-color: darken($ui-base-color, 8%);
+}
+
+.compose-panel {
+ width: 285px;
+ margin-top: 10px;
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+
+ .search__input {
+ line-height: 18px;
+ font-size: 16px;
+ padding: 15px;
+ padding-right: 30px;
+ }
+
+ .search__icon .fa {
+ top: 15px;
+ }
+
+ .navigation-bar {
+ padding-top: 20px;
+ padding-bottom: 20px;
+ }
+
+ .flex-spacer {
+ background: transparent;
+ }
+
+ .autosuggest-textarea__textarea {
+ max-height: 200px;
+ }
+
+ .compose-form__upload-thumbnail {
+ height: 80px;
+ }
+}
+
+.navigation-panel {
+ margin-top: 10px;
+
+ hr {
+ border: 0;
+ background: transparent;
+ border-top: 1px solid lighten($ui-base-color, 4%);
+ margin: 10px 0;
+ }
+}
+
.drawer__pager {
box-sizing: border-box;
padding: 0;
@@ -2127,15 +2276,6 @@ a.account__display-name {
}
}
-.navigational-toggle {
- padding: 10px;
- display: flex;
- align-items: center;
- justify-content: space-between;
- font-size: 14px;
- color: $dark-text-color;
-}
-
.pseudo-drawer {
background: lighten($ui-base-color, 13%);
font-size: 13px;
@@ -2365,9 +2505,31 @@ a.account__display-name {
padding: 15px;
text-decoration: none;
- &:hover {
+ &:hover,
+ &:focus,
+ &:active {
background: lighten($ui-base-color, 11%);
}
+
+ &:focus {
+ outline: 0;
+ }
+
+ &--transparent {
+ background: transparent;
+ color: $ui-secondary-color;
+
+ &:hover,
+ &:focus,
+ &:active {
+ background: transparent;
+ color: $primary-text-color;
+ }
+
+ &.active {
+ color: $ui-highlight-color;
+ }
+ }
}
.column-link__icon {
@@ -5436,34 +5598,6 @@ noscript {
}
}
-.floating-action-button {
- position: fixed;
- display: flex;
- justify-content: center;
- align-items: center;
- width: 3.9375rem;
- height: 3.9375rem;
- bottom: 1.3125rem;
- right: 1.3125rem;
- background: darken($ui-highlight-color, 3%);
- color: $white;
- border-radius: 50%;
- font-size: 21px;
- line-height: 21px;
- text-decoration: none;
- box-shadow: 2px 3px 9px rgba($base-shadow-color, 0.4);
-
- &:hover,
- &:focus,
- &:active {
- background: lighten($ui-highlight-color, 7%);
- }
-
- @media screen and (min-width: 630px) {
- display: none;
- }
-}
-
.account__header__content {
color: $darker-text-color;
font-size: 14px;
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index 802ca71fe1..a95d09c5cb 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -36,6 +36,7 @@ class UserSettingsDecorator
user.settings['hide_network'] = hide_network_preference if change?('setting_hide_network')
user.settings['aggregate_reblogs'] = aggregate_reblogs_preference if change?('setting_aggregate_reblogs')
user.settings['show_application'] = show_application_preference if change?('setting_show_application')
+ user.settings['advanced_layout'] = advanced_layout_preference if change?('setting_advanced_layout')
user.settings['default_content_type']= default_content_type_preference if change?('setting_default_content_type')
end
@@ -123,6 +124,10 @@ class UserSettingsDecorator
boolean_cast_setting 'setting_aggregate_reblogs'
end
+ def advanced_layout_preference
+ boolean_cast_setting 'setting_advanced_layout'
+ end
+
def default_content_type_preference
settings['setting_default_content_type']
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 496cb0b1b3..c24741ff1e 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -104,7 +104,8 @@ class User < ApplicationRecord
delegate :auto_play_gif, :default_sensitive, :unfollow_modal, :boost_modal, :favourite_modal, :delete_modal,
:reduce_motion, :system_font_ui, :noindex, :flavour, :skin, :display_media, :hide_network, :hide_followers_count,
- :expand_spoilers, :default_language, :aggregate_reblogs, :show_application, :default_content_type, to: :settings, prefix: :setting, allow_nil: false
+ :expand_spoilers, :default_language, :aggregate_reblogs, :show_application,
+ :advanced_layout, :default_content_type, to: :settings, prefix: :setting, allow_nil: false
attr_reader :invite_code
attr_writer :external
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index d74e56ebc8..efed199f3d 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -46,6 +46,7 @@ class InitialStateSerializer < ActiveModel::Serializer
store[:display_media] = object.current_account.user.setting_display_media
store[:expand_spoilers] = object.current_account.user.setting_expand_spoilers
store[:reduce_motion] = object.current_account.user.setting_reduce_motion
+ store[:advanced_layout] = object.current_account.user.setting_advanced_layout
store[:is_staff] = object.current_account.user.staff?
store[:default_content_type] = object.current_account.user.setting_default_content_type
end
diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml
index cd5bf9be24..45c8b55db0 100644
--- a/app/views/settings/preferences/show.html.haml
+++ b/app/views/settings/preferences/show.html.haml
@@ -46,6 +46,9 @@
%hr#settings_web/
+ .fields-group
+ = f.input :setting_advanced_layout, as: :boolean, wrapper: :with_label
+
.fields-group
= f.input :setting_unfollow_modal, as: :boolean, wrapper: :with_label
= f.input :setting_boost_modal, as: :boolean, wrapper: :with_label
diff --git a/config/locales/simple_form.cs.yml b/config/locales/simple_form.cs.yml
index 2b48884242..fa45fecd55 100644
--- a/config/locales/simple_form.cs.yml
+++ b/config/locales/simple_form.cs.yml
@@ -26,6 +26,7 @@ cs:
password: Použijte alespoň 8 znaků
phrase: Shoda bude nalezena bez ohledu na velikost písmen v těle tootu či varování o obsahu
scopes: Která API bude aplikaci povoleno používat. Pokud vyberete rozsah nejvyššího stupně, nebudete je muset vybírat jednotlivě.
+ setting_advanced_layout: Pokročilé rozhraní se skládá z několika přizpůsobitelných sloupců
setting_aggregate_reblogs: Nezobrazovat nové boosty pro tooty, které byly nedávno boostnuty (ovlivňuje pouze nově přijaté boosty)
setting_default_language: Jazyk vašich tootů může být detekován automaticky, není to však vždy přesné
setting_display_media_default: Skrývat média označená jako citlivá
@@ -90,6 +91,7 @@ cs:
otp_attempt: Dvoufázový kód
password: Heslo
phrase: Klíčové slovo či fráze
+ setting_advanced_layout: Povolit pokročilé webové rozhraní
setting_aggregate_reblogs: Seskupovat boosty v časových osách
setting_auto_play_gif: Automaticky přehrávat animace GIF
setting_boost_modal: Zobrazovat před boostnutím potvrzovací okno
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index 6fad7f73a2..97a5e87858 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -26,6 +26,7 @@ en:
password: Use at least 8 characters
phrase: Will be matched regardless of casing in text or content warning of a toot
scopes: Which APIs the application will be allowed to access. If you select a top-level scope, you don't need to select individual ones.
+ setting_advanced_layout: The advanced UI consists of multiple customizable columns
setting_aggregate_reblogs: Do not show new boosts for toots that have been recently boosted (only affects newly-received boosts)
setting_default_content_type_html: When writing toots, assume they are written in raw HTML, unless specified otherwise
setting_default_content_type_markdown: When writing toots, assume they are using Markdown for rich text formatting, unless specified otherwise
@@ -93,6 +94,7 @@ en:
otp_attempt: Two-factor code
password: Password
phrase: Keyword or phrase
+ setting_advanced_layout: Enable advanced web interface
setting_aggregate_reblogs: Group boosts in timelines
setting_auto_play_gif: Auto-play animated GIFs
setting_boost_modal: Show confirmation dialog before boosting
diff --git a/config/locales/simple_form.sk.yml b/config/locales/simple_form.sk.yml
index 28e8629d23..c6de0009d6 100644
--- a/config/locales/simple_form.sk.yml
+++ b/config/locales/simple_form.sk.yml
@@ -26,6 +26,7 @@ sk:
password: Zadaj aspoň osem znakov
phrase: Zhoda sa nájde nezávisle od toho, či je text napísaný, veľkými, alebo malými písmenami, či už v tele, alebo v hlavičke
scopes: Ktoré API budú povolené aplikácii pre prístup. Ak vyberieš vrcholný stupeň, nemusíš už potom vyberať po jednom.
+ setting_advanced_layout: Pokročilé užívateľské rozhranie sa skladá z viacero prispôsobiteľných stĺpcov
setting_aggregate_reblogs: Nezobrazuj nové vyzdvihnutia pre príspevky, ktoré už boli len nedávno povýšené (týka sa iba nanovo získaných povýšení)
setting_default_language: Jazyk tvojích príspevkov môže byť zistený automaticky, ale nieje to vždy presné
setting_display_media_default: Skry médiá označené ako citlivé
@@ -90,6 +91,7 @@ sk:
otp_attempt: Dvoj-faktorový overovací (2FA) kód
password: Heslo
phrase: Kľúčové slovo, alebo fráza
+ setting_advanced_layout: Zapni pokročilé užívateľské rozhranie
setting_aggregate_reblogs: Zoskupuj vyzdvihnutia v časovej osi
setting_auto_play_gif: Automaticky prehrávaj animované GIFy
setting_boost_modal: Zobrazuj potvrdzovacie okno pred povýšením
@@ -99,7 +101,7 @@ sk:
setting_delete_modal: Zobrazuj potvrdzovacie okno pred vymazaním toot-u
setting_display_media: Zobrazovanie médií
setting_display_media_default: Štandard
- setting_display_media_hide_all: Skryť všetky
+ setting_display_media_hide_all: Skry všetky
setting_display_media_show_all: Ukáž všetky
setting_expand_spoilers: Stále rozbaľ príspevky označené varovaním o obsahu
setting_hide_network: Ukri svoju sieť kontaktov
@@ -112,7 +114,7 @@ sk:
severity: Závažnosť
type: Typ importu
username: Prezývka
- username_or_email: Prezívka, alebo email
+ username_or_email: Prezývka, alebo email
whole_word: Celé slovo
featured_tag:
name: Haštag
diff --git a/config/settings.yml b/config/settings.yml
index 69996af25d..bde43cb3c0 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -35,6 +35,7 @@ defaults: &defaults
flavour: 'glitch'
skin: 'default'
aggregate_reblogs: true
+ advanced_layout: true
notification_emails:
follow: false
reblog: false
diff --git a/lib/mastodon/version.rb b/lib/mastodon/version.rb
index b2eec94e65..c986d711b5 100644
--- a/lib/mastodon/version.rb
+++ b/lib/mastodon/version.rb
@@ -13,7 +13,7 @@ module Mastodon
end
def patch
- 2
+ 4
end
def pre