Add default expires date setting
This commit is contained in:
parent
695f9a7d08
commit
dc138ccb32
11 changed files with 77 additions and 23 deletions
|
@ -20,6 +20,7 @@ class Api::V1::StatusesController < Api::BaseController
|
|||
# conversations as quasi-unlimited, it would be too much work to render more
|
||||
# than this anyway
|
||||
CONTEXT_LIMIT = 4_096
|
||||
DURATION_RE = /^(?:(?<year>\d+)y)?(?:(?<month>\d+)m(?=[\do])o?)?(?:(?<day>\d+)d)?(?:(?<hour>\d+)h)?(?:(?<minute>\d+)m)?$/
|
||||
|
||||
def index
|
||||
@statuses = cache_collection(@statuses, Status)
|
||||
|
@ -128,7 +129,18 @@ class Api::V1::StatusesController < Api::BaseController
|
|||
end
|
||||
|
||||
def set_expire
|
||||
@expires_at = status_params[:expires_at] || (status_params[:expires_in].blank? ? nil : (@scheduled_at || Time.now.utc) + status_params[:expires_in].to_i.seconds)
|
||||
expires_in =
|
||||
if status_params.has_key?(:expires_in)
|
||||
status_params[:expires_in].blank? ? nil : status_params[:expires_in].to_i.seconds
|
||||
elsif (match = current_user.setting_default_expires_in.match(DURATION_RE))
|
||||
year, month, day, hour, minute = match.to_a.values_at(1,2,3,4,5).map(&:to_i)
|
||||
seconds = (year.years + month.months + day.days + hour.hours + minute.minutes).to_i.seconds
|
||||
seconds < 1.minutes ? nil : seconds
|
||||
else
|
||||
nil
|
||||
end
|
||||
|
||||
@expires_at = status_params[:expires_at] || (expires_in.nil? ? nil : (@scheduled_at || Time.now.utc) + expires_in)
|
||||
end
|
||||
|
||||
def status_ids
|
||||
|
|
|
@ -97,6 +97,8 @@ class Settings::PreferencesController < Settings::BaseController
|
|||
:setting_show_reload_button,
|
||||
:setting_default_column_width,
|
||||
:setting_confirm_domain_block,
|
||||
:setting_default_expires_in,
|
||||
:setting_default_expires_action,
|
||||
notification_emails: %i(follow follow_request reblog favourite emoji_reaction status_reference mention digest report pending_account trending_tag),
|
||||
interactions: %i(must_be_follower must_be_following must_be_following_dm must_be_dm_to_send_email must_be_following_reference)
|
||||
)
|
||||
|
|
|
@ -213,7 +213,7 @@
|
|||
"datetime_button.add_datetime": "日時を追加",
|
||||
"datetime_button.remove_datetime": "日時を削除",
|
||||
"datetime.expires": "終了日時",
|
||||
"datetime.expires_action.mark": "保持",
|
||||
"datetime.expires_action.mark": "期限切れマーク",
|
||||
"datetime.expires_action.delete": "削除",
|
||||
"datetime.open_calendar": "カレンダーを開く",
|
||||
"datetime.placeholder": "日付か期間を入力",
|
||||
|
|
|
@ -160,10 +160,10 @@ const clearAll = state => {
|
|||
map.update('media_attachments', list => list.clear());
|
||||
map.set('poll', null);
|
||||
map.set('idempotencyKey', uuid());
|
||||
map.set('datetime_form', null);
|
||||
map.set('datetime_form', state.get('default_expires_in') ? true : null);
|
||||
map.set('scheduled', null);
|
||||
map.set('expires', null);
|
||||
map.set('expires_action', 'mark');
|
||||
map.set('expires', state.get('default_expires_in', null));
|
||||
map.set('expires_action', state.get('default_expires_action', 'mark'));
|
||||
map.update('references', set => set.clear());
|
||||
map.update('context_references', set => set.clear());
|
||||
});
|
||||
|
@ -410,10 +410,10 @@ export default function compose(state = initialState, action) {
|
|||
map.set('caretPosition', null);
|
||||
map.set('preselectDate', new Date());
|
||||
map.set('idempotencyKey', uuid());
|
||||
map.set('datetime_form', null);
|
||||
map.set('datetime_form', state.get('default_expires_in') ? true : null);
|
||||
map.set('scheduled', null);
|
||||
map.set('expires', null);
|
||||
map.set('expires_action', 'mark');
|
||||
map.set('expires', state.get('default_expires_in', null));
|
||||
map.set('expires_action', state.get('default_expires_action', 'mark'));
|
||||
map.update('context_references', set => set.clear().concat(action.context_references));
|
||||
|
||||
if (action.status.get('spoiler_text').length > 0) {
|
||||
|
@ -438,10 +438,10 @@ export default function compose(state = initialState, action) {
|
|||
map.set('focusDate', new Date());
|
||||
map.set('preselectDate', new Date());
|
||||
map.set('idempotencyKey', uuid());
|
||||
map.set('datetime_form', null);
|
||||
map.set('datetime_form', state.get('default_expires_in') ? true : null);
|
||||
map.set('scheduled', null);
|
||||
map.set('expires', null);
|
||||
map.set('expires_action', 'mark');
|
||||
map.set('expires', state.get('default_expires_in', null));
|
||||
map.set('expires_action', state.get('default_expires_action', 'mark'));
|
||||
map.update('context_references', set => set.clear().add(action.status.get('id')));
|
||||
|
||||
if (action.status.get('spoiler_text').length > 0) {
|
||||
|
@ -468,10 +468,10 @@ export default function compose(state = initialState, action) {
|
|||
map.set('circle_id', null);
|
||||
map.set('poll', null);
|
||||
map.set('idempotencyKey', uuid());
|
||||
map.set('datetime_form', null);
|
||||
map.set('datetime_form', state.get('default_expires_in') ? true : null);
|
||||
map.set('scheduled', null);
|
||||
map.set('expires', null);
|
||||
map.set('expires_action', 'mark');
|
||||
map.set('expires', state.get('default_expires_in', null));
|
||||
map.set('expires_action', state.get('default_expires_action', 'mark'));
|
||||
map.update('context_references', set => set.clear());
|
||||
if (action.type == COMPOSE_RESET) {
|
||||
map.update('references', set => set.clear());
|
||||
|
@ -575,6 +575,8 @@ export default function compose(state = initialState, action) {
|
|||
}));
|
||||
case REDRAFT:
|
||||
return state.withMutations(map => {
|
||||
const default_expires_in_exist = state.get('default_expires_in') ? true : null;
|
||||
|
||||
map.set('text', action.raw_text || unescapeHTML(rejectQuoteAltText(expandMentions(action.status))));
|
||||
map.set('in_reply_to', action.status.get('in_reply_to_id'));
|
||||
map.set('quote_from', action.status.getIn(['quote', 'id']));
|
||||
|
@ -588,10 +590,10 @@ export default function compose(state = initialState, action) {
|
|||
map.set('caretPosition', null);
|
||||
map.set('idempotencyKey', uuid());
|
||||
map.set('sensitive', action.status.get('sensitive'));
|
||||
map.set('datetime_form', !!action.status.get('scheduled_at') || !!action.status.get('expires_at') ? true : null);
|
||||
map.set('datetime_form', !!action.status.get('scheduled_at') || !!action.status.get('expires_at') ? true : default_expires_in_exist);
|
||||
map.set('scheduled', action.status.get('scheduled_at'));
|
||||
map.set('expires', action.status.get('expires_at') ? format(parseISO(action.status.get('expires_at')), 'yyyy-MM-dd HH:mm') : null);
|
||||
map.set('expires_action', action.status.get('expires_action') ?? 'mark');
|
||||
map.set('expires', action.status.get('expires_at') ? format(parseISO(action.status.get('expires_at')), 'yyyy-MM-dd HH:mm') : state.get('default_expires_in', null));
|
||||
map.set('expires_action', action.status.get('expires_action') ?? state.get('default_expires_action', 'mark'));
|
||||
map.update('references', set => set.clear().concat(action.status.get('status_reference_ids')));
|
||||
map.update('context_references', set => set.clear().concat(action.context_references));
|
||||
|
||||
|
|
|
@ -91,7 +91,9 @@ class UserSettingsDecorator
|
|||
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
|
||||
user.settings['default_expires_in'] = default_expires_in_preference if change?('setting_default_expires_in')
|
||||
user.settings['default_expires_action'] = default_expires_action_preference if change?('setting_default_expires_action')
|
||||
end
|
||||
|
||||
def merged_notification_emails
|
||||
user.settings['notification_emails'].merge coerced_settings('notification_emails').to_h
|
||||
|
@ -341,6 +343,14 @@ class UserSettingsDecorator
|
|||
settings['setting_default_column_width']
|
||||
end
|
||||
|
||||
def default_expires_in_preference
|
||||
settings['setting_default_expires_in']
|
||||
end
|
||||
|
||||
def default_expires_action_preference
|
||||
settings['setting_default_expires_action']
|
||||
end
|
||||
|
||||
def boolean_cast_setting(key)
|
||||
ActiveModel::Type::Boolean.new.cast(settings[key])
|
||||
end
|
||||
|
|
|
@ -141,7 +141,7 @@ class User < ApplicationRecord
|
|||
:multi_column_customize, :multi_column_content_font_size, :multi_column_info_font_size, :multi_column_content_emoji_reaction_size,
|
||||
: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,
|
||||
:default_search_searchability, :default_expires_in, :default_expires_action,
|
||||
:show_reload_button, :default_column_width,
|
||||
|
||||
to: :settings, prefix: :setting, allow_nil: false
|
||||
|
|
|
@ -89,10 +89,12 @@ class InitialStateSerializer < ActiveModel::Serializer
|
|||
store = {}
|
||||
|
||||
if object.current_account
|
||||
store[:me] = object.current_account.id.to_s
|
||||
store[:default_privacy] = object.visibility || object.current_account.user.setting_default_privacy
|
||||
store[:default_searchability] = object.current_account.searchability
|
||||
store[:default_sensitive] = object.current_account.user.setting_default_sensitive
|
||||
store[:me] = object.current_account.id.to_s
|
||||
store[:default_privacy] = object.visibility || object.current_account.user.setting_default_privacy
|
||||
store[:default_searchability] = object.current_account.searchability
|
||||
store[:default_sensitive] = object.current_account.user.setting_default_sensitive
|
||||
store[:default_expires_in] = object.current_account.user.setting_default_expires_in
|
||||
store[:default_expires_action] = object.current_account.user.setting_default_expires_action
|
||||
end
|
||||
|
||||
store[:text] = object.text if object.text
|
||||
|
|
|
@ -40,6 +40,14 @@
|
|||
.fields-group
|
||||
= f.input :setting_show_application, as: :boolean, wrapper: :with_label, recommended: true
|
||||
|
||||
.fields-row
|
||||
.fields-group.fields-row__column.fields-row__column-6
|
||||
= f.input :setting_default_expires_in, wrapper: :with_label, input_html: { maxlength: 30, pattern: '^(?:(\d+)y)?(?:(\d+)m(?=[\do])o?)?(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?$' }, fedibird_features: true
|
||||
|
||||
.fields-group.fields-row__column.fields-row__column-6
|
||||
%span.fedibird_features.float Fedibird
|
||||
= f.input :setting_default_expires_action, collection: ['mark', 'delete'], label_method: lambda { |item| t("simple_form.labels.defaults.setting_default_expires_action_#{item}") }, hint: t("simple_form.hints.defaults.setting_default_expires_action"), as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', wrapper: :with_floating_label
|
||||
|
||||
%h4= t 'preferences.searching_defaults'
|
||||
|
||||
.fields-group
|
||||
|
|
|
@ -62,6 +62,12 @@ en:
|
|||
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_expires_action: |
|
||||
Submissions whose publication period has ended will be marked or deleted.
|
||||
Marked posts will no longer be visible, but only the poster and those who reacted (favourite, emoji reaction, bookmark) to the post will be able to see it.
|
||||
setting_default_expires_in: |
|
||||
Specify the end date and time as the starting point of the posting date and time.
|
||||
The format is 1y2mo3d4h5m (1 year, 2 months, 3 days, 4 hours, 5 minutes later).
|
||||
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
|
||||
|
@ -226,6 +232,10 @@ en:
|
|||
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_expires_action: Default expiry action
|
||||
setting_default_expires_action_mark: Mark as expired
|
||||
setting_default_expires_action_delete: Delete
|
||||
setting_default_expires_in: Default expiry duration
|
||||
setting_default_language: Posting language
|
||||
setting_default_privacy: Posting privacy
|
||||
setting_default_search_searchability: Search range
|
||||
|
|
|
@ -62,6 +62,8 @@ ja:
|
|||
setting_default_column_width_x100: 100% - Mastodon標準のカラム幅に固定します
|
||||
setting_default_column_width_x125: 125% - 標準の125%の幅に固定します
|
||||
setting_default_column_width_x150: 150% - 標準の150%の幅に固定します
|
||||
setting_default_expires_action: 公開期間が終了した投稿には、マークが付けられるか、削除されます。マークされた投稿は見えなくなり、投稿者とその投稿に反応(お気に入り・絵文字リアクション・ブックマーク)した人だけが見ることができるようになります。
|
||||
setting_default_expires_in: 投稿日時を起点とする終了日時を指定します。書式は1y2mo3d4h5m(1年2ヶ月3日4時間5分後)です。
|
||||
setting_default_search_searchability: 範囲の詳細設定に対応していないクライアントでは、ここで設定を切り替えてください。Mastodonの標準動作は『リアクション限定』です。『公開』を対象にすると未知の情報を発見しやすくなりますが、結果にノイズが多い場合は検索範囲を狭めると効果的です。
|
||||
setting_default_sensitive: 閲覧注意状態のメディアはデフォルトでは内容が伏せられ、クリックして初めて閲覧できるようになります
|
||||
setting_disable_joke_appearance: エイプリルフール等のジョーク機能を無効にします
|
||||
|
@ -226,6 +228,10 @@ ja:
|
|||
setting_content_font_size: 投稿のフォントサイズ
|
||||
setting_crop_images: 投稿の詳細以外では画像を16:9に切り抜く
|
||||
setting_default_column_width: デフォルトのカラム幅
|
||||
setting_default_expires_action: デフォルトの終了時アクション
|
||||
setting_default_expires_action_mark: 期限切れマーク
|
||||
setting_default_expires_action_delete: 削除
|
||||
setting_default_expires_in: デフォルトの終了日時
|
||||
setting_default_language: 投稿する言語
|
||||
setting_default_privacy: 投稿の公開範囲
|
||||
setting_default_search_searchability: 検索の対象とする範囲
|
||||
|
|
|
@ -112,6 +112,8 @@ defaults: &defaults
|
|||
default_search_searchability: 'private'
|
||||
show_reload_button: true
|
||||
default_column_width: 'x100'
|
||||
default_expires_in: ''
|
||||
default_expires_action: 'mark'
|
||||
|
||||
development:
|
||||
<<: *defaults
|
||||
|
|
Loading…
Reference in a new issue