diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb
index 3e4771dcf..8a78b07a1 100644
--- a/app/controllers/settings/preferences_controller.rb
+++ b/app/controllers/settings/preferences_controller.rb
@@ -85,6 +85,7 @@ class Settings::PreferencesController < Settings::BaseController
:setting_post_reference_modal,
:setting_add_reference_modal,
:setting_unselect_reference_modal,
+ :setting_enable_empty_column,
notification_emails: %i(follow follow_request reblog favourite emoji_reaction status_reference mention digest report pending_account trending_tag),
interactions: %i(must_be_follower must_be_following must_be_following_dm)
)
diff --git a/app/javascript/mastodon/components/column_back_button.js b/app/javascript/mastodon/components/column_back_button.js
index d97622705..603e413c7 100644
--- a/app/javascript/mastodon/components/column_back_button.js
+++ b/app/javascript/mastodon/components/column_back_button.js
@@ -3,6 +3,7 @@ import { FormattedMessage } from 'react-intl';
import PropTypes from 'prop-types';
import Icon from 'mastodon/components/icon';
import { createPortal } from 'react-dom';
+import { enableEmptyColumn } from 'mastodon/initial_state';
export default class ColumnBackButton extends React.PureComponent {
@@ -22,6 +23,10 @@ export default class ColumnBackButton extends React.PureComponent {
}
}
+ handleCloseClick = () => {
+ this.context.router.history.push('/empty');
+ }
+
render () {
const { multiColumn } = this.props;
@@ -32,8 +37,15 @@ export default class ColumnBackButton extends React.PureComponent {
);
+ const backButton = enableEmptyColumn ? (
+
+ ) : component;
+
if (multiColumn) {
- return component;
+ return backButton;
} else {
// The portal container and the component may be rendered to the DOM in
// the same React render pass, so the container might not be available at
diff --git a/app/javascript/mastodon/components/column_back_button_slim.js b/app/javascript/mastodon/components/column_back_button_slim.js
index cc8bfb151..be9ed2e84 100644
--- a/app/javascript/mastodon/components/column_back_button_slim.js
+++ b/app/javascript/mastodon/components/column_back_button_slim.js
@@ -2,16 +2,26 @@ import React from 'react';
import { FormattedMessage } from 'react-intl';
import ColumnBackButton from './column_back_button';
import Icon from 'mastodon/components/icon';
+import { enableEmptyColumn } from 'mastodon/initial_state';
export default class ColumnBackButtonSlim extends ColumnBackButton {
render () {
+ const { multiColumn } = this.props;
+
return (
-
-
-
-
+ { multiColumn && enableEmptyColumn ? (
+
+
+
+
+ ) : (
+
+
+
+
+ )}
);
}
diff --git a/app/javascript/mastodon/components/column_header.js b/app/javascript/mastodon/components/column_header.js
index 236e92296..6fd4f042c 100644
--- a/app/javascript/mastodon/components/column_header.js
+++ b/app/javascript/mastodon/components/column_header.js
@@ -4,6 +4,7 @@ import { createPortal } from 'react-dom';
import classNames from 'classnames';
import { FormattedMessage, injectIntl, defineMessages } from 'react-intl';
import Icon from 'mastodon/components/icon';
+import { enableEmptyColumn } from 'mastodon/initial_state';
const messages = defineMessages({
show: { id: 'column_header.show_settings', defaultMessage: 'Show settings' },
@@ -71,6 +72,10 @@ class ColumnHeader extends React.PureComponent {
this.historyBack();
}
+ handleCloseClick = () => {
+ this.context.router.history.push('/empty');
+ }
+
handleTransitionEnd = () => {
this.setState({ animating: false });
}
@@ -128,7 +133,12 @@ class ColumnHeader extends React.PureComponent {
}
if (!pinned && (multiColumn || showBackButton)) {
- backButton = (
+ backButton = multiColumn && enableEmptyColumn ? (
+
+ ) : (
+ {enableEmptyColumn &&
}
}
diff --git a/app/javascript/mastodon/features/reactioned/components/header.js b/app/javascript/mastodon/features/reactioned/components/header.js
index 5fc2b828a..6efa1497e 100644
--- a/app/javascript/mastodon/features/reactioned/components/header.js
+++ b/app/javascript/mastodon/features/reactioned/components/header.js
@@ -21,6 +21,10 @@ export default class Header extends ImmutablePureComponent {
this.context.router.history.push(`/statuses/${this.props.status.get('id')}`);
};
+ handleStatusCloseClick = () => {
+ this.context.router.history.push('/empty');
+ }
+
render () {
const { status, hideTabs } = this.props;
diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js
index b0e89d1a1..0683fc660 100644
--- a/app/javascript/mastodon/features/ui/index.js
+++ b/app/javascript/mastodon/features/ui/index.js
@@ -65,8 +65,9 @@ import {
FollowRecommendations,
Trends,
Suggestions,
+ EmptyColumn,
} from './util/async-components';
-import { me } from '../../initial_state';
+import { me, enableEmptyColumn } from '../../initial_state';
import { closeOnboarding, INTRODUCTION_VERSION } from 'mastodon/actions/onboarding';
// Dummy import, to make sure that ends up in the application bundle.
@@ -158,7 +159,7 @@ class SwitchingColumnsArea extends React.PureComponent {
render () {
const { children, mobile } = this.props;
- const redirect = mobile ? : ;
+ const redirect = mobile ? : enableEmptyColumn ? : ;
return (
@@ -211,6 +212,8 @@ class SwitchingColumnsArea extends React.PureComponent {
+
+
diff --git a/app/javascript/mastodon/features/ui/util/async-components.js b/app/javascript/mastodon/features/ui/util/async-components.js
index 3a1d3bf97..6b5549b9e 100644
--- a/app/javascript/mastodon/features/ui/util/async-components.js
+++ b/app/javascript/mastodon/features/ui/util/async-components.js
@@ -217,3 +217,7 @@ export function Trends () {
export function Suggestions () {
return import(/* webpackChunkName: "features/suggestions" */'../../suggestions');
}
+
+export function EmptyColumn () {
+ return import(/* webpackChunkName: "features/empty" */'../../empty');
+}
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js
index bce09126a..a2a720eed 100644
--- a/app/javascript/mastodon/initial_state.js
+++ b/app/javascript/mastodon/initial_state.js
@@ -49,5 +49,6 @@ export const new_features_policy = getMeta('new_features_policy');
export const enableStatusReference = getMeta('enable_status_reference');
export const maxReferences = initialState?.status_references?.max_references;
export const matchVisibilityOfReferences = getMeta('match_visibility_of_references');
+export const enableEmptyColumn = getMeta('enable_empty_column');
export default initialState;
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 7689e3c80..e2e3f4e10 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -108,6 +108,7 @@
"column.public": "Federated timeline",
"column_back_button.label": "Back",
"column_back_button_to_pots.label": "Back to post detail",
+ "column_close_button.label": "Close",
"column_header.hide_settings": "Hide settings",
"column_header.moveLeft_settings": "Move column to the left",
"column_header.moveRight_settings": "Move column to the right",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index 0c0901149..8bf77586a 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -108,6 +108,7 @@
"column.public": "連合タイムライン",
"column_back_button.label": "戻る",
"column_back_button_to_pots.label": "投稿の詳細に戻る",
+ "column_close_button.label": "閉じる",
"column_header.hide_settings": "設定を隠す",
"column_header.moveLeft_settings": "カラムを左に移動する",
"column_header.moveRight_settings": "カラムを右に移動する",
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index eda5470a2..8c067c242 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -79,6 +79,7 @@ class UserSettingsDecorator
user.settings['enable_status_reference'] = enable_status_reference_preference if change?('setting_enable_status_reference')
user.settings['match_visibility_of_references'] = match_visibility_of_references_preference if change?('setting_match_visibility_of_references')
user.settings['hexagon_avatar'] = hexagon_avatar_preference if change?('setting_hexagon_avatar')
+ user.settings['enable_empty_column'] = enable_empty_column_preference if change?('setting_enable_empty_column')
end
def merged_notification_emails
@@ -281,6 +282,10 @@ end
boolean_cast_setting 'setting_match_visibility_of_references'
end
+ def enable_empty_column_preference
+ boolean_cast_setting 'setting_enable_empty_column'
+ end
+
def boolean_cast_setting(key)
ActiveModel::Type::Boolean.new.cast(settings[key])
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 9010bde77..e9c2523f8 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -136,7 +136,7 @@ class User < ApplicationRecord
:theme_instance_ticker,
:enable_status_reference, :match_visibility_of_references,
:post_reference_modal, :add_reference_modal, :unselect_reference_modal,
- :hexagon_avatar,
+ :hexagon_avatar, :enable_empty_column,
to: :settings, prefix: :setting, allow_nil: false
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index 4f0c132e0..2bae08577 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -63,6 +63,7 @@ class InitialStateSerializer < ActiveModel::Serializer
store[:post_reference_modal] = object.current_account.user.setting_post_reference_modal
store[:add_reference_modal] = object.current_account.user.setting_add_reference_modal
store[:unselect_reference_modal] = object.current_account.user.setting_unselect_reference_modal
+ store[:enable_empty_column] = object.current_account.user.setting_enable_empty_column
else
store[:auto_play_gif] = Setting.auto_play_gif
diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml
index 17acecb9b..1d6c3a7db 100644
--- a/app/views/settings/preferences/appearance/show.html.haml
+++ b/app/views/settings/preferences/appearance/show.html.haml
@@ -31,6 +31,9 @@
.fields-group
= f.input :setting_advanced_layout, as: :boolean, wrapper: :with_label, hint: false
+ .fields-group
+ = f.input :setting_enable_empty_column, as: :boolean, wrapper: :with_label, fedibird_features: true
+
%h4= t 'appearance.animations_and_accessibility'
.fields-group
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index 872199de5..bbfb34f3c 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -59,6 +59,7 @@ en:
setting_display_media_default: Hide media marked as sensitive
setting_display_media_hide_all: Always hide media
setting_display_media_show_all: Always show media
+ setting_enable_empty_column: The last column is initially hidden and can be closed at will
setting_enable_limited_timeline: Enable a limited home to display private and circle and direct message
setting_enable_reaction: Enable the reaction display on the timeline and display the reaction button
setting_enable_status_reference: Enable the feature where a post references another post
@@ -216,6 +217,7 @@ en:
setting_display_media_default: Default
setting_display_media_hide_all: Hide all
setting_display_media_show_all: Show all
+ setting_enable_empty_column: Enable last column to be closed
setting_enable_limited_timeline: Enable limited timeline
setting_enable_reaction: Enable reaction
setting_enable_status_reference: Enable reference
diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml
index 25e6f9840..c6220d48c 100644
--- a/config/locales/simple_form.ja.yml
+++ b/config/locales/simple_form.ja.yml
@@ -59,6 +59,7 @@ ja:
setting_display_media_default: 閲覧注意としてマークされたメディアは隠す
setting_display_media_hide_all: メディアを常に隠す
setting_display_media_show_all: メディアを常に表示する
+ setting_enable_empty_column: 最後のカラムを初期状態で非表示にし、任意に閉じられるようにします
setting_enable_limited_timeline: フォロワー限定・サークル・ダイレクトメッセージを表示する限定ホームを有効にします
setting_enable_reaction: タイムラインでリアクションの表示を有効にし、リアクションボタンを表示する
setting_enable_status_reference: 投稿が別の投稿を参照する機能を有効にします
@@ -216,6 +217,7 @@ ja:
setting_display_media_default: 標準
setting_display_media_hide_all: 非表示
setting_display_media_show_all: 表示
+ setting_enable_empty_column: 最終カラムを閉じられるようにする
setting_enable_limited_timeline: 限定ホームを有効にする
setting_enable_reaction: リアクションを有効にする
setting_enable_status_reference: 参照を有効にする
diff --git a/config/settings.yml b/config/settings.yml
index 18888f656..3bd234c7c 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -97,6 +97,7 @@ defaults: &defaults
add_reference_modal: true
unselect_reference_modal: false
hexagon_avatar: false
+ enable_empty_column: false
development:
<<: *defaults