)}
diff --git a/app/javascript/mastodon/features/referred_by_statuses/index.js b/app/javascript/mastodon/features/referred_by_statuses/index.js
index c587ef953..dea550430 100644
--- a/app/javascript/mastodon/features/referred_by_statuses/index.js
+++ b/app/javascript/mastodon/features/referred_by_statuses/index.js
@@ -12,17 +12,28 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
import ReactedHeaderContaier from '../reactioned/containers/header_container';
import { debounce } from 'lodash';
+import { defaultColumnWidth } from 'mastodon/initial_state';
+import { changeSetting } from '../../actions/settings';
+import { changeColumnParams } from '../../actions/columns';
const messages = defineMessages({
refresh: { id: 'refresh', defaultMessage: 'Refresh' },
heading: { id: 'column.referred_by_statuses', defaultMessage: 'Referred by posts' },
});
-const mapStateToProps = (state, props) => ({
- statusIds: state.getIn(['status_status_lists', 'referred_by', props.params.statusId, 'items']),
- isLoading: state.getIn(['status_status_lists', 'referred_by', props.params.statusId, 'isLoading'], true),
- hasMore: !!state.getIn(['status_status_lists', 'referred_by', props.params.statusId, 'next']),
-});
+const mapStateToProps = (state, { columnId, params }) => {
+ const uuid = columnId;
+ const columns = state.getIn(['settings', 'columns']);
+ const index = columns.findIndex(c => c.get('uuid') === uuid);
+ const columnWidth = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'columnWidth']) : state.getIn(['settings', 'referred_by_statuses', 'columnWidth']);
+
+ return {
+ statusIds: state.getIn(['status_status_lists', 'referred_by', params.statusId, 'items']),
+ isLoading: state.getIn(['status_status_lists', 'referred_by', params.statusId, 'isLoading'], true),
+ hasMore: !!state.getIn(['status_status_lists', 'referred_by', params.statusId, 'next']),
+ columnWidth: columnWidth ?? defaultColumnWidth,
+ };
+};
export default @connect(mapStateToProps)
@injectIntl
@@ -33,6 +44,7 @@ class ReferredByStatuses extends ImmutablePureComponent {
statusIds: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
multiColumn: PropTypes.bool,
+ columnWidth: PropTypes.string,
hasMore: PropTypes.bool,
isLoading: PropTypes.bool,
};
@@ -57,8 +69,18 @@ class ReferredByStatuses extends ImmutablePureComponent {
this.props.dispatch(expandReferredByStatuses(this.props.params.statusId));
}, 300, { leading: true })
+ handleWidthChange = (value) => {
+ const { columnId, dispatch } = this.props;
+
+ if (columnId) {
+ dispatch(changeColumnParams(columnId, 'columnWidth', value));
+ } else {
+ dispatch(changeSetting(['referred_by_statuses', 'columnWidth'], value));
+ }
+ }
+
render () {
- const { intl, statusIds, multiColumn, hasMore, isLoading } = this.props;
+ const { intl, statusIds, multiColumn, hasMore, isLoading, columnWidth } = this.props;
if (!statusIds) {
return (
@@ -71,10 +93,12 @@ class ReferredByStatuses extends ImmutablePureComponent {
const emptyMessage = ;
return (
-
+
)}
diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js
index 3bee1d945..70046c62d 100644
--- a/app/javascript/mastodon/features/status/index.js
+++ b/app/javascript/mastodon/features/status/index.js
@@ -65,6 +65,9 @@ import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from
import { textForScreenReader, defaultMediaVisibility } from '../../components/status';
import Icon from 'mastodon/components/icon';
import DetailedHeaderContaier from './containers/header_container';
+import { defaultColumnWidth } from 'mastodon/initial_state';
+import { changeSetting } from '../../actions/settings';
+import { changeColumnParams } from '../../actions/columns';
const messages = defineMessages({
deleteConfirm: { id: 'confirmations.delete.confirm', defaultMessage: 'Delete' },
@@ -148,8 +151,12 @@ const makeMapStateToProps = () => {
return ImmutableList(contextReference.get(statusId));
});
- const mapStateToProps = (state, props) => {
- const status = getStatus(state, { id: props.params.statusId });
+ const mapStateToProps = (state, { columnId, params }) => {
+ const uuid = columnId;
+ const columns = state.getIn(['settings', 'columns']);
+ const index = columns.findIndex(c => c.get('uuid') === uuid);
+ const columnWidth = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'columnWidth']) : state.getIn(['settings', 'status', 'columnWidth']);
+ const status = getStatus(state, { id: params.statusId });
const ancestorsIds = status ? getAncestorsIds(state, { id: status.get('in_reply_to_id') }) : ImmutableList();
const descendantsIds = status ? getDescendantsIds(state, { id: status.get('id') }) : ImmutableList();
const referencesIds = status ? getReferencesIds(state, { id: status.get('id') }) : ImmutableList();
@@ -161,10 +168,11 @@ const makeMapStateToProps = () => {
descendantsIds,
askReplyConfirmation: state.getIn(['compose', 'text']).trim().length !== 0,
domain: state.getIn(['meta', 'domain']),
- pictureInPicture: getPictureInPicture(state, { id: props.params.statusId }),
+ pictureInPicture: getPictureInPicture(state, { id: params.statusId }),
emojiMap: customEmojiMap(state),
referenced: state.getIn(['compose', 'references']).has(id),
contextReferenced: state.getIn(['compose', 'context_references']).has(id),
+ columnWidth: columnWidth ?? defaultColumnWidth,
};
};
@@ -190,6 +198,7 @@ class Status extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
askReplyConfirmation: PropTypes.bool,
multiColumn: PropTypes.bool,
+ columnWidth: PropTypes.string,
domain: PropTypes.string.isRequired,
pictureInPicture: ImmutablePropTypes.contains({
inUse: PropTypes.bool,
@@ -561,9 +570,19 @@ class Status extends ImmutablePureComponent {
this.setState({ fullscreen: isFullscreen() });
}
+ handleWidthChange = (value) => {
+ const { columnId, dispatch } = this.props;
+
+ if (columnId) {
+ dispatch(changeColumnParams(columnId, 'columnWidth', value));
+ } else {
+ dispatch(changeSetting(['status', 'columnWidth'], value));
+ }
+ }
+
render () {
let ancestors, descendants;
- const { status, ancestorsIds, descendantsIds, intl, domain, multiColumn, pictureInPicture, emojiMap, referenced, contextReferenced } = this.props;
+ const { status, ancestorsIds, descendantsIds, intl, domain, multiColumn, pictureInPicture, emojiMap, referenced, contextReferenced, columnWidth } = this.props;
const { fullscreen } = this.state;
if (status === null) {
@@ -599,10 +618,12 @@ class Status extends ImmutablePureComponent {
};
return (
-
+
)}
diff --git a/app/javascript/mastodon/features/status_references/index.js b/app/javascript/mastodon/features/status_references/index.js
index 75264222e..7c0835fc5 100644
--- a/app/javascript/mastodon/features/status_references/index.js
+++ b/app/javascript/mastodon/features/status_references/index.js
@@ -22,6 +22,9 @@ import ImmutablePureComponent from 'react-immutable-pure-component';
import { attachFullscreenListener, detachFullscreenListener, isFullscreen } from '../ui/util/fullscreen';
import Icon from 'mastodon/components/icon';
import DetailedHeaderContaier from '../status/containers/header_container';
+import { defaultColumnWidth } from 'mastodon/initial_state';
+import { changeSetting } from '../../actions/settings';
+import { changeColumnParams } from '../../actions/columns';
const messages = defineMessages({
revealAll: { id: 'status.show_more_all', defaultMessage: 'Show more for all' },
@@ -39,13 +42,18 @@ const makeMapStateToProps = () => {
return ImmutableList(contextReference.get(statusId));
});
- const mapStateToProps = (state, props) => {
- const status = getStatus(state, { id: props.params.statusId });
+ const mapStateToProps = (state, { columnId, params }) => {
+ const uuid = columnId;
+ const columns = state.getIn(['settings', 'columns']);
+ const index = columns.findIndex(c => c.get('uuid') === uuid);
+ const columnWidth = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'columnWidth']) : state.getIn(['settings', 'status_references', 'columnWidth']);
+ const status = getStatus(state, { id: params.statusId });
const referencesIds = status ? getReferencesIds(state, { id: status.get('id') }) : ImmutableList();
return {
status,
referencesIds,
+ columnWidth: columnWidth ?? defaultColumnWidth,
};
};
@@ -67,6 +75,7 @@ class StatusReferences extends ImmutablePureComponent {
referencesIds: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
multiColumn: PropTypes.bool,
+ columnWidth: PropTypes.string,
};
state = {
@@ -154,8 +163,18 @@ class StatusReferences extends ImmutablePureComponent {
this.setState({ fullscreen: isFullscreen() });
}
+ handleWidthChange = (value) => {
+ const { columnId, dispatch } = this.props;
+
+ if (columnId) {
+ dispatch(changeColumnParams(columnId, 'columnWidth', value));
+ } else {
+ dispatch(changeSetting(['status_references', 'columnWidth'], value));
+ }
+ }
+
render () {
- const { status, referencesIds, intl, multiColumn } = this.props;
+ const { status, referencesIds, intl, multiColumn, columnWidth } = this.props;
const { fullscreen } = this.state;
if (status === null) {
@@ -173,10 +192,12 @@ class StatusReferences extends ImmutablePureComponent {
}
return (
-
+
)}
diff --git a/app/javascript/mastodon/features/subscribing/index.js b/app/javascript/mastodon/features/subscribing/index.js
index 5f7e418ed..ac32c6855 100644
--- a/app/javascript/mastodon/features/subscribing/index.js
+++ b/app/javascript/mastodon/features/subscribing/index.js
@@ -18,7 +18,8 @@ import ColumnSettingsContainer from '../account_timeline/containers/column_setti
import HeaderContainer from '../account_timeline/containers/header_container';
import ScrollableList from '../../components/scrollable_list';
import MissingIndicator from 'mastodon/components/missing_indicator';
-import { new_features_policy } from 'mastodon/initial_state';
+import { new_features_policy, defaultColumnWidth } from 'mastodon/initial_state';
+import { changeSetting } from '../../actions/settings';
const messages = defineMessages({
title: { id: 'column.account', defaultMessage: 'Account' },
@@ -31,6 +32,7 @@ const mapStateToProps = (state, props) => ({
isLoading: state.getIn(['user_lists', 'subscribing', props.params.accountId, 'isLoading'], true),
blockedBy: state.getIn(['relationships', props.params.accountId, 'blocked_by'], false),
advancedMode: state.getIn(['settings', 'account', 'other', 'advancedMode'], new_features_policy === 'conservative' ? false : true),
+ columnWidth: state.getIn(['settings', 'account', 'columnWidth'], defaultColumnWidth),
});
export default @connect(mapStateToProps)
@@ -46,6 +48,7 @@ class Subscribing extends ImmutablePureComponent {
blockedBy: PropTypes.bool,
isAccount: PropTypes.bool,
multiColumn: PropTypes.bool,
+ columnWidth: PropTypes.string,
};
componentWillMount () {
@@ -70,12 +73,16 @@ class Subscribing extends ImmutablePureComponent {
this.column.scrollTop();
}
+ handleWidthChange = (value) => {
+ this.props.dispatch(changeSetting(['account', 'columnWidth'], value));
+ }
+
setRef = c => {
this.column = c;
}
render () {
- const { accountIds, hasMore, blockedBy, isAccount, multiColumn, isLoading, intl } = this.props;
+ const { accountIds, hasMore, blockedBy, isAccount, multiColumn, isLoading, columnWidth, intl } = this.props;
if (!isAccount) {
return (
@@ -96,7 +103,7 @@ class Subscribing extends ImmutablePureComponent {
const emptyMessage = blockedBy ? : ;
return (
-
+
diff --git a/app/javascript/mastodon/features/suggestions/index.js b/app/javascript/mastodon/features/suggestions/index.js
index f19d5dccf..6131c60b0 100644
--- a/app/javascript/mastodon/features/suggestions/index.js
+++ b/app/javascript/mastodon/features/suggestions/index.js
@@ -11,6 +11,9 @@ import ScrollableList from 'mastodon/components/scrollable_list';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import AccountContainer from 'mastodon/containers/account_container';
import ImmutablePureComponent from 'react-immutable-pure-component';
+import { defaultColumnWidth } from 'mastodon/initial_state';
+import { changeSetting } from '../../actions/settings';
+import { changeColumnParams } from '../../actions/columns';
const messages = defineMessages({
heading: { id: 'suggestions.heading', defaultMessage: 'Suggestions' },
@@ -18,10 +21,18 @@ const messages = defineMessages({
dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
});
-const mapStateToProps = state => ({
- suggestions: state.getIn(['suggestions', 'items']),
- isLoading: state.getIn(['suggestions', 'isLoading'], true),
-});
+const mapStateToProps = (state, { columnId }) => {
+ const uuid = columnId;
+ const columns = state.getIn(['settings', 'columns']);
+ const index = columns.findIndex(c => c.get('uuid') === uuid);
+ const columnWidth = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'columnWidth']) : state.getIn(['settings', 'suggestions', 'columnWidth']);
+
+ return {
+ suggestions: state.getIn(['suggestions', 'items']),
+ isLoading: state.getIn(['suggestions', 'isLoading'], true),
+ columnWidth: columnWidth ?? defaultColumnWidth,
+ };
+};
export default @connect(mapStateToProps)
@injectIntl
@@ -33,6 +44,7 @@ class Suggestions extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
columnId: PropTypes.string,
multiColumn: PropTypes.bool,
+ columnWidth: PropTypes.string,
isLoading: PropTypes.bool,
};
@@ -75,14 +87,24 @@ class Suggestions extends ImmutablePureComponent {
this.column = c;
}
+ handleWidthChange = (value) => {
+ const { columnId, dispatch } = this.props;
+
+ if (columnId) {
+ dispatch(changeColumnParams(columnId, 'columnWidth', value));
+ } else {
+ dispatch(changeSetting(['suggestions', 'columnWidth'], value));
+ }
+ }
+
render () {
- const { intl, suggestions, columnId, multiColumn, isLoading } = this.props;
+ const { intl, suggestions, columnId, multiColumn, isLoading, columnWidth } = this.props;
const pinned = !!columnId;
const emptyMessage = ;
return (
-
+
diff --git a/app/javascript/mastodon/features/trends/index.js b/app/javascript/mastodon/features/trends/index.js
index 7af077282..f6ddd6a3d 100644
--- a/app/javascript/mastodon/features/trends/index.js
+++ b/app/javascript/mastodon/features/trends/index.js
@@ -12,6 +12,9 @@ import ScrollableList from 'mastodon/components/scrollable_list';
import Hashtag from 'mastodon/components/hashtag';
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
import ImmutablePureComponent from 'react-immutable-pure-component';
+import { defaultColumnWidth } from 'mastodon/initial_state';
+import { changeSetting } from '../../actions/settings';
+import { changeColumnParams } from '../../actions/columns';
const messages = defineMessages({
heading: { id: 'trends.heading', defaultMessage: 'Trends' },
@@ -19,10 +22,18 @@ const messages = defineMessages({
refresh: { id: 'refresh', defaultMessage: 'Refresh' },
});
-const mapStateToProps = state => ({
- trends: state.getIn(['trends', 'items']),
- isLoading: state.getIn(['trends', 'isLoading'], true),
-});
+const mapStateToProps = (state, { columnId }) => {
+ const uuid = columnId;
+ const columns = state.getIn(['settings', 'columns']);
+ const index = columns.findIndex(c => c.get('uuid') === uuid);
+ const columnWidth = (columnId && index >= 0) ? columns.get(index).getIn(['params', 'columnWidth']) : state.getIn(['settings', 'trends', 'columnWidth']);
+
+ return {
+ trends: state.getIn(['trends', 'items']),
+ isLoading: state.getIn(['trends', 'isLoading'], true),
+ columnWidth: columnWidth ?? defaultColumnWidth,
+ };
+};
export default @connect(mapStateToProps)
@injectIntl
@@ -34,6 +45,7 @@ class Trends extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
columnId: PropTypes.string,
multiColumn: PropTypes.bool,
+ columnWidth: PropTypes.string,
isLoading: PropTypes.bool,
};
@@ -81,14 +93,24 @@ class Trends extends ImmutablePureComponent {
this.column = c;
}
+ handleWidthChange = (value) => {
+ const { columnId, dispatch } = this.props;
+
+ if (columnId) {
+ dispatch(changeColumnParams(columnId, 'columnWidth', value));
+ } else {
+ dispatch(changeSetting(['trends', 'columnWidth'], value));
+ }
+ }
+
render () {
- const { intl, trends, columnId, multiColumn, isLoading } = this.props;
+ const { intl, trends, columnId, multiColumn, isLoading, columnWidth } = this.props;
const pinned = !!columnId;
const emptyMessage = ;
return (
-
+
diff --git a/app/javascript/mastodon/features/ui/components/column.js b/app/javascript/mastodon/features/ui/components/column.js
index 15538ea38..187101136 100644
--- a/app/javascript/mastodon/features/ui/components/column.js
+++ b/app/javascript/mastodon/features/ui/components/column.js
@@ -4,6 +4,7 @@ import PropTypes from 'prop-types';
import { debounce } from 'lodash';
import { scrollTop } from '../../../scroll';
import { isMobile } from '../../../is_mobile';
+import classNames from 'classnames';
export default class Column extends React.PureComponent {
@@ -13,6 +14,7 @@ export default class Column extends React.PureComponent {
children: PropTypes.node,
active: PropTypes.bool,
hideHeadingOnMobile: PropTypes.bool,
+ columnWidth: PropTypes.string,
};
handleHeaderClick = () => {
@@ -47,7 +49,7 @@ export default class Column extends React.PureComponent {
}
render () {
- const { heading, icon, children, active, hideHeadingOnMobile } = this.props;
+ const { heading, icon, children, active, hideHeadingOnMobile, columnWidth } = this.props;
const showHeading = heading && (!hideHeadingOnMobile || (hideHeadingOnMobile && !isMobile(window.innerWidth)));
@@ -60,7 +62,7 @@ export default class Column extends React.PureComponent {
ref={this.setRef}
role='region'
aria-labelledby={columnHeaderId}
- className='column'
+ className={classNames('column', columnWidth)}
onScroll={this.handleScroll}
>
{header}
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js
index f7079d5b3..d24bfaf54 100644
--- a/app/javascript/mastodon/initial_state.js
+++ b/app/javascript/mastodon/initial_state.js
@@ -52,5 +52,6 @@ export const maxReferences = initialState?.status_references?.max_references;
export const matchVisibilityOfReferences = getMeta('match_visibility_of_references');
export const enableEmptyColumn = getMeta('enable_empty_column');
export const showReloadButton = getMeta('show_reload_button');
+export const defaultColumnWidth = getMeta('default_column_width');
export default initialState;
diff --git a/app/javascript/mastodon/locales/en.json b/app/javascript/mastodon/locales/en.json
index 8dc233d00..dcef07bb4 100644
--- a/app/javascript/mastodon/locales/en.json
+++ b/app/javascript/mastodon/locales/en.json
@@ -140,6 +140,11 @@
"column_subheading.favourite_lists": "Favourite lists",
"column_subheading.favourite_tags": "Favourite tags",
"column_subheading.settings": "Settings",
+ "column_width.free": "Free",
+ "column_width.x080": "80%",
+ "column_width.x100": "100%",
+ "column_width.x125": "125%",
+ "column_width.x150": "150%",
"community.column_settings.local_only": "Local only",
"community.column_settings.media_only": "Media only",
"community.column_settings.remote_only": "Remote only",
diff --git a/app/javascript/mastodon/locales/ja.json b/app/javascript/mastodon/locales/ja.json
index d4a453d06..c5f4af3bc 100644
--- a/app/javascript/mastodon/locales/ja.json
+++ b/app/javascript/mastodon/locales/ja.json
@@ -140,6 +140,11 @@
"column_subheading.favourite_lists": "お気に入りリスト",
"column_subheading.favourite_tags": "お気に入りハッシュタグ",
"column_subheading.settings": "設定",
+ "column_width.free": "フリー",
+ "column_width.x080": "80%",
+ "column_width.x100": "100%",
+ "column_width.x125": "125%",
+ "column_width.x150": "150%",
"community.column_settings.local_only": "ローカルのみ表示",
"community.column_settings.media_only": "メディアのみ表示",
"community.column_settings.remote_only": "リモートのみ表示",
diff --git a/app/javascript/styles/mastodon/components.scss b/app/javascript/styles/mastodon/components.scss
index a0c19f7d0..326f0dcda 100644
--- a/app/javascript/styles/mastodon/components.scss
+++ b/app/javascript/styles/mastodon/components.scss
@@ -2346,6 +2346,57 @@ a.account__display-name {
> .scrollable {
background: $ui-base-color;
}
+
+ .layout-multiple-columns &.free {
+ flex: 1 1 auto;
+ min-width: 350px;
+ }
+
+ .layout-multiple-columns &.x080 {
+ width: 350px * 0.8;
+
+ .status__action-bar {
+ zoom: 0.8;
+ }
+ }
+
+ .layout-multiple-columns &.x125 {
+ width: 350px * 1.25;
+ }
+
+ .layout-multiple-columns &.x150 {
+ width: 350px * 1.5;
+ }
+
+ .layout-multiple-columns &.x200 {
+ width: 350px * 2;
+ }
+}
+
+.column-width {
+ display: flex;
+ justify-content: flex-end;
+ padding-bottom: 8px;
+ margin-bottom: 10px;
+
+ &__item {
+ flex: 0 0 auto;
+ min-width: 36px;
+ padding: 4px;
+ margin: 0 2px;
+ border-radius: 4px;
+ text-align: center;
+ background-color: $ui-base-color;
+ }
+
+ &__item.active {
+ color: $primary-text-color;
+ background-color: $ui-highlight-color;
+ }
+
+ input[type=radio] {
+ display: none;
+ }
}
.ui {
diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb
index 243ec1577..4eda7a581 100644
--- a/app/lib/user_settings_decorator.rb
+++ b/app/lib/user_settings_decorator.rb
@@ -89,6 +89,7 @@ class UserSettingsDecorator
user.settings['confirm_follow_from_bot'] = confirm_follow_from_bot_preference if change?('setting_confirm_follow_from_bot')
user.settings['default_search_searchability'] = default_search_searchability_preference if change?('setting_default_search_searchability')
user.settings['show_reload_button'] = show_reload_button_preference if change?('setting_show_reload_button')
+ user.settings['default_column_width'] = default_column_width_preference if change?('setting_default_column_width')
end
def merged_notification_emails
@@ -331,6 +332,10 @@ end
boolean_cast_setting 'setting_show_reload_button'
end
+ def default_column_width_preference
+ settings['setting_default_column_width']
+ 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 9a0e3de7a..f2efad61f 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -142,7 +142,7 @@ class User < ApplicationRecord
:mobile_customize, :mobile_content_font_size, :mobile_info_font_size, :mobile_content_emoji_reaction_size,
:hide_bot_on_public_timeline, :confirm_follow_from_bot,
:default_search_searchability,
- :show_reload_button,
+ :show_reload_button, :default_column_width,
to: :settings, prefix: :setting, allow_nil: false
diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb
index da52345b0..e7f17e946 100644
--- a/app/serializers/initial_state_serializer.rb
+++ b/app/serializers/initial_state_serializer.rb
@@ -72,6 +72,7 @@ class InitialStateSerializer < ActiveModel::Serializer
store[:hide_bot_on_public_timeline] = object.current_account.user.setting_hide_bot_on_public_timeline
store[:confirm_follow_from_bot] = object.current_account.user.setting_confirm_follow_from_bot
store[:show_reload_button] = object.current_account.user.setting_show_reload_button
+ store[:default_column_width] = object.current_account.user.setting_default_column_width
else
store[:auto_play_gif] = Setting.auto_play_gif
store[:display_media] = Setting.display_media
diff --git a/app/views/settings/preferences/appearance/show.html.haml b/app/views/settings/preferences/appearance/show.html.haml
index 3406bb938..42aae6abc 100644
--- a/app/views/settings/preferences/appearance/show.html.haml
+++ b/app/views/settings/preferences/appearance/show.html.haml
@@ -62,6 +62,9 @@
.fields-group
= f.input :setting_enable_empty_column, as: :boolean, wrapper: :with_label, fedibird_features: true
+ .fields-group
+ = f.input :setting_default_column_width, collection: ['x080', 'x100', 'x125', 'x150', 'free'], label_method: lambda { |item| t("simple_form.hints.defaults.setting_default_column_width_#{item}") }, wrapper: :with_label, include_blank: false, 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 32ad9c90b..3402fbc66 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -57,6 +57,11 @@ en:
setting_aggregate_reblogs: Do not show new boosts for posts that have been recently boosted (only affects newly-received boosts)
setting_compact_reaction: Emoji reaction display to be only the number of cases, except for the detail display
setting_confirm_follow_from_bot: Manually approve followers from bot accounts
+ setting_default_column_width_free: Free - Column width changes according to screen
+ setting_default_column_width_x080: 80% - Fix to 80% of standard width
+ setting_default_column_width_x100: 100% - Fix to Mastodon standard column width
+ setting_default_column_width_x125: 125% - Fix to 125% of standard width
+ setting_default_column_width_x150: 150% - Fix to 150% of standard width
setting_default_search_searchability: For clients that do not support advanced range settings, switch the settings here. Mastodon's standard behavior is "Reacted-users-only". Targeting "Public" makes it easier to discover unknown information, but if the results are noisy, narrowing the search range is effective.
setting_default_sensitive: Sensitive media is hidden by default and can be revealed with a click
setting_disable_joke_appearance: Disable April Fools' Day and other joke functions
@@ -219,6 +224,7 @@ en:
setting_content_emoji_reaction_size: Emoji reaction size
setting_content_font_size: Content font size
setting_crop_images: Crop images in non-expanded posts to 16x9
+ setting_default_column_width: Default column width
setting_default_language: Posting language
setting_default_privacy: Posting privacy
setting_default_search_searchability: Search range
diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml
index ac5e44f6c..ede5d861d 100644
--- a/config/locales/simple_form.ja.yml
+++ b/config/locales/simple_form.ja.yml
@@ -57,6 +57,11 @@ ja:
setting_aggregate_reblogs: 最近ブーストされた投稿が新たにブーストされても表示しません (設定後受信したものにのみ影響)
setting_compact_reaction: 詳細表示以外の絵文字リアクション表示を件数のみにする
setting_confirm_follow_from_bot: Botアカウントからのフォローを手動で承認する
+ setting_default_column_width_free: フリー - 画面に応じてカラム幅が変わります
+ setting_default_column_width_x080: 80% - 標準の80%の幅に固定します
+ setting_default_column_width_x100: 100% - Mastodon標準のカラム幅に固定します
+ setting_default_column_width_x125: 125% - 標準の125%の幅に固定します
+ setting_default_column_width_x150: 150% - 標準の150%の幅に固定します
setting_default_search_searchability: 範囲の詳細設定に対応していないクライアントでは、ここで設定を切り替えてください。Mastodonの標準動作は『リアクション限定』です。『公開』を対象にすると未知の情報を発見しやすくなりますが、結果にノイズが多い場合は検索範囲を狭めると効果的です。
setting_default_sensitive: 閲覧注意状態のメディアはデフォルトでは内容が伏せられ、クリックして初めて閲覧できるようになります
setting_disable_joke_appearance: エイプリルフール等のジョーク機能を無効にします
@@ -219,6 +224,7 @@ ja:
setting_content_emoji_reaction_size: 投稿の絵文字リアクションのサイズ
setting_content_font_size: 投稿のフォントサイズ
setting_crop_images: 投稿の詳細以外では画像を16:9に切り抜く
+ setting_default_column_width: デフォルトのカラム幅
setting_default_language: 投稿する言語
setting_default_privacy: 投稿の公開範囲
setting_default_search_searchability: 検索の対象とする範囲
diff --git a/config/settings.yml b/config/settings.yml
index 521a214ea..4596601a6 100644
--- a/config/settings.yml
+++ b/config/settings.yml
@@ -110,6 +110,7 @@ defaults: &defaults
confirm_follow_from_bot: true
default_search_searchability: 'private'
show_reload_button: true
+ default_column_width: 'x100'
development:
<<: *defaults