Skip to content

Commit

Permalink
Add: #483 特定の公開範囲を無効にするオプション
Browse files Browse the repository at this point in the history
  • Loading branch information
kmycode committed Apr 17, 2024
1 parent 1c054ed commit dac00b1
Show file tree
Hide file tree
Showing 20 changed files with 137 additions and 41 deletions.
10 changes: 10 additions & 0 deletions app/controllers/settings/preferences/base_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@ def after_update_redirect_path
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
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,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';

Expand Down Expand Up @@ -151,16 +151,14 @@ class PrivacyDropdown extends PureComponent {
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 (!enablePublicPrivacy) {
this.options = this.options.filter((opt) => opt.value !== 'public');
if (this.options.length === 0) {
this.options.push(
{ icon: 'at', iconComponent: AlternateEmailIcon, value: 'direct', text: formatMessage(messages.direct_short), meta: formatMessage(messages.direct_long) },
);
}

this.selectableOptions = [...this.options];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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({
Expand Down Expand Up @@ -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');
}
}
Expand Down
8 changes: 2 additions & 6 deletions app/javascript/mastodon/initial_state.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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') || [];
Expand Down
29 changes: 24 additions & 5 deletions app/javascript/mastodon/reducers/compose.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -143,17 +143,14 @@ 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);
}
map.set('reply_to_limited', false);
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'));
Expand All @@ -163,6 +160,7 @@ function clearAll(state) {
map.update('media_attachments', list => list.clear());
map.set('poll', null);
map.set('idempotencyKey', uuid());
normalizePrivacy(map);
});
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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());
Expand Down Expand Up @@ -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)));
Expand Down Expand Up @@ -621,6 +639,7 @@ export default function compose(state = initialState, action) {
} else {
map.set('privacy', action.status.get('limited_scope') || 'circle');
}
normalizePrivacy(map);
map.set('reply_to_limited', action.status.get('limited_scope') === 'reply');
map.set('limited_scope', action.status.get('limited_scope'));
map.set('media_attachments', action.status.get('media_attachments'));
Expand Down
9 changes: 7 additions & 2 deletions app/javascript/styles/mastodon/forms.scss
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
12 changes: 8 additions & 4 deletions app/models/concerns/user/has_settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ def setting_reaction_deck
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
Expand Down Expand Up @@ -235,6 +231,14 @@ def setting_default_reblog_privacy
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
Expand Down
6 changes: 5 additions & 1 deletion app/models/status.rb
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,11 @@ def searchable_visibility

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
Expand Down
3 changes: 2 additions & 1 deletion app/models/user_settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class KeyError < Error; end
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
Expand All @@ -47,6 +48,7 @@ class KeyError < Error; end
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
Expand All @@ -57,7 +59,6 @@ class KeyError < Error; end
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
Expand Down
4 changes: 4 additions & 0 deletions app/models/user_settings/dsl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ 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

def namespace(key, &block)
@definitions ||= {}

Expand Down
4 changes: 4 additions & 0 deletions app/models/user_settings/namespace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ def setting(key, options = {})
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
20 changes: 20 additions & 0 deletions app/models/user_settings/setting.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ def inverse_of(name)
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?
Expand All @@ -24,13 +30,21 @@ def value_for(name, original_value)
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
Expand All @@ -39,7 +53,13 @@ def default_value
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
Expand Down
11 changes: 8 additions & 3 deletions app/serializers/initial_state_serializer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ def meta
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
Expand All @@ -50,6 +49,7 @@ def meta
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
Expand Down Expand Up @@ -112,6 +112,13 @@ def languages
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
Expand All @@ -121,8 +128,6 @@ def default_meta_store
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,
Expand Down
Loading

0 comments on commit dac00b1

Please sign in to comment.