* Bump version to 8.0 * Add: 他のサーバーに公開する情報に、制限設定などを追加 * Fix: `quote_of_id`のインデックス * Fix: #172 他のサーバーからの相乗り絵文字削除が反映されない * Test: #166 リモートから自分の絵文字を受け取った時、ライセンスが上書きされないことを確認するテスト * Add: #62 ローカルタイムラインを無効にする管理者設定(内部挙動のみ) * Add: 画面部分を追加
This commit is contained in:
parent
ae865975d4
commit
1d8862712a
21 changed files with 238 additions and 16 deletions
|
@ -27,6 +27,7 @@ module KmyblueCapabilitiesHelper
|
|||
capabilities << :enable_wide_emoji_reaction
|
||||
end
|
||||
capabilities << :kmyblue_visibility_public_unlisted if Setting.enable_public_unlisted_visibility
|
||||
capabilities << :timeline_no_local unless Setting.enable_local_timeline
|
||||
|
||||
capabilities
|
||||
end
|
||||
|
@ -58,6 +59,7 @@ module KmyblueCapabilitiesHelper
|
|||
capabilities << :emoji_reaction
|
||||
capabilities << :enable_wide_emoji_reaction
|
||||
end
|
||||
capabilities << :timeline_no_local unless Setting.enable_local_timeline
|
||||
|
||||
capabilities
|
||||
end
|
||||
|
|
|
@ -25,6 +25,7 @@ const messages = defineMessages({
|
|||
title: { id: 'column.about', defaultMessage: 'About' },
|
||||
rules: { id: 'about.rules', defaultMessage: 'Server rules' },
|
||||
blocks: { id: 'about.blocks', defaultMessage: 'Moderated servers' },
|
||||
localTimeline: { id: 'column.community', defaultMessage: 'Local timeline' },
|
||||
noop: { id: 'about.domain_blocks.noop.title', defaultMessage: 'Soft limited' },
|
||||
noopExplanation: { id: 'about.domain_blocks.noop.explanation', defaultMessage: 'This server is limited partically.' },
|
||||
silenced: { id: 'about.domain_blocks.silenced.title', defaultMessage: 'Limited' },
|
||||
|
@ -133,6 +134,7 @@ class About extends PureComponent {
|
|||
const fedibirdCapabilities = server.get('fedibird_capabilities') || []; // thinking about isLoading is true
|
||||
const isPublicUnlistedVisibility = fedibirdCapabilities.includes('kmyblue_visibility_public_unlisted');
|
||||
const isEmojiReaction = fedibirdCapabilities.includes('emoji_reaction');
|
||||
const isLocalTimeline = !fedibirdCapabilities.includes('timeline_no_local');
|
||||
|
||||
return (
|
||||
<Column bindToDocument={!multiColumn} label={intl.formatMessage(messages.title)}>
|
||||
|
@ -204,6 +206,9 @@ class About extends PureComponent {
|
|||
<li>
|
||||
<span className='rules-list__text'>{intl.formatMessage(messages.publicUnlistedVisibility)}: {intl.formatMessage(isPublicUnlistedVisibility ? messages.enabled : messages.disabled)}</span>
|
||||
</li>
|
||||
<li>
|
||||
<span className='rules-list__text'>{intl.formatMessage(messages.localTimeline)}: {intl.formatMessage(isLocalTimeline ? messages.enabled : messages.disabled)}</span>
|
||||
</li>
|
||||
</ol>
|
||||
)}
|
||||
</Section>
|
||||
|
|
|
@ -46,6 +46,7 @@ import ColumnHeader from 'mastodon/components/column_header';
|
|||
import { Icon } from 'mastodon/components/icon';
|
||||
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||
import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';
|
||||
import { enableLocalTimeline } from 'mastodon/initial_state';
|
||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
||||
|
||||
import RadioPanel from './components/radio_panel';
|
||||
|
@ -401,7 +402,7 @@ class AntennaSetting extends PureComponent {
|
|||
</button>
|
||||
</div>
|
||||
|
||||
{!isLtl && (
|
||||
{!isLtl && (enableLocalTimeline || isStl) && (
|
||||
<div className='setting-toggle'>
|
||||
<Toggle id={`antenna-${id}-stl`} defaultChecked={isStl} onChange={this.onStlToggle} />
|
||||
<label htmlFor={`antenna-${id}-stl`} className='setting-toggle__label'>
|
||||
|
@ -410,7 +411,7 @@ class AntennaSetting extends PureComponent {
|
|||
</div>
|
||||
)}
|
||||
|
||||
{!isStl && (
|
||||
{!isStl && (enableLocalTimeline || isLtl) && (
|
||||
<div className='setting-toggle'>
|
||||
<Toggle id={`antenna-${id}-ltl`} defaultChecked={isLtl} onChange={this.onLtlToggle} />
|
||||
<label htmlFor={`antenna-${id}-ltl`} className='setting-toggle__label'>
|
||||
|
|
|
@ -13,7 +13,7 @@ import { changeSetting } from 'mastodon/actions/settings';
|
|||
import { connectPublicStream, connectCommunityStream } from 'mastodon/actions/streaming';
|
||||
import { expandPublicTimeline, expandCommunityTimeline } from 'mastodon/actions/timelines';
|
||||
import { DismissableBanner } from 'mastodon/components/dismissable_banner';
|
||||
import initialState, { domain } from 'mastodon/initial_state';
|
||||
import initialState, { domain, enableLocalTimeline } from 'mastodon/initial_state';
|
||||
import { useAppDispatch, useAppSelector } from 'mastodon/store';
|
||||
|
||||
import Column from '../../components/column';
|
||||
|
@ -173,9 +173,11 @@ const Firehose = ({ feedType, multiColumn }) => {
|
|||
</ColumnHeader>
|
||||
|
||||
<div className='account__section-headline'>
|
||||
<NavLink exact to='/public/local'>
|
||||
<FormattedMessage tagName='div' id='firehose.local' defaultMessage='This server' />
|
||||
</NavLink>
|
||||
{enableLocalTimeline && (
|
||||
<NavLink exact to='/public/local'>
|
||||
<FormattedMessage tagName='div' id='firehose.local' defaultMessage='This server' />
|
||||
</NavLink>
|
||||
)}
|
||||
|
||||
<NavLink exact to='/public/remote'>
|
||||
<FormattedMessage tagName='div' id='firehose.remote' defaultMessage='Other servers' />
|
||||
|
|
|
@ -21,7 +21,7 @@ import { ReactComponent as AntennaIcon } from '@material-symbols/svg-600/outline
|
|||
|
||||
import { WordmarkLogo } from 'mastodon/components/logo';
|
||||
import { NavigationPortal } from 'mastodon/components/navigation_portal';
|
||||
import { enableDtlMenu, timelinePreview, trendsEnabled, dtlTag } from 'mastodon/initial_state';
|
||||
import { enableDtlMenu, timelinePreview, trendsEnabled, dtlTag, enableLocalTimeline } from 'mastodon/initial_state';
|
||||
import { transientSingleColumn } from 'mastodon/is_mobile';
|
||||
|
||||
import ColumnLink from './column_link';
|
||||
|
@ -108,10 +108,13 @@ class NavigationPanel extends Component {
|
|||
<>
|
||||
<ColumnLink transparent to='/home' icon='home' iconComponent={HomeIcon} text={intl.formatMessage(messages.home)} />
|
||||
<ColumnLink transparent to='/notifications' icon={<NotificationsCounterIcon className='column-link__icon' />} text={intl.formatMessage(messages.notifications)} />
|
||||
<ColumnLink transparent to='/public/local/fixed' icon='users' iconComponent={PeopleIcon} text={intl.formatMessage(messages.local)} />
|
||||
</>
|
||||
)}
|
||||
|
||||
{signedIn && enableLocalTimeline && (
|
||||
<ColumnLink transparent to='/public/local/fixed' icon='users' iconComponent={PeopleIcon} text={intl.formatMessage(messages.local)} />
|
||||
)}
|
||||
|
||||
{signedIn && enableDtlMenu && dtlTag && (
|
||||
<ColumnLink transparent to={`/tags/${dtlTag}`} icon='users' iconComponent={PeopleIcon} text={intl.formatMessage(messages.deepLocal)} />
|
||||
)}
|
||||
|
@ -123,7 +126,7 @@ class NavigationPanel extends Component {
|
|||
)}
|
||||
|
||||
{(!signedIn && timelinePreview) && (
|
||||
<ColumnLink transparent to='/public/local' isActive={this.isFirehoseActive} icon='globe' iconComponent={PublicIcon} text={intl.formatMessage(messages.firehose)} />
|
||||
<ColumnLink transparent to={enableLocalTimeline ? '/public/local' : '/public'} isActive={this.isFirehoseActive} icon='globe' iconComponent={PublicIcon} text={intl.formatMessage(messages.firehose)} />
|
||||
)}
|
||||
|
||||
{signedIn && (
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
* @property {boolean} enable_emoji_reaction
|
||||
* @property {boolean} enable_login_privacy
|
||||
* @property {boolean} enable_local_privacy
|
||||
* @property {boolean} enable_local_timeline
|
||||
* @property {boolean} enable_dtl_menu
|
||||
* @property {boolean=} expand_spoilers
|
||||
* @property {boolean} hide_blocking_quote
|
||||
|
@ -136,6 +137,7 @@ export const domain = getMeta('domain');
|
|||
export const dtlTag = getMeta('dtl_tag');
|
||||
export const enableEmojiReaction = getMeta('enable_emoji_reaction');
|
||||
export const enableLocalPrivacy = getMeta('enable_local_privacy');
|
||||
export const enableLocalTimeline = getMeta('enable_local_timeline');
|
||||
export const enableLoginPrivacy = getMeta('enable_login_privacy');
|
||||
export const enableDtlMenu = getMeta('enable_dtl_menu');
|
||||
export const expandSpoilers = getMeta('expand_spoilers');
|
||||
|
|
|
@ -51,6 +51,7 @@ class Form::AdminSettings
|
|||
check_lts_version_only
|
||||
enable_public_unlisted_visibility
|
||||
unlocked_friend
|
||||
enable_local_timeline
|
||||
).freeze
|
||||
|
||||
INTEGER_KEYS = %i(
|
||||
|
@ -81,6 +82,7 @@ class Form::AdminSettings
|
|||
enable_public_unlisted_visibility
|
||||
unlocked_friend
|
||||
stranger_mention_from_local_ng
|
||||
enable_local_timeline
|
||||
).freeze
|
||||
|
||||
UPLOAD_KEYS = %i(
|
||||
|
|
|
@ -19,6 +19,8 @@ class PublicFeed
|
|||
# @param [Integer] min_id
|
||||
# @return [Array<Status>]
|
||||
def get(limit, max_id = nil, since_id = nil, min_id = nil)
|
||||
return [] if local_only? && !Setting.enable_local_timeline
|
||||
|
||||
scope = public_scope
|
||||
|
||||
scope.merge!(without_replies_scope) unless with_replies?
|
||||
|
|
|
@ -23,6 +23,8 @@ class TagFeed < PublicFeed
|
|||
# @param [Integer] min_id
|
||||
# @return [Array<Status>]
|
||||
def get(limit, max_id = nil, since_id = nil, min_id = nil)
|
||||
return [] if local_only? && !Setting.enable_local_timeline
|
||||
|
||||
scope = public_search_scope
|
||||
|
||||
scope.merge!(tagged_with_any_scope)
|
||||
|
|
|
@ -38,6 +38,7 @@ class InitialStateSerializer < ActiveModel::Serializer
|
|||
sso_redirect: sso_redirect,
|
||||
dtl_tag: DTL_ENABLED ? DTL_TAG : nil,
|
||||
enable_local_privacy: Setting.enable_public_unlisted_visibility,
|
||||
enable_local_timeline: Setting.enable_local_timeline,
|
||||
}
|
||||
|
||||
if object.current_account
|
||||
|
|
|
@ -27,7 +27,8 @@ class DeliveryAntennaService
|
|||
return if must_dtl_tag && !DTL_ENABLED
|
||||
|
||||
tag_ids = @status.tags.pluck(:id)
|
||||
domain = @account.domain || Rails.configuration.x.local_domain
|
||||
domain = @account.domain
|
||||
domain ||= Rails.configuration.x.local_domain if Setting.enable_local_timeline
|
||||
follower_ids = @status.unlisted_visibility? ? @status.account.followers.pluck(:id) : []
|
||||
|
||||
antennas = Antenna.availables
|
||||
|
@ -77,6 +78,8 @@ class DeliveryAntennaService
|
|||
end
|
||||
|
||||
def delivery_stl!
|
||||
return unless Setting.enable_local_timeline
|
||||
|
||||
antennas = Antenna.available_stls
|
||||
antennas = antennas.where(account_id: Account.without_suspended.joins(:user).select('accounts.id').where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago))
|
||||
|
||||
|
@ -101,6 +104,7 @@ class DeliveryAntennaService
|
|||
return if %i(public public_unlisted login).exclude?(@status.visibility.to_sym)
|
||||
return unless @account.local?
|
||||
return if @status.reblog?
|
||||
return unless Setting.enable_local_timeline
|
||||
|
||||
antennas = Antenna.available_ltls
|
||||
antennas = antennas.where(account_id: Account.without_suspended.joins(:user).select('accounts.id').where('users.current_sign_in_at > ?', User::ACTIVE_DURATION.ago))
|
||||
|
|
|
@ -50,12 +50,12 @@ class FanOutOnWriteService < BaseService
|
|||
deliver_to_all_followers!
|
||||
deliver_to_lists!
|
||||
deliver_to_antennas! if !@account.dissubscribable || (@status.dtl? && DTL_ENABLED && @account.user&.setting_dtl_force_subscribable && @status.tags.exists?(name: DTL_TAG))
|
||||
deliver_to_stl_antennas!
|
||||
deliver_to_ltl_antennas!
|
||||
deliver_to_stl_antennas! if Setting.enable_local_timeline
|
||||
deliver_to_ltl_antennas! if Setting.enable_local_timeline
|
||||
when :limited
|
||||
deliver_to_lists_mentioned_accounts_only!
|
||||
deliver_to_antennas! unless @account.dissubscribable
|
||||
deliver_to_stl_antennas!
|
||||
deliver_to_stl_antennas! if Setting.enable_local_timeline
|
||||
deliver_to_mentioned_followers!
|
||||
else
|
||||
deliver_to_mentioned_followers!
|
||||
|
@ -152,7 +152,7 @@ class FanOutOnWriteService < BaseService
|
|||
def broadcast_to_hashtag_streams!
|
||||
@status.tags.map(&:name).each do |hashtag|
|
||||
redis.publish("timeline:hashtag:#{hashtag.mb_chars.downcase}", anonymous_payload)
|
||||
redis.publish("timeline:hashtag:#{hashtag.mb_chars.downcase}:local", anonymous_payload) if @status.local?
|
||||
redis.publish("timeline:hashtag:#{hashtag.mb_chars.downcase}:local", anonymous_payload) if @status.local? && Setting.enable_local_timeline
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -160,11 +160,13 @@ class FanOutOnWriteService < BaseService
|
|||
return if @status.reply? && @status.in_reply_to_account_id != @account.id
|
||||
|
||||
redis.publish('timeline:public', anonymous_payload)
|
||||
redis.publish(@status.local? ? 'timeline:public:local' : 'timeline:public:remote', anonymous_payload)
|
||||
redis.publish('timeline:public:remote', anonymous_payload) unless @status.local?
|
||||
redis.publish('timeline:public:local', anonymous_payload) if @status.local? && Setting.enable_local_timeline
|
||||
|
||||
if @status.with_media?
|
||||
redis.publish('timeline:public:media', anonymous_payload)
|
||||
redis.publish(@status.local? ? 'timeline:public:local:media' : 'timeline:public:remote:media', anonymous_payload)
|
||||
redis.publish('timeline:public:remote:media', anonymous_payload) unless @status.local?
|
||||
redis.publish('timeline:public:local:media', anonymous_payload) if @status.local? && Setting.enable_local_timeline
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -45,6 +45,9 @@
|
|||
.fields-group
|
||||
= f.input :enable_public_unlisted_visibility, as: :boolean, wrapper: :with_label, kmyblue: true, hint: false
|
||||
|
||||
.fields-group
|
||||
= f.input :enable_local_timeline, as: :boolean, wrapper: :with_label, kmyblue: true
|
||||
|
||||
%h4= t('admin.settings.discovery.friend_servers')
|
||||
|
||||
.fields-group
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue