From 498cef91c6311cff2f8ba703438b00f65930a946 Mon Sep 17 00:00:00 2001 From: noellabo Date: Sun, 25 Dec 2022 19:32:02 +0900 Subject: [PATCH] Add ability to disable federated timeline --- .../api/v1/timelines/public_controller.rb | 6 ++ .../settings/preferences_controller.rb | 2 + app/javascript/mastodon/actions/compose.js | 6 +- .../mastodon/features/compose/index.js | 18 ++++-- .../features/getting_started/index.js | 24 ++++++-- .../components/column_settings.js | 4 +- .../features/ui/components/columns_area.js | 18 ++++-- .../ui/components/navigation_panel.js | 7 ++- .../features/ui/components/tabs_bar.js | 8 ++- app/javascript/mastodon/features/ui/index.js | 2 + .../features/ui/util/async-components.js | 4 ++ app/javascript/mastodon/initial_state.js | 4 +- app/javascript/mastodon/selectors/index.js | 32 +++++----- app/lib/user_settings_decorator.rb | 2 + app/models/user.rb | 4 +- app/serializers/initial_state_serializer.rb | 2 + .../settings/preferences/other/show.html.haml | 6 ++ config/locales/simple_form.en.yml | 4 ++ config/locales/simple_form.ja.yml | 4 ++ config/settings.yml | 2 + streaming/index.js | 61 ++++++++++++++++++- 21 files changed, 175 insertions(+), 45 deletions(-) diff --git a/app/controllers/api/v1/timelines/public_controller.rb b/app/controllers/api/v1/timelines/public_controller.rb index 66c597463..969f7df0d 100644 --- a/app/controllers/api/v1/timelines/public_controller.rb +++ b/app/controllers/api/v1/timelines/public_controller.rb @@ -22,7 +22,13 @@ class Api::V1::Timelines::PublicController < Api::BaseController !Setting.timeline_preview end + def disable_federated_timeline? + !(truthy_param?(:local) || params[:domain]) && (current_user && !current_user.setting_enable_federated_timeline) + end + def load_statuses + return [] if disable_federated_timeline? + cached_public_statuses_page end diff --git a/app/controllers/settings/preferences_controller.rb b/app/controllers/settings/preferences_controller.rb index 93eb35908..c524efdd7 100644 --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@ -70,7 +70,9 @@ class Settings::PreferencesController < Settings::BaseController :setting_place_tab_bar_at_bottom, :setting_show_tab_bar_label, :setting_show_target, + :setting_enable_federated_timeline, :setting_enable_limited_timeline, + :setting_enable_local_timeline, :setting_enable_reaction, :setting_compact_reaction, :setting_show_reply_tree_button, diff --git a/app/javascript/mastodon/actions/compose.js b/app/javascript/mastodon/actions/compose.js index c91649c22..3c144eed9 100644 --- a/app/javascript/mastodon/actions/compose.js +++ b/app/javascript/mastodon/actions/compose.js @@ -14,7 +14,7 @@ import { openModal } from './modal'; import { defineMessages } from 'react-intl'; import { addYears, addMonths, addDays, addHours, addMinutes, addSeconds, millisecondsToSeconds, set, parseISO, formatISO, format } from 'date-fns'; import { Set as ImmutableSet } from 'immutable'; -import { postReferenceModal } from '../initial_state'; +import { postReferenceModal, enableFederatedTimeline } from '../initial_state'; let cancelFetchComposeSuggestionsAccounts, cancelFetchComposeSuggestionsTags; @@ -313,7 +313,9 @@ export function submitCompose(routerHistory) { } if (response.data.in_reply_to_id === null && response.data.visibility === 'public') { - insertIfOnline('public'); + if (enableFederatedTimeline) { + insertIfOnline('public'); + } insertIfOnline(`account:${response.data.account.id}`); } }).catch(function (error) { diff --git a/app/javascript/mastodon/features/compose/index.js b/app/javascript/mastodon/features/compose/index.js index 16201835e..7dff315a0 100644 --- a/app/javascript/mastodon/features/compose/index.js +++ b/app/javascript/mastodon/features/compose/index.js @@ -14,7 +14,7 @@ import SearchResultsContainer from './containers/search_results_container'; import { changeComposing } from '../../actions/compose'; import { openModal } from 'mastodon/actions/modal'; import elephantUIPlane from '../../../images/elephant_ui_plane.svg'; -import { mascot, show_tab_bar_label, enable_limited_timeline } from '../../initial_state'; +import { mascot, show_tab_bar_label, enableLimitedTimeline, enableFederatedTimeline, enableLocalTimeline } from '../../initial_state'; import Icon from 'mastodon/components/icon'; import { logOut } from 'mastodon/utils/log_out'; import NotificationsCounterIcon from '../ui/components/notifications_counter_icon'; @@ -35,6 +35,7 @@ const messages = defineMessages({ limited_timeline: { id: 'tabs_bar.limited_timeline', defaultMessage: 'Limited home' }, notifications: { id: 'tabs_bar.notifications', defaultMessage: 'Notifications' }, public: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' }, + community: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' }, lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' }, preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' }, logout: { id: 'navigation_bar.logout', defaultMessage: 'Logout' }, @@ -110,7 +111,7 @@ class Compose extends React.PureComponent { 'HOME': { to: '/timelines/home', title: formatMessage(messages.home_timeline), label: formatMessage(messages.short_home_timeline), icon_id: 'home' }, 'LIMITED': { to: '/timelines/limited', title: formatMessage(messages.limited_timeline), label: formatMessage(messages.short_limited_timeline), icon_id: 'lock' }, 'NOTIFICATIONS': { to: '/notifications', title: formatMessage(messages.notifications), label: formatMessage(messages.short_notifications), icon_id: 'bell' }, - // 'COMMUNITY': { to: '/timelines/public/local', title: formatMessage(messages.community), label: formatMessage(messages.short_community), icon_id: 'users' }, + 'COMMUNITY': { to: '/timelines/public/local', title: formatMessage(messages.community), label: formatMessage(messages.short_community), icon_id: 'users' }, 'PUBLIC': { to: '/timelines/public', title: formatMessage(messages.public), label: formatMessage(messages.short_public), icon_id: 'globe' }, 'LIST': { to: '/lists', title: formatMessage(messages.lists), label: formatMessage(messages.short_lists), icon_id: 'list-ul' }, 'PREFERENCES': { href: '/settings/preferences', title: formatMessage(messages.preferences), label: formatMessage(messages.short_preferences), icon_id: 'cog' }, @@ -140,8 +141,17 @@ class Compose extends React.PureComponent { let header = ''; if (multiColumn) { - // const defaultTabIds = ['START', 'HOME', 'NOTIFICATIONS', 'COMMUNITY', 'PUBLIC', 'LIST', 'PREFERENCES', 'SIGN_OUT']; - const defaultTabIds = enable_limited_timeline ? ['START', 'HOME', 'LIMITED', 'NOTIFICATIONS', 'PUBLIC', 'LIST', 'PREFERENCES', 'SIGN_OUT'] : ['START', 'HOME', 'NOTIFICATIONS', 'PUBLIC', 'LIST', 'PREFERENCES', 'SIGN_OUT']; + const defaultTabIds = [ + 'START', + 'HOME', + enableLimitedTimeline ? 'LIMITED' : null, + 'NOTIFICATIONS', + enableLocalTimeline ? 'COMMUNITY' : null, + enableFederatedTimeline ? 'PUBLIC' : null, + 'LIST', + 'PREFERENCES', + 'SIGN_OUT', + ].filter(x => !!x); let tabs = defaultTabIds; diff --git a/app/javascript/mastodon/features/getting_started/index.js b/app/javascript/mastodon/features/getting_started/index.js index 1b26b1402..f524bb060 100644 --- a/app/javascript/mastodon/features/getting_started/index.js +++ b/app/javascript/mastodon/features/getting_started/index.js @@ -7,7 +7,7 @@ import { connect } from 'react-redux'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; -import { me, profile_directory, showTrends, enable_limited_timeline, enableEmptyColumn, defaultColumnWidth } from '../../initial_state'; +import { me, profile_directory, showTrends, enableLimitedTimeline, enableFederatedTimeline, enableLocalTimeline, enableEmptyColumn, defaultColumnWidth } from '../../initial_state'; import { fetchFollowRequests } from 'mastodon/actions/accounts'; import { fetchFavouriteDomains } from 'mastodon/actions/favourite_domains'; import { fetchFavouriteTags } from 'mastodon/actions/favourite_tags'; @@ -25,6 +25,7 @@ const messages = defineMessages({ home_timeline: { id: 'tabs_bar.home', defaultMessage: 'Home' }, notifications: { id: 'tabs_bar.notifications', defaultMessage: 'Notifications' }, public_timeline: { id: 'navigation_bar.public_timeline', defaultMessage: 'Federated timeline' }, + community_timeline: { id: 'navigation_bar.community_timeline', defaultMessage: 'Local timeline' }, settings_subheading: { id: 'column_subheading.settings', defaultMessage: 'Settings' }, direct: { id: 'navigation_bar.direct', defaultMessage: 'Direct messages' }, bookmarks: { id: 'navigation_bar.bookmarks', defaultMessage: 'Bookmarks' }, @@ -128,10 +129,25 @@ class GettingStarted extends ImmutablePureComponent { if (multiColumn) { navItems.push( , - , ); - height += 34 + 48; + height += 34; + + if (enableLocalTimeline) { + navItems.push( + , + ); + + height += 48; + } + + if (enableFederatedTimeline) { + navItems.push( + , + ); + + height += 48; + } navItems.push( , @@ -203,7 +219,7 @@ class GettingStarted extends ImmutablePureComponent { height += 48; } - if (enable_limited_timeline && multiColumn && !columns.find(item => item.get('id') === 'LIMITED')) { + if (enableLimitedTimeline && multiColumn && !columns.find(item => item.get('id') === 'LIMITED')) { navItems.push( , ); diff --git a/app/javascript/mastodon/features/home_timeline/components/column_settings.js b/app/javascript/mastodon/features/home_timeline/components/column_settings.js index 0247f60e2..166689649 100644 --- a/app/javascript/mastodon/features/home_timeline/components/column_settings.js +++ b/app/javascript/mastodon/features/home_timeline/components/column_settings.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { injectIntl, FormattedMessage } from 'react-intl'; import SettingToggle from '../../notifications/components/setting_toggle'; -import { enable_limited_timeline } from 'mastodon/initial_state'; +import { enableLimitedTimeline } from 'mastodon/initial_state'; export default @injectIntl class ColumnSettings extends React.PureComponent { @@ -30,7 +30,7 @@ class ColumnSettings extends React.PureComponent { } /> - {enable_limited_timeline && + {enableLimitedTimeline &&
diff --git a/app/javascript/mastodon/features/ui/components/columns_area.js b/app/javascript/mastodon/features/ui/components/columns_area.js index 6edc277bd..8b32c5431 100644 --- a/app/javascript/mastodon/features/ui/components/columns_area.js +++ b/app/javascript/mastodon/features/ui/components/columns_area.js @@ -8,7 +8,7 @@ import ReactSwipeableViews from 'react-swipeable-views'; import TabsBar, { getSwipeableIndex, getSwipeableLink } from './tabs_bar'; import { Link } from 'react-router-dom'; -import { disableSwiping, place_tab_bar_at_bottom, enable_limited_timeline } from 'mastodon/initial_state'; +import { disableSwiping, place_tab_bar_at_bottom, enableLimitedTimeline, enableFederatedTimeline, enableLocalTimeline } from 'mastodon/initial_state'; import BundleContainer from '../containers/bundle_container'; import ColumnLoading from './column_loading'; @@ -19,6 +19,7 @@ import { Notifications, HomeTimeline, GroupTimeline, + CommunityTimeline, PublicTimeline, DomainTimeline, HashtagTimeline, @@ -49,6 +50,7 @@ const componentMap = { 'NOTIFICATIONS': Notifications, 'PUBLIC': PublicTimeline, 'REMOTE': PublicTimeline, + 'COMMUNITY': CommunityTimeline, 'DOMAIN': DomainTimeline, 'GROUP': GroupTimeline, 'HASHTAG': HashtagTimeline, @@ -122,13 +124,17 @@ class ColumnsArea extends ImmutablePureComponent { this.setState({ shouldAnimate: true }); - if (!enable_limited_timeline) { - const limitedColumn = columns.find(item => item.get('id') === 'LIMITED') + const removeColumnById = id => { + const column = columns.find(item => item.get('id') === id) - if (limitedColumn) { - dispatch(removeColumn(limitedColumn.get('uuid'))); + if (column) { + dispatch(removeColumn(column.get('uuid'))); } - } + }; + + if (!enableFederatedTimeline) { removeColumnById('PUBLIC'); } + if (!enableLocalTimeline) { removeColumnById('COMMUNITY'); } + if (!enableLimitedTimeline) { removeColumnById('LIMITED'); } } componentWillUpdate(nextProps) { diff --git a/app/javascript/mastodon/features/ui/components/navigation_panel.js b/app/javascript/mastodon/features/ui/components/navigation_panel.js index c259aac5d..a4a33b410 100644 --- a/app/javascript/mastodon/features/ui/components/navigation_panel.js +++ b/app/javascript/mastodon/features/ui/components/navigation_panel.js @@ -2,7 +2,7 @@ import React from 'react'; import { NavLink, withRouter } from 'react-router-dom'; import { FormattedMessage } from 'react-intl'; import Icon from 'mastodon/components/icon'; -import { profile_directory, showTrends, enable_limited_timeline } from 'mastodon/initial_state'; +import { profile_directory, showTrends, enableLimitedTimeline, enableFederatedTimeline, enableLocalTimeline } from 'mastodon/initial_state'; import NotificationsCounterIcon from './notifications_counter_icon'; import FollowRequestsNavLink from './follow_requests_nav_link'; import ListPanel from './list_panel'; @@ -13,10 +13,11 @@ import TrendsContainer from 'mastodon/features/getting_started/containers/trends const NavigationPanel = () => (
- {enable_limited_timeline && } + {enableLimitedTimeline && } - + {enableLocalTimeline && } + {enableFederatedTimeline && } diff --git a/app/javascript/mastodon/features/ui/components/tabs_bar.js b/app/javascript/mastodon/features/ui/components/tabs_bar.js index d4f27d19e..f41bbaadd 100644 --- a/app/javascript/mastodon/features/ui/components/tabs_bar.js +++ b/app/javascript/mastodon/features/ui/components/tabs_bar.js @@ -6,7 +6,7 @@ import { debounce, memoize } from 'lodash'; import { isUserTouching } from '../../../is_mobile'; import Icon from 'mastodon/components/icon'; import NotificationsCounterIcon from './notifications_counter_icon'; -import { place_tab_bar_at_bottom, show_tab_bar_label, enable_limited_timeline } from 'mastodon/initial_state'; +import { place_tab_bar_at_bottom, show_tab_bar_label, enableLimitedTimeline, enableFederatedTimeline, enableLocalTimeline } from 'mastodon/initial_state'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { connect } from 'react-redux'; import { createSelector } from 'reselect'; @@ -15,6 +15,7 @@ import classNames from 'classnames'; const link_home = <>{msg}} /> <>{msg}} />; const link_limited = <>{msg}} /> <>{msg}} />; const link_notifications = <>{msg}} /> <>{msg}} />; +const link_local = <>{msg}} /> <>{msg}} />; const link_public = <>{msg}} /> <>{msg}} />; // const link_lists = <>{msg}} /> <>{msg}} />; const link_search = <>{msg}} /> <>{msg}} />; @@ -38,10 +39,11 @@ export const getLinks = memoize((favouriteLists = null) => { return [ link_home, - enable_limited_timeline ? link_limited : null, + enableLimitedTimeline ? link_limited : null, link_favourite_lists, link_notifications, - link_public, + enableLocalTimeline ? link_local : null, + enableFederatedTimeline ? link_public : null, link_search, link_started, ].flat().filter(v => !!v); diff --git a/app/javascript/mastodon/features/ui/index.js b/app/javascript/mastodon/features/ui/index.js index f9a204baa..3a2d6786d 100644 --- a/app/javascript/mastodon/features/ui/index.js +++ b/app/javascript/mastodon/features/ui/index.js @@ -30,6 +30,7 @@ import { GettingStarted, KeyboardShortcuts, PublicTimeline, + CommunityTimeline, DomainTimeline, GroupTimeline, AccountTimeline, @@ -176,6 +177,7 @@ 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 16b89a713..8281a1a66 100644 --- a/app/javascript/mastodon/features/ui/util/async-components.js +++ b/app/javascript/mastodon/features/ui/util/async-components.js @@ -18,6 +18,10 @@ export function PublicTimeline () { return import(/* webpackChunkName: "features/public_timeline" */'../../public_timeline'); } +export function CommunityTimeline () { + return import(/* webpackChunkName: "features/community_timeline" */'../../public_timeline'); +} + export function DomainTimeline () { return import(/* webpackChunkName: "features/domain_timeline" */'../../domain_timeline'); } diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js index 48d9fe4ae..525033cf2 100644 --- a/app/javascript/mastodon/initial_state.js +++ b/app/javascript/mastodon/initial_state.js @@ -42,7 +42,9 @@ export const show_bookmark_button = getMeta('show_bookmark_button'); export const show_target = getMeta('show_target'); export const place_tab_bar_at_bottom = getMeta('place_tab_bar_at_bottom'); export const show_tab_bar_label = getMeta('show_tab_bar_label'); -export const enable_limited_timeline = getMeta('enable_limited_timeline'); +export const enableLimitedTimeline = getMeta('enable_limited_timeline'); +export const enableFederatedTimeline = getMeta('enable_federated_timeline') ?? true; +export const enableLocalTimeline = getMeta('enable_local_timeline') ?? true; export const enableReaction = getMeta('enable_reaction'); export const compactReaction = getMeta('compact_reaction'); export const show_reply_tree_button = getMeta('show_reply_tree_button'); diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js index 4aea4bb2c..76a2d63fa 100644 --- a/app/javascript/mastodon/selectors/index.js +++ b/app/javascript/mastodon/selectors/index.js @@ -1,6 +1,6 @@ import { createSelector } from 'reselect'; import { List as ImmutableList, Map as ImmutableMap, is } from 'immutable'; -import { me, enable_limited_timeline } from '../initial_state'; +import { me, enableLimitedTimeline } from '../initial_state'; const getAccountBase = (state, id) => state.getIn(['accounts', id], null); const getAccountCounters = (state, id) => state.getIn(['accounts_counters', id], null); @@ -249,22 +249,20 @@ export const getAccountGallery = createSelector([ export const getHomeVisibilities = createSelector( state => state.getIn(['settings', 'home', 'shows']), - shows => { - return enable_limited_timeline ? ( - ['public', 'unlisted'] - .concat(shows.get('private') ? ['private'] : []) - .concat(shows.get('limited') ? ['limited'] : []) - .concat(shows.get('direct') ? ['direct'] : []) - ) : []; -}); + shows => !enableLimitedTimeline ? [] : [ + 'public', + 'unlisted', + shows.get('private') ? 'private' : null, + shows.get('limited') ? 'limited' : null, + shows.get('direct') ? 'direct' : null, + ].filter(x => !!x), +); export const getLimitedVisibilities = createSelector( state => state.getIn(['settings', 'limited', 'shows']), - shows => { - return enable_limited_timeline ? ( - [] - .concat(shows.get('private') ? ['private'] : []) - .concat(shows.get('limited') ? ['limited'] : []) - .concat(shows.get('direct') ? ['direct'] : []) - ) : []; -}); + shows => !enableLimitedTimeline ? [] : [ + shows.get('private') ? 'private' : null, + shows.get('limited') ? 'limited' : null, + shows.get('direct') ? 'direct' : null, + ].filter(x => !!x), +); diff --git a/app/lib/user_settings_decorator.rb b/app/lib/user_settings_decorator.rb index b45e406ac..5451ede05 100644 --- a/app/lib/user_settings_decorator.rb +++ b/app/lib/user_settings_decorator.rb @@ -63,7 +63,9 @@ class UserSettingsDecorator show_target place_tab_bar_at_bottom show_tab_bar_label + enable_federated_timeline enable_limited_timeline + enable_local_timeline enable_reaction compact_reaction show_reply_tree_button diff --git a/app/models/user.rb b/app/models/user.rb index ae88221c8..531bfb990 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -129,7 +129,9 @@ class User < ApplicationRecord :show_follow_button_on_timeline, :show_subscribe_button_on_timeline, :show_target, :show_follow_button_on_timeline, :show_subscribe_button_on_timeline, :show_followed_by, :show_target, :follow_button_to_list_adder, :show_navigation_panel, :show_quote_button, :show_bookmark_button, - :place_tab_bar_at_bottom,:show_tab_bar_label, :enable_limited_timeline, :enable_reaction, :compact_reaction, + :place_tab_bar_at_bottom,:show_tab_bar_label, + :enable_local_timeline, :enable_federated_timeline, :enable_limited_timeline, + :enable_reaction, :compact_reaction, :show_reply_tree_button, :hide_statuses_count, :hide_following_count, :hide_followers_count, :disable_joke_appearance, :new_features_policy, diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 6239e89c3..953afae90 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -53,7 +53,9 @@ class InitialStateSerializer < ActiveModel::Serializer store[:show_target] = object.current_account.user.setting_show_target store[:place_tab_bar_at_bottom] = object.current_account.user.setting_place_tab_bar_at_bottom store[:show_tab_bar_label] = object.current_account.user.setting_show_tab_bar_label + store[:enable_federated_timeline] = object.current_account.user.setting_enable_federated_timeline store[:enable_limited_timeline] = object.current_account.user.setting_enable_limited_timeline + store[:enable_local_timeline] = false #object.current_account.user.setting_enable_local_timeline store[:enable_reaction] = object.current_account.user.setting_enable_reaction store[:compact_reaction] = object.current_account.user.setting_compact_reaction store[:show_reply_tree_button] = object.current_account.user.setting_show_reply_tree_button diff --git a/app/views/settings/preferences/other/show.html.haml b/app/views/settings/preferences/other/show.html.haml index 38fa01a73..24b103bfe 100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@ -86,6 +86,12 @@ .fields-group = f.input :setting_show_tab_bar_label, as: :boolean, wrapper: :with_label, fedibird_features: true + -# .fields-group + -# = f.input :setting_enable_local_timeline, as: :boolean, wrapper: :with_label, fedibird_features: true + + .fields-group + = f.input :setting_enable_federated_timeline, as: :boolean, wrapper: :with_label, fedibird_features: true + .fields-group = f.input :setting_enable_limited_timeline, as: :boolean, wrapper: :with_label, fedibird_features: true diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index fd4b0d268..e618188e3 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -83,7 +83,9 @@ en: 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_federated_timeline: 'Enable a federated timeline (default: enable)' setting_enable_limited_timeline: Enable a limited home to display private and circle and direct message + setting_enable_local_timeline: 'Enable a local timeline (default: enable)' 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 setting_follow_button_to_list_adder: Change the behavior of the Follow / Subscribe button, open a dialog where you can select a list to follow / subscribe, or opt out of receiving at home @@ -267,7 +269,9 @@ en: setting_display_media_show_all: Show all setting_emoji_scale: Single emoji size setting_enable_empty_column: Enable last column to be closed + setting_enable_federated_timeline: Enable federated timeline setting_enable_limited_timeline: Enable limited timeline + setting_enable_local_timeline: Enable local timeline setting_enable_reaction: Enable reaction setting_enable_status_reference: Enable reference setting_expand_spoilers: Always expand posts marked with content warnings diff --git a/config/locales/simple_form.ja.yml b/config/locales/simple_form.ja.yml index 04991f93f..e3ae354ac 100644 --- a/config/locales/simple_form.ja.yml +++ b/config/locales/simple_form.ja.yml @@ -79,7 +79,9 @@ ja: setting_display_media_hide_all: メディアを常に隠す setting_display_media_show_all: メディアを常に表示する setting_enable_empty_column: 最後のカラムを初期状態で非表示にし、任意に閉じられるようにします + setting_enable_federated_timeline: 連合タイムラインを有効にします(デフォルト) setting_enable_limited_timeline: フォロワー限定・サークル・ダイレクトメッセージを表示する限定ホームを有効にします + setting_enable_local_timeline: ローカルタイムラインを有効にします(デフォルト) setting_enable_reaction: タイムラインでリアクションの表示を有効にし、リアクションボタンを表示する setting_enable_status_reference: 投稿が別の投稿を参照する機能を有効にします setting_follow_button_to_list_adder: フォロー・購読ボタンの動作を変更し、フォロー・購読するリストを選択したり、ホームで受け取らないよう設定するダイアログを開きます @@ -263,7 +265,9 @@ ja: setting_display_media_show_all: 表示 setting_emoji_scale: 単独絵文字のサイズ setting_enable_empty_column: 最終カラムを閉じられるようにする + setting_enable_federated_timeline: 連合タイムラインを有効にする setting_enable_limited_timeline: 限定ホームを有効にする + setting_enable_local_timeline: ローカルタイムラインを有効にする setting_enable_reaction: リアクションを有効にする setting_enable_status_reference: 参照を有効にする setting_expand_spoilers: 閲覧注意としてマークされた投稿を常に展開する diff --git a/config/settings.yml b/config/settings.yml index 684e17a55..1a8515b0d 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -53,7 +53,9 @@ defaults: &defaults show_target: false place_tab_bar_at_bottom: false show_tab_bar_label: false + enable_federated_timeline: true enable_limited_timeline: false + enable_local_timeline: true enable_reaction: true compact_reaction: false show_reply_tree_button: true diff --git a/streaming/index.js b/streaming/index.js index a4cbfb38f..660fd2d3a 100644 --- a/streaming/index.js +++ b/streaming/index.js @@ -294,7 +294,7 @@ const startWorker = (workerId) => { return; } - client.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes, devices.device_id, oauth_applications.name, oauth_applications.website, (select settings.value from settings where thing_type = \'User\' and thing_id=users.id and var = \'hide_bot_on_public_timeline\') as bot FROM oauth_access_tokens INNER JOIN oauth_applications ON oauth_access_tokens.application_id = oauth_applications.id INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id LEFT OUTER JOIN devices ON oauth_access_tokens.id = devices.access_token_id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL LIMIT 1', [token], (err, result) => { + client.query('SELECT oauth_access_tokens.id, oauth_access_tokens.resource_owner_id, users.account_id, users.chosen_languages, oauth_access_tokens.scopes, devices.device_id, oauth_applications.name, oauth_applications.website, (select settings.value from settings where thing_type = \'User\' and thing_id=users.id and var = \'hide_bot_on_public_timeline\') as bot, (select exists (select settings.value from settings where thing_type = \'User\' and thing_id=users.id and var = \'enable_federated_timeline\' and value ilike \'%false%\')) as disable_federated_timeline FROM oauth_access_tokens INNER JOIN oauth_applications ON oauth_access_tokens.application_id = oauth_applications.id INNER JOIN users ON oauth_access_tokens.resource_owner_id = users.id LEFT OUTER JOIN devices ON oauth_access_tokens.id = devices.access_token_id WHERE oauth_access_tokens.token = $1 AND oauth_access_tokens.revoked_at IS NULL LIMIT 1', [token], (err, result) => { done(); if (err) { @@ -315,6 +315,7 @@ const startWorker = (workerId) => { req.accountId = result.rows[0].account_id; req.chosenLanguages = result.rows[0].chosen_languages; req.bot = result.rows[0].bot; + req.enableFederatedTimeline = !result.rows[0].disable_federated_timeline; req.allowNotifications = req.scopes.some(scope => ['read', 'read:notifications'].includes(scope)); req.deviceId = result.rows[0].device_id; req.applicationName = result.rows[0].name; @@ -826,6 +827,10 @@ const startWorker = (workerId) => { break; case 'public': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: req.applicationName === '◆ Tootdon ◆' ? ['timeline:public:remote'] : ['timeline:public'], options: { needsFiltering: true, notificationOnly: false }, @@ -833,6 +838,10 @@ const startWorker = (workerId) => { break; case 'public:nobot': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: req.applicationName === '◆ Tootdon ◆' ? ['timeline:public:remote:nobot'] : ['timeline:public:nobot'], options: { needsFiltering: true, notificationOnly: false }, @@ -872,6 +881,10 @@ const startWorker = (workerId) => { break; case 'public:remote': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: ['timeline:public:remote'], options: { needsFiltering: true, notificationOnly: false }, @@ -879,6 +892,10 @@ const startWorker = (workerId) => { break; case 'public:remote:nobot': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: ['timeline:public:remote:nobot'], options: { needsFiltering: true, notificationOnly: false }, @@ -919,6 +936,10 @@ const startWorker = (workerId) => { break; case 'public:media': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: req.applicationName === '◆ Tootdon ◆' ? ['timeline:public:remote:media'] : ['timeline:public:media'], options: { needsFiltering: true, notificationOnly: false }, @@ -926,6 +947,10 @@ const startWorker = (workerId) => { break; case 'public:nobot:media': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: req.applicationName === '◆ Tootdon ◆' ? ['timeline:public:remote:nobot:media'] : ['timeline:public:nobot:media'], options: { needsFiltering: true, notificationOnly: false }, @@ -965,6 +990,10 @@ const startWorker = (workerId) => { break; case 'public:remote:media': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: ['timeline:public:remote:media'], options: { needsFiltering: true, notificationOnly: false }, @@ -972,6 +1001,10 @@ const startWorker = (workerId) => { break; case 'public:remote:nobot:media': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: ['timeline:public:remote:nobot:media'], options: { needsFiltering: true, notificationOnly: false }, @@ -1001,6 +1034,10 @@ const startWorker = (workerId) => { break; case 'public:nomedia': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: req.applicationName === '◆ Tootdon ◆' ? ['timeline:public:remote:nomedia'] : ['timeline:public:nomedia'], options: { needsFiltering: true, notificationOnly: false }, @@ -1008,6 +1045,10 @@ const startWorker = (workerId) => { break; case 'public:nobot:nomedia': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: req.applicationName === '◆ Tootdon ◆' ? ['timeline:public:remote:nobot:nomedia'] : ['timeline:public:nobot:nomedia'], options: { needsFiltering: true, notificationOnly: false }, @@ -1047,6 +1088,10 @@ const startWorker = (workerId) => { break; case 'public:remote:nomedia': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: ['timeline:public:remote:nomedia'], options: { needsFiltering: true, notificationOnly: false }, @@ -1054,6 +1099,10 @@ const startWorker = (workerId) => { break; case 'public:remote:nobot:nomedia': + if (!isEnableFederatedTimeline(req)) { + reject('No local stream provided'); + } + resolve({ channelIds: ['timeline:public:remote:nobot:nomedia'], options: { needsFiltering: true, notificationOnly: false }, @@ -1350,7 +1399,15 @@ const startWorker = (workerId) => { * @param {any} req * @return {boolean} */ - const isImast = (req) => { +const isEnableFederatedTimeline = (req) => { + return req.enableFederatedTimeline; +}; + +/** + * @param {any} req + * @return {boolean} + */ +const isImast = (req) => { return req.website == 'https://cinderella-project.github.io/iMast/'; };