* Add: #483 特定の公開範囲を無効にするオプション * Fix test partically * Complete
This commit is contained in:
parent
7f9ec2e510
commit
f79fb3adae
24 changed files with 177 additions and 59 deletions
|
@ -19,6 +19,16 @@ class Settings::Preferences::BaseController < Settings::BaseController
|
|||
end
|
||||
|
||||
def user_params
|
||||
original_user_params.tap do |params|
|
||||
params[:settings_attributes]&.merge!(disabled_visibilities_params[:settings_attributes] || {})
|
||||
end
|
||||
end
|
||||
|
||||
def original_user_params
|
||||
params.require(:user).permit(:locale, :time_zone, chosen_languages: [], settings_attributes: UserSettings.keys)
|
||||
end
|
||||
|
||||
def disabled_visibilities_params
|
||||
params.require(:user).permit(settings_attributes: { enabled_visibilities: [] })
|
||||
end
|
||||
end
|
||||
|
|
|
@ -116,7 +116,7 @@ class ComposeForm extends ImmutablePureComponent {
|
|||
const fulltext = this.getFulltextForCharacterCounting();
|
||||
const isOnlyWhitespace = fulltext.length !== 0 && fulltext.trim().length === 0;
|
||||
|
||||
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars || (isOnlyWhitespace && !anyMedia) || (privacy === 'circle' && !isEditing && !circleId));
|
||||
return !(isSubmitting || isUploading || isChangingUpload || length(fulltext) > maxChars || (isOnlyWhitespace && !anyMedia) || (privacy === 'circle' && !isEditing && !circleId) || privacy === 'banned');
|
||||
};
|
||||
|
||||
handleSubmit = (e) => {
|
||||
|
|
|
@ -9,6 +9,7 @@ import Overlay from 'react-overlays/Overlay';
|
|||
|
||||
import CircleIcon from '@/material-icons/400-24px/account_circle.svg?react';
|
||||
import AlternateEmailIcon from '@/material-icons/400-24px/alternate_email.svg?react';
|
||||
import BlockIcon from '@/material-icons/400-24px/block.svg?react';
|
||||
import PublicUnlistedIcon from '@/material-icons/400-24px/cloud.svg?react';
|
||||
import MutualIcon from '@/material-icons/400-24px/compare_arrows.svg?react';
|
||||
import LoginIcon from '@/material-icons/400-24px/key.svg?react';
|
||||
|
@ -18,7 +19,7 @@ import QuietTimeIcon from '@/material-icons/400-24px/quiet_time.svg?react';
|
|||
import ReplyIcon from '@/material-icons/400-24px/reply.svg?react';
|
||||
import LimitedIcon from '@/material-icons/400-24px/shield.svg?react';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { enableLoginPrivacy, enableLocalPrivacy, enablePublicPrivacy } from 'mastodon/initial_state';
|
||||
import { enabledVisibilites } from 'mastodon/initial_state';
|
||||
|
||||
import { PrivacyDropdownMenu } from './privacy_dropdown_menu';
|
||||
|
||||
|
@ -42,6 +43,8 @@ const messages = defineMessages({
|
|||
reply_long: { id: 'privacy.reply.long', defaultMessage: 'Reply to limited post' },
|
||||
direct_short: { id: 'privacy.direct.short', defaultMessage: 'Specific people' },
|
||||
direct_long: { id: 'privacy.direct.long', defaultMessage: 'Everyone mentioned in the post' },
|
||||
banned_short: { id: 'privacy.banned.short', defaultMessage: 'No posting' },
|
||||
banned_long: { id: 'privacy.banned.long', defaultMessage: 'All public range submissions are disabled. User settings need to be modified.' },
|
||||
change_privacy: { id: 'privacy.change', defaultMessage: 'Change post privacy' },
|
||||
unlisted_extra: { id: 'privacy.unlisted.additional', defaultMessage: 'This behaves exactly like public, except the post will not appear in live feeds or hashtags, explore, or Mastodon search, even if you are opted-in account-wide.' },
|
||||
});
|
||||
|
@ -131,7 +134,12 @@ class PrivacyDropdown extends PureComponent {
|
|||
UNSAFE_componentWillMount () {
|
||||
const { intl: { formatMessage } } = this.props;
|
||||
|
||||
this.options = [
|
||||
this.dynamicOptions = [
|
||||
{ icon: 'reply', iconComponent: ReplyIcon, value: 'reply', text: formatMessage(messages.reply_short), meta: formatMessage(messages.reply_long), extra: formatMessage(messages.limited_short), extraIcomComponent: LimitedIcon },
|
||||
{ icon: 'ban', iconComponent: BlockIcon, value: 'banned', text: formatMessage(messages.banned_short), meta: formatMessage(messages.banned_long) },
|
||||
];
|
||||
|
||||
this.originalOptions = [
|
||||
{ icon: 'globe', iconComponent: PublicIcon, value: 'public', text: formatMessage(messages.public_short), meta: formatMessage(messages.public_long) },
|
||||
{ icon: 'cloud', iconComponent: PublicUnlistedIcon, value: 'public_unlisted', text: formatMessage(messages.public_unlisted_short), meta: formatMessage(messages.public_unlisted_long) },
|
||||
{ icon: 'key', iconComponent: LoginIcon, value: 'login', text: formatMessage(messages.login_short), meta: formatMessage(messages.login_long) },
|
||||
|
@ -139,31 +147,28 @@ class PrivacyDropdown extends PureComponent {
|
|||
{ icon: 'lock', iconComponent: LockIcon, value: 'private', text: formatMessage(messages.private_short), meta: formatMessage(messages.private_long) },
|
||||
{ icon: 'exchange', iconComponent: MutualIcon, value: 'mutual', text: formatMessage(messages.mutual_short), meta: formatMessage(messages.mutual_long), extra: formatMessage(messages.limited_short), extraIcomComponent: LimitedIcon },
|
||||
{ icon: 'user-circle', iconComponent: CircleIcon, value: 'circle', text: formatMessage(messages.circle_short), meta: formatMessage(messages.circle_long), extra: formatMessage(messages.limited_short), extraIcomComponent: LimitedIcon },
|
||||
{ icon: 'at', iconComponent: AlternateEmailIcon, value: 'direct', text: formatMessage(messages.direct_short), meta: formatMessage(messages.direct_long) },
|
||||
...this.dynamicOptions,
|
||||
];
|
||||
|
||||
if (!this.props.noDirect) {
|
||||
this.options.push(
|
||||
{ icon: 'at', iconComponent: AlternateEmailIcon, value: 'direct', text: formatMessage(messages.direct_short), meta: formatMessage(messages.direct_long) },
|
||||
);
|
||||
this.options = [...this.originalOptions];
|
||||
|
||||
if (this.props.noDirect) {
|
||||
this.options = this.options.filter((opt) => opt.value !== 'direct');
|
||||
}
|
||||
|
||||
if (this.props.noLimited) {
|
||||
this.options = this.options.filter((opt) => !['mutual', 'circle'].includes(opt.value));
|
||||
}
|
||||
|
||||
if (!enableLoginPrivacy) {
|
||||
this.options = this.options.filter((opt) => opt.value !== 'login');
|
||||
if (enabledVisibilites) {
|
||||
this.options = this.options.filter((opt) => enabledVisibilites.includes(opt.value));
|
||||
}
|
||||
|
||||
if (!enableLocalPrivacy) {
|
||||
this.options = this.options.filter((opt) => opt.value !== 'public_unlisted');
|
||||
if (this.options.length === 0) {
|
||||
this.options.push(this.dynamicOptions.find((opt) => opt.value === 'banned'));
|
||||
this.props.onChange('banned');
|
||||
}
|
||||
|
||||
if (!enablePublicPrivacy) {
|
||||
this.options = this.options.filter((opt) => opt.value !== 'public');
|
||||
}
|
||||
|
||||
this.selectableOptions = [...this.options];
|
||||
}
|
||||
|
||||
setTargetRef = c => {
|
||||
|
@ -183,18 +188,16 @@ class PrivacyDropdown extends PureComponent {
|
|||
const { open, placement } = this.state;
|
||||
|
||||
if (replyToLimited) {
|
||||
if (!this.selectableOptions.some((op) => op.value === 'reply')) {
|
||||
this.selectableOptions.unshift(
|
||||
{ icon: 'reply', iconComponent: ReplyIcon, value: 'reply', text: intl.formatMessage(messages.reply_short), meta: intl.formatMessage(messages.reply_long), extra: intl.formatMessage(messages.limited_short), extraIcomComponent: LimitedIcon },
|
||||
);
|
||||
if (!this.options.some((op) => op.value === 'reply')) {
|
||||
this.options.unshift(this.dynamicOptions.find((opt) => opt.value === 'reply'));
|
||||
}
|
||||
} else {
|
||||
if (this.selectableOptions.some((op) => op.value === 'reply')) {
|
||||
this.selectableOptions = this.selectableOptions.filter((op) => op.value !== 'reply');
|
||||
if (this.options.some((op) => op.value === 'reply')) {
|
||||
this.options = this.options.filter((op) => op.value !== 'reply');
|
||||
}
|
||||
}
|
||||
|
||||
const valueOption = this.selectableOptions.find(item => item.value === value) || this.selectableOptions[0];
|
||||
const valueOption = (disabled ? this.originalOptions : this.options).find(item => item.value === value) || this.options[0];
|
||||
|
||||
return (
|
||||
<div ref={this.setTargetRef} onKeyDown={this.handleKeyDown}>
|
||||
|
@ -217,7 +220,7 @@ class PrivacyDropdown extends PureComponent {
|
|||
<div {...props}>
|
||||
<div className={`dropdown-animation privacy-dropdown__dropdown ${placement}`}>
|
||||
<PrivacyDropdownMenu
|
||||
items={this.selectableOptions}
|
||||
items={this.options}
|
||||
value={value}
|
||||
onClose={this.handleClose}
|
||||
onChange={this.handleChange}
|
||||
|
|
|
@ -14,7 +14,7 @@ import LockIcon from '@/material-icons/400-24px/lock.svg?react';
|
|||
import LockOpenIcon from '@/material-icons/400-24px/no_encryption.svg?react';
|
||||
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { enableLocalPrivacy } from 'mastodon/initial_state';
|
||||
import { enabledVisibilites } from 'mastodon/initial_state';
|
||||
|
||||
|
||||
const messages = defineMessages({
|
||||
|
@ -236,7 +236,7 @@ class SearchabilityDropdown extends PureComponent {
|
|||
{ icon: 'at', iconComponent: AlternateEmailIcon, value: 'limited', text: formatMessage(messages.limited_short), meta: formatMessage(messages.limited_long) },
|
||||
];
|
||||
|
||||
if (!enableLocalPrivacy) {
|
||||
if (!enabledVisibilites.includes('public_unlisted')) {
|
||||
this.options = this.options.filter((opt) => opt.value !== 'public_unlisted');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,16 +32,14 @@
|
|||
* @property {boolean=} delete_modal
|
||||
* @property {boolean=} disable_swiping
|
||||
* @property {string=} disabled_account_id
|
||||
* @property {string[]} enabled_visibilities
|
||||
* @property {string} display_media
|
||||
* @property {boolean} display_media_expand
|
||||
* @property {string} domain
|
||||
* @property {string} dtl_tag
|
||||
* @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} enable_public_privacy
|
||||
* @property {boolean=} expand_spoilers
|
||||
* @property {string[]} featured_tags
|
||||
* @property {HideItemsDefinition[]} hide_items
|
||||
|
@ -121,15 +119,13 @@ export const boostModal = getMeta('boost_modal');
|
|||
export const deleteModal = getMeta('delete_modal');
|
||||
export const disableSwiping = getMeta('disable_swiping');
|
||||
export const disabledAccountId = getMeta('disabled_account_id');
|
||||
export const enabledVisibilites = getMeta('enabled_visibilities');
|
||||
export const displayMedia = getMeta('display_media');
|
||||
export const displayMediaExpand = getMeta('display_media_expand');
|
||||
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 enablePublicPrivacy = getMeta('enable_public_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');
|
||||
export const featuredTags = getMeta('featured_tags') || [];
|
||||
|
|
|
@ -712,6 +712,8 @@
|
|||
"poll.votes": "{votes, plural, one {# vote} other {# votes}}",
|
||||
"poll_button.add_poll": "Add a poll",
|
||||
"poll_button.remove_poll": "Remove poll",
|
||||
"privacy.banned.long": "All public range submissions are disabled. User settings need to be modified.",
|
||||
"privacy.banned.short": "No posting",
|
||||
"privacy.change": "Change post privacy",
|
||||
"privacy.circle.long": "Circle members only",
|
||||
"privacy.circle.short": "Circle",
|
||||
|
|
|
@ -696,6 +696,8 @@
|
|||
"poll.votes": "{votes}票",
|
||||
"poll_button.add_poll": "アンケートを追加",
|
||||
"poll_button.remove_poll": "アンケートを削除",
|
||||
"privacy.banned.long": "全ての公開範囲が、ユーザー設定により無効になっています",
|
||||
"privacy.banned.short": "投稿不可",
|
||||
"privacy.change": "公開範囲を変更",
|
||||
"privacy.circle.long": "サークルメンバーのみ閲覧可",
|
||||
"privacy.circle.short": "サークル (投稿時点)",
|
||||
|
|
|
@ -58,7 +58,7 @@ import {
|
|||
import { REDRAFT } from '../actions/statuses';
|
||||
import { STORE_HYDRATE } from '../actions/store';
|
||||
import { TIMELINE_DELETE } from '../actions/timelines';
|
||||
import { enableLocalPrivacy, enableLoginPrivacy, enablePublicPrivacy, me } from '../initial_state';
|
||||
import { enabledVisibilites, me } from '../initial_state';
|
||||
import { unescapeHTML } from '../utils/html';
|
||||
import { uuid } from '../uuid';
|
||||
|
||||
|
@ -143,9 +143,6 @@ function clearAll(state) {
|
|||
if (state.get('stay_privacy') && !state.get('in_reply_to')) {
|
||||
map.set('default_privacy', state.get('privacy'));
|
||||
}
|
||||
if ((map.get('privacy') === 'login' && !enableLoginPrivacy) || (map.get('privacy') === 'public_unlisted' && !enableLocalPrivacy)) {
|
||||
map.set('privacy', enablePublicPrivacy ? 'public' : 'unlisted');
|
||||
}
|
||||
if (!state.get('in_reply_to')) {
|
||||
map.set('posted_on_this_session', true);
|
||||
}
|
||||
|
@ -153,7 +150,7 @@ function clearAll(state) {
|
|||
map.set('limited_scope', null);
|
||||
map.set('id', null);
|
||||
map.set('in_reply_to', null);
|
||||
if (state.get('default_searchability') === 'public_unlisted' && !enableLocalPrivacy) {
|
||||
if (state.get('default_searchability') === 'public_unlisted' && !enabledVisibilites.includes('public_unlisted')) {
|
||||
map.set('searchability', 'public');
|
||||
} else {
|
||||
map.set('searchability', state.get('default_searchability'));
|
||||
|
@ -163,6 +160,7 @@ function clearAll(state) {
|
|||
map.update('media_attachments', list => list.clear());
|
||||
map.set('poll', null);
|
||||
map.set('idempotencyKey', uuid());
|
||||
normalizePrivacy(map);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -243,6 +241,22 @@ const sortHashtagsByUse = (state, tags) => {
|
|||
return sorted;
|
||||
};
|
||||
|
||||
const normalizePrivacy = (map, last) => {
|
||||
if (!enabledVisibilites) {
|
||||
return;
|
||||
}
|
||||
|
||||
const current = map.get('privacy');
|
||||
const invalid = !enabledVisibilites.includes(current);
|
||||
|
||||
if (invalid) {
|
||||
if (enabledVisibilites.length > 0) {
|
||||
const index = last ? enabledVisibilites.length - 1 : 0;
|
||||
map.set('privacy', enabledVisibilites[index]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const insertEmoji = (state, position, emojiData, needsSpace) => {
|
||||
const oldText = state.get('text');
|
||||
const emoji = needsSpace ? ' ' + emojiData.native : emojiData.native;
|
||||
|
@ -467,6 +481,8 @@ export default function compose(state = initialState, action) {
|
|||
map.set('spoiler', false);
|
||||
map.set('spoiler_text', '');
|
||||
}
|
||||
|
||||
normalizePrivacy(map);
|
||||
});
|
||||
case COMPOSE_SUBMIT_REQUEST:
|
||||
return state.set('is_submitting', true);
|
||||
|
@ -532,6 +548,7 @@ export default function compose(state = initialState, action) {
|
|||
return state.withMutations(map => {
|
||||
map.update('text', text => [text.trim(), `@${action.account.get('acct')} `].filter((str) => str.length !== 0).join(' '));
|
||||
map.set('privacy', 'direct');
|
||||
normalizePrivacy(map, true);
|
||||
map.set('focusDate', new Date());
|
||||
map.set('caretPosition', null);
|
||||
map.set('idempotencyKey', uuid());
|
||||
|
@ -584,6 +601,7 @@ export default function compose(state = initialState, action) {
|
|||
map.set('text', action.raw_text || unescapeHTML(expandMentions(action.status)));
|
||||
map.set('in_reply_to', action.status.get('in_reply_to_id'));
|
||||
map.set('privacy', action.status.get('visibility_ex'));
|
||||
normalizePrivacy(map);
|
||||
map.set('reply_to_limited', action.status.get('limited_scope') === 'reply');
|
||||
map.set('limited_scope', null);
|
||||
map.set('media_attachments', action.status.get('media_attachments').map((media) => media.set('unattached', true)));
|
||||
|
|
|
@ -105,13 +105,18 @@ code {
|
|||
|
||||
.overridden,
|
||||
.recommended,
|
||||
.not_recommended,
|
||||
.kmyblue {
|
||||
.not_recommended {
|
||||
position: absolute;
|
||||
margin: 0 4px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
.kmyblue {
|
||||
position: absolute;
|
||||
margin: 0 4px;
|
||||
margin-top: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
.row {
|
||||
|
|
|
@ -27,10 +27,6 @@ module User::HasSettings
|
|||
settings['reaction_deck']
|
||||
end
|
||||
|
||||
def setting_enable_login_privacy
|
||||
settings['web.enable_login_privacy']
|
||||
end
|
||||
|
||||
def setting_enable_dtl_menu
|
||||
settings['web.enable_dtl_menu']
|
||||
end
|
||||
|
@ -235,6 +231,14 @@ module User::HasSettings
|
|||
settings['default_reblog_privacy'] || 'unset'
|
||||
end
|
||||
|
||||
def setting_enabled_visibilities
|
||||
settings['enabled_visibilities']
|
||||
end
|
||||
|
||||
def setting_disabled_visibilities
|
||||
settings['disabled_visibilities']
|
||||
end
|
||||
|
||||
def setting_default_searchability
|
||||
settings['default_searchability'] || 'direct'
|
||||
end
|
||||
|
|
|
@ -497,7 +497,11 @@ class Status < ApplicationRecord
|
|||
|
||||
class << self
|
||||
def selectable_visibilities
|
||||
vs = visibilities.keys - %w(direct limited)
|
||||
selectable_all_visibilities - %w(mutual circle reply direct)
|
||||
end
|
||||
|
||||
def selectable_all_visibilities
|
||||
vs = %w(public public_unlisted login unlisted private mutual circle reply direct)
|
||||
vs -= %w(public_unlisted) unless Setting.enable_public_unlisted_visibility
|
||||
vs -= %w(public) unless Setting.enable_public_visibility
|
||||
vs
|
||||
|
|
|
@ -23,6 +23,7 @@ class UserSettings
|
|||
setting :default_privacy, default: nil, in: %w(public public_unlisted login unlisted private)
|
||||
setting :stay_privacy, default: false
|
||||
setting :default_reblog_privacy, default: nil
|
||||
setting :disabled_visibilities, default: %w()
|
||||
setting :default_searchability, default: :direct, in: %w(public private direct limited public_unlisted)
|
||||
setting :default_searchability_of_search, default: :public, in: %w(public private direct limited)
|
||||
setting :use_public_index, default: true
|
||||
|
@ -47,6 +48,7 @@ class UserSettings
|
|||
setting_inverse_alias :show_statuses_count, :hide_statuses_count
|
||||
setting_inverse_alias :show_following_count, :hide_following_count
|
||||
setting_inverse_alias :show_followers_count, :hide_followers_count
|
||||
setting_inverse_array :enabled_visibilities, :disabled_visibilities, %w(public public_unlisted login unlisted private mutual circle reply personal direct)
|
||||
|
||||
namespace :web do
|
||||
setting :advanced_layout, default: false
|
||||
|
@ -57,7 +59,6 @@ class UserSettings
|
|||
setting :bookmark_category_needed, default: false
|
||||
setting :disable_swiping, default: false
|
||||
setting :delete_modal, default: true
|
||||
setting :enable_login_privacy, default: false
|
||||
setting :enable_dtl_menu, default: false
|
||||
setting :hide_recent_emojis, default: false
|
||||
setting :enable_emoji_reaction, default: true
|
||||
|
|
|
@ -14,6 +14,10 @@ module UserSettings::DSL
|
|||
@definitions[key] = @definitions[original_key].inverse_of(key)
|
||||
end
|
||||
|
||||
def setting_inverse_array(key, original_key, reverse_array)
|
||||
@definitions[key] = @definitions[original_key].array_inverse_of(key, reverse_array)
|
||||
end
|
||||
|
||||
def namespace(key, &block)
|
||||
@definitions ||= {}
|
||||
|
||||
|
|
|
@ -22,4 +22,8 @@ class UserSettings::Namespace
|
|||
def setting_inverse_alias(key, original_key)
|
||||
@definitions[key] = @definitions[original_key].inverse_of(key)
|
||||
end
|
||||
|
||||
def setting_inverse_array(key, original_key, reverse_array)
|
||||
@definitions[key] = @definitions[original_key].array_inverse_of(key, reverse_array)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,6 +15,12 @@ class UserSettings::Setting
|
|||
self
|
||||
end
|
||||
|
||||
def array_inverse_of(name, arr)
|
||||
@inverse_of_array = name.to_sym
|
||||
@reverse_array = arr
|
||||
self
|
||||
end
|
||||
|
||||
def value_for(name, original_value)
|
||||
value = begin
|
||||
if original_value.nil?
|
||||
|
@ -24,13 +30,21 @@ class UserSettings::Setting
|
|||
end
|
||||
end
|
||||
|
||||
value = value.compact_blank if value.is_a?(Array)
|
||||
|
||||
if !@inverse_of.nil? && @inverse_of == name.to_sym
|
||||
!value
|
||||
elsif !@inverse_of_array.nil? && @inverse_of_array == name.to_sym
|
||||
reverse_array(value)
|
||||
else
|
||||
value
|
||||
end
|
||||
end
|
||||
|
||||
def reverse_array(value)
|
||||
@reverse_array.clone.filter { |v| value.exclude?(v) }
|
||||
end
|
||||
|
||||
def default_value
|
||||
if @default_value.respond_to?(:call)
|
||||
@default_value.call
|
||||
|
@ -39,7 +53,13 @@ class UserSettings::Setting
|
|||
end
|
||||
end
|
||||
|
||||
def array_type?
|
||||
default_value.is_a?(Array) || default_value == []
|
||||
end
|
||||
|
||||
def type
|
||||
return ActiveRecord::Type.lookup(:string, array: true) if array_type?
|
||||
|
||||
case default_value
|
||||
when TrueClass, FalseClass
|
||||
ActiveModel::Type::Boolean.new
|
||||
|
|
|
@ -26,7 +26,6 @@ class InitialStateSerializer < ActiveModel::Serializer
|
|||
store[:display_media_expand] = object_account_user.setting_display_media_expand
|
||||
store[:expand_spoilers] = object_account_user.setting_expand_spoilers
|
||||
store[:enable_emoji_reaction] = object_account_user.setting_enable_emoji_reaction && Setting.enable_emoji_reaction
|
||||
store[:enable_login_privacy] = object_account_user.setting_enable_login_privacy
|
||||
store[:enable_dtl_menu] = object_account_user.setting_enable_dtl_menu
|
||||
store[:reduce_motion] = object_account_user.setting_reduce_motion
|
||||
store[:disable_swiping] = object_account_user.setting_disable_swiping
|
||||
|
@ -50,6 +49,7 @@ class InitialStateSerializer < ActiveModel::Serializer
|
|||
object_account_user.setting_show_quote_in_public ? nil : 'quote_in_public',
|
||||
object_account_user.setting_show_relationships ? nil : 'relationships',
|
||||
].compact
|
||||
store[:enabled_visibilities] = enabled_visibilities
|
||||
store[:featured_tags] = object.current_account.featured_tags.pluck(:name)
|
||||
else
|
||||
store[:auto_play_gif] = Setting.auto_play_gif
|
||||
|
@ -112,6 +112,13 @@ class InitialStateSerializer < ActiveModel::Serializer
|
|||
LanguagesHelper::SUPPORTED_LOCALES.map { |(key, value)| [key, value[0], value[1]] }
|
||||
end
|
||||
|
||||
def enabled_visibilities
|
||||
vs = object_account_user.setting_enabled_visibilities
|
||||
vs -= %w(public_unlisted) unless Setting.enable_public_unlisted_visibility
|
||||
vs -= %w(public) unless Setting.enable_public_visibility
|
||||
vs
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def default_meta_store
|
||||
|
@ -121,8 +128,6 @@ class InitialStateSerializer < ActiveModel::Serializer
|
|||
admin: object.admin&.id&.to_s,
|
||||
domain: Addressable::IDNA.to_unicode(instance_presenter.domain),
|
||||
dtl_tag: dtl_enabled? ? dtl_tag_name : nil,
|
||||
enable_local_privacy: Setting.enable_public_unlisted_visibility,
|
||||
enable_public_privacy: Setting.enable_public_visibility,
|
||||
enable_local_timeline: Setting.enable_local_timeline,
|
||||
limited_federation_mode: Rails.configuration.x.limited_federation_mode,
|
||||
locale: I18n.locale,
|
||||
|
|
|
@ -71,11 +71,7 @@ class PostStatusService < BaseService
|
|||
def preprocess_attributes!
|
||||
@sensitive = (@options[:sensitive].nil? ? @account.user&.setting_default_sensitive : @options[:sensitive]) || @options[:spoiler_text].present?
|
||||
@text = @options.delete(:spoiler_text) if @text.blank? && @options[:spoiler_text].present?
|
||||
@visibility = @options[:visibility]&.to_sym || @account.user&.setting_default_privacy&.to_sym
|
||||
@visibility = :limited if %w(mutual circle reply).include?(@options[:visibility])
|
||||
@visibility = :unlisted if (@visibility == :public || @visibility == :public_unlisted || @visibility == :login) && @account.silenced?
|
||||
@visibility = :public_unlisted if @visibility == :public && !@options[:force_visibility] && !@options[:application]&.superapp && @account.user&.setting_public_post_to_unlisted && Setting.enable_public_unlisted_visibility
|
||||
@visibility = Setting.enable_public_unlisted_visibility ? :public_unlisted : :unlisted if !Setting.enable_public_visibility && @visibility == :public
|
||||
@visibility = visibility
|
||||
@limited_scope = @options[:visibility]&.to_sym if @visibility == :limited && @options[:visibility] != 'limited'
|
||||
@searchability = searchability
|
||||
@searchability = :private if @account.silenced? && %i(public public_unlisted).include?(@searchability&.to_sym)
|
||||
|
@ -84,6 +80,7 @@ class PostStatusService < BaseService
|
|||
@scheduled_at = nil if scheduled_in_the_past?
|
||||
@reference_ids = (@options[:status_reference_ids] || []).map(&:to_i).filter(&:positive?)
|
||||
raise ArgumentError if !Setting.enable_public_unlisted_visibility && (@visibility == :public_unlisted || @searchability == :public_unlisted)
|
||||
raise ArgumentError if @account.user&.setting_disabled_visibilities&.include?((@limited_scope || @visibility).to_s)
|
||||
|
||||
if @in_reply_to.present? && ((@options[:visibility] == 'limited' && @options[:circle_id].nil?) || @limited_scope == :reply)
|
||||
@visibility = :limited
|
||||
|
@ -97,6 +94,15 @@ class PostStatusService < BaseService
|
|||
raise ActiveRecord::RecordInvalid
|
||||
end
|
||||
|
||||
def visibility
|
||||
v = @options[:visibility]&.to_sym || @account.user&.setting_default_privacy&.to_sym
|
||||
v = :limited if %w(mutual circle reply).include?(@options[:visibility])
|
||||
v = :unlisted if %i(public public_unlisted login).include?(v) && @account.silenced?
|
||||
v = :public_unlisted if v == :public && !@options[:force_visibility] && !@options[:application]&.superapp && @account.user&.setting_public_post_to_unlisted && Setting.enable_public_unlisted_visibility
|
||||
v = Setting.enable_public_unlisted_visibility ? :public_unlisted : :unlisted if !Setting.enable_public_visibility && v == :public
|
||||
v
|
||||
end
|
||||
|
||||
def load_circle
|
||||
return if @visibility == :limited && @limited_scope == :reply && @in_reply_to.present?
|
||||
return unless %w(circle limited reply).include?(@options[:visibility])
|
||||
|
|
|
@ -40,7 +40,18 @@
|
|||
= ff.input :public_post_to_unlisted, wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_public_post_to_unlisted'), hint: I18n.t('simple_form.hints.defaults.setting_public_post_to_unlisted')
|
||||
|
||||
.fields-group
|
||||
= ff.input :'web.enable_login_privacy', wrapper: :with_label, kmyblue: true, label: I18n.t('simple_form.labels.defaults.setting_enable_login_privacy'), hint: false
|
||||
= ff.input :enabled_visibilities,
|
||||
as: :check_boxes,
|
||||
collection_wrapper_tag: 'ul',
|
||||
collection: Status.selectable_all_visibilities,
|
||||
hint: I18n.t('simple_form.hints.defaults.setting_enabled_visibilities'),
|
||||
include_blank: false,
|
||||
item_wrapper_tag: 'li',
|
||||
kmyblue: true,
|
||||
label: I18n.t('simple_form.labels.defaults.setting_enabled_visibilities'),
|
||||
label_method: ->(visibility) { I18n.t("statuses.visibilities.#{visibility}") },
|
||||
required: false,
|
||||
wrapper: :with_block_label
|
||||
|
||||
%h4= t 'preferences.searchability'
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue