:setting_aggregate_reblogs,
:setting_show_application,
:setting_advanced_layout,
+ :setting_default_content_type,
notification_emails: %i(follow follow_request reblog favourite mention digest report pending_account),
- interactions: %i(must_be_follower must_be_following)
+ interactions: %i(must_be_follower must_be_following must_be_following_dm)
)
end
end
--- /dev/null
- delegate(document, '.status__content__spoiler-link', 'click', ({ target }) => {
- const contentEl = target.parentNode.parentNode.querySelector('.e-content');
+// This file will be loaded on public pages, regardless of theme.
+
+import createHistory from 'history/createBrowserHistory';
+import ready from '../mastodon/ready';
+
+const { delegate } = require('rails-ujs');
+const { length } = require('stringz');
+
+delegate(document, '.webapp-btn', 'click', ({ target, button }) => {
+ if (button !== 0) {
+ return true;
+ }
+ window.location.href = target.href;
+ return false;
+});
+
- target.parentNode.style.marginBottom = 0;
++delegate(document, '.status__content__spoiler-link', 'click', function() {
++ const contentEl = this.parentNode.parentNode.querySelector('.e-content');
+
+ if (contentEl.style.display === 'block') {
+ contentEl.style.display = 'none';
- target.parentNode.style.marginBottom = null;
++ this.parentNode.style.marginBottom = 0;
+ } else {
+ contentEl.style.display = 'block';
++ this.parentNode.style.marginBottom = null;
+ }
+
+ return false;
+});
+
+delegate(document, '.modal-button', 'click', e => {
+ e.preventDefault();
+
+ let href;
+
+ if (e.target.nodeName !== 'A') {
+ href = e.target.parentNode.href;
+ } else {
+ href = e.target.href;
+ }
+
+ window.open(href, 'mastodon-intent', 'width=445,height=600,resizable=no,menubar=no,status=no,scrollbars=yes');
+});
+
+const getProfileAvatarAnimationHandler = (swapTo) => {
+ //animate avatar gifs on the profile page when moused over
+ return ({ target }) => {
+ const swapSrc = target.getAttribute(swapTo);
+ //only change the img source if autoplay is off and the image src is actually different
+ if(target.getAttribute('data-autoplay') === 'false' && target.src !== swapSrc) {
+ target.src = swapSrc;
+ }
+ };
+};
+
+delegate(document, 'img#profile_page_avatar', 'mouseover', getProfileAvatarAnimationHandler('data-original'));
+
+delegate(document, 'img#profile_page_avatar', 'mouseout', getProfileAvatarAnimationHandler('data-static'));
+
+delegate(document, '#account_header', 'change', ({ target }) => {
+ const header = document.querySelector('.card .card__img img');
+ const [file] = target.files || [];
+ const url = file ? URL.createObjectURL(file) : header.dataset.originalSrc;
+
+ header.src = url;
+});
"navigation_bar.personal": "個人用",
"navigation_bar.pins": "固定したトゥート",
"navigation_bar.preferences": "ユーザー設定",
+ "navigation_bar.profile_directory": "Profile directory",
"navigation_bar.public_timeline": "連合タイムライン",
+ "navigation_bar.misc": "その他",
"navigation_bar.security": "セキュリティ",
"notification.favourite": "{name}さんがあなたのトゥートをお気に入りに登録しました",
"notification.follow": "{name}さんにフォローされました",
--- /dev/null
- .fields-row
- .fields-group.fields-row__column.fields-row__column-6
- = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, selected: I18n.locale, hint: false
- .fields-group.fields-row__column.fields-row__column-6
- = f.input :setting_theme, collection: Themes.instance.names, label_method: lambda { |theme| I18n.t("themes.#{theme}", default: theme) }, wrapper: :with_label, include_blank: false, hint: false
+ - content_for :page_title do
+ = t('settings.appearance')
+
+ = simple_form_for current_user, url: settings_preferences_appearance_path, html: { method: :put } do |f|
++ .fields-group
++ = f.input :locale, collection: I18n.available_locales, wrapper: :with_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, selected: I18n.locale, hint: false
+
+ %h4= t 'appearance.advanced_web_interface'
+
+ %p.hint= t 'appearance.advanced_web_interface_hint'
+
+ .fields-group
+ = f.input :setting_advanced_layout, as: :boolean, wrapper: :with_label, hint: false
+
+ %h4= t 'appearance.animations_and_accessibility'
+
+ .fields-group
+ = f.input :setting_auto_play_gif, as: :boolean, wrapper: :with_label, recommended: true
+ = f.input :setting_reduce_motion, as: :boolean, wrapper: :with_label
+ = f.input :setting_system_font_ui, as: :boolean, wrapper: :with_label
+
+ %h4= t 'appearance.confirmation_dialogs'
+
+ .fields-group
+ = f.input :setting_unfollow_modal, as: :boolean, wrapper: :with_label
+ = f.input :setting_boost_modal, as: :boolean, wrapper: :with_label
++ = f.input :setting_favourite_modal, as: :boolean, wrapper: :with_label
+ = f.input :setting_delete_modal, as: :boolean, wrapper: :with_label
+
+ %h4= t 'appearance.sensitive_content'
+
+ .fields-group
+ = f.input :setting_display_media, collection: ['default', 'show_all', 'hide_all'],label_method: lambda { |item| t("simple_form.hints.defaults.setting_display_media_#{item}") }, hint: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li', wrapper: :with_floating_label
+
+ .fields-group
+ = f.input :setting_expand_spoilers, as: :boolean, wrapper: :with_label
+
+ .actions
+ = f.button :button, t('generic.save_changes'), type: :submit
--- /dev/null
+ - content_for :page_title do
+ = t('settings.preferences')
+
+ = simple_form_for current_user, url: settings_preferences_path, html: { method: :put } do |f|
+ = render 'shared/error_messages', object: current_user
+
+ .fields-group
+ = f.input :setting_noindex, as: :boolean, wrapper: :with_label
+
+ .fields-group
+ = f.input :setting_hide_network, as: :boolean, wrapper: :with_label
+
+ .fields-group
+ = f.input :setting_aggregate_reblogs, as: :boolean, wrapper: :with_label, recommended: true
+
++ - unless Setting.hide_followers_count
++ .fields-group
++ = f.input :setting_hide_followers_count, as: :boolean, wrapper: :with_label
++
+ %h4= t 'preferences.posting_defaults'
+
+ .fields-row
+ .fields-group.fields-row__column.fields-row__column-6
+ = f.input :setting_default_privacy, collection: Status.selectable_visibilities, wrapper: :with_label, include_blank: false, label_method: lambda { |visibility| safe_join([I18n.t("statuses.visibilities.#{visibility}"), I18n.t("statuses.visibilities.#{visibility}_long")], ' - ') }, required: false, hint: false
+
+ .fields-group.fields-row__column.fields-row__column-6
+ = f.input :setting_default_language, collection: [nil] + filterable_languages.sort, wrapper: :with_label, label_method: lambda { |locale| locale.nil? ? I18n.t('statuses.language_detection') : human_locale(locale) }, required: false, include_blank: false, hint: false
+
+ .fields-group
+ = f.input :setting_default_sensitive, as: :boolean, wrapper: :with_label
+
+ .fields-group
+ = f.input :setting_show_application, as: :boolean, wrapper: :with_label, recommended: true
+
++ .fields-group
++ = f.input :setting_default_content_type, collection: ['text/plain', 'text/markdown', 'text/html'], wrapper: :with_label, include_blank: false, label_method: lambda { |item| safe_join([t("simple_form.labels.defaults.setting_default_content_type_#{item.split('/')[1]}"), content_tag(:span, t("simple_form.hints.defaults.setting_default_content_type_#{item.split('/')[1]}"), class: 'hint')]) }, required: false, as: :radio_buttons, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
++
+ %h4= t 'preferences.public_timelines'
+
+ .fields-group
+ = f.input :chosen_languages, collection: filterable_languages.sort, wrapper: :with_block_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, required: false, as: :check_boxes, collection_wrapper_tag: 'ul', item_wrapper_tag: 'li'
+
+ .actions
+ = f.button :button, t('generic.save_changes'), type: :submit
- if status.spoiler_text?
%p{ :style => ('margin-bottom: 0' unless current_account&.user&.setting_expand_spoilers) }<
%span.p-summary> #{Formatter.instance.format_spoiler(status, autoplay: autoplay)}
- %a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more')
+ %button.status__content__spoiler-link= t('statuses.show_more')
- .e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }
+ .e-content{ lang: status.language, style: "display: #{!current_account&.user&.setting_expand_spoilers && status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }<
= Formatter.instance.format(status, custom_emojify: true, autoplay: autoplay)
+ - if status.preloadable_poll
+ = react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
+ = render partial: 'stream_entries/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay }
- - if status.preloadable_poll
- = react_component :poll, disabled: true, poll: ActiveModelSerializers::SerializableResource.new(status.preloadable_poll, serializer: REST::PollSerializer, scope: current_user, scope_name: :current_user).as_json do
- = render partial: 'stream_entries/poll', locals: { status: status, poll: status.preloadable_poll, autoplay: autoplay }
- - elsif !status.media_attachments.empty?
+ - if !status.media_attachments.empty?
- if status.media_attachments.first.video?
- video = status.media_attachments.first
= react_component :video, src: video.file.url(:original), preview: video.file.url(:small), blurhash: video.blurhash, sensitive: !current_account&.user&.show_all_media? && status.sensitive? || current_account&.user&.hide_all_media?, width: 610, height: 343, inline: true, alt: video.description do
password: Use at least 8 characters
phrase: Will be matched regardless of casing in text or content warning of a toot
scopes: Which APIs the application will be allowed to access. If you select a top-level scope, you don't need to select individual ones.
- setting_advanced_layout: The advanced UI consists of multiple customizable columns
setting_aggregate_reblogs: Do not show new boosts for toots that have been recently boosted (only affects newly-received boosts)
+ setting_default_content_type_html: When writing toots, assume they are written in raw HTML, unless specified otherwise
+ setting_default_content_type_markdown: When writing toots, assume they are using Markdown for rich text formatting, unless specified otherwise
+ setting_default_content_type_plain: When writing toots, assume they are plain text with no special formatting, unless specified otherwise (default Mastodon behavior)
+ setting_default_language: The language of your toots can be detected automatically, but it's not always accurate
+ setting_default_sensitive: Sensitive media is hidden by default and can be revealed with a click
setting_display_media_default: Hide media marked as sensitive
setting_display_media_hide_all: Always hide all media
setting_display_media_show_all: Always show media marked as sensitive
setting_aggregate_reblogs: Group boosts in timelines
setting_auto_play_gif: Auto-play animated GIFs
setting_boost_modal: Show confirmation dialog before boosting
+ setting_default_content_type: Default format for toots
+ setting_default_content_type_html: HTML
+ setting_default_content_type_markdown: Markdown
+ setting_default_content_type_plain: Plain text
setting_default_language: Posting language
- setting_default_privacy: Post privacy
+ setting_default_privacy: Posting privacy
setting_default_sensitive: Always mark media as sensitive
setting_delete_modal: Show confirmation dialog before deleting a toot
setting_display_media: Media display
s.item :identity_proofs, safe_join([fa_icon('key fw'), t('settings.identity_proofs')]), settings_identity_proofs_path, highlights_on: %r{/settings/identity_proofs*}, if: proc { current_account.identity_proofs.exists? }
end
- n.item :preferences, safe_join([fa_icon('cog fw'), t('settings.preferences')]), settings_preferences_url, highlights_on: %r{/settings/preferences|/settings/notifications}
+ n.item :preferences, safe_join([fa_icon('cog fw'), t('settings.preferences')]), settings_preferences_url do |s|
+ s.item :appearance, safe_join([fa_icon('desktop fw'), t('settings.appearance')]), settings_preferences_appearance_url
+ s.item :notifications, safe_join([fa_icon('bell fw'), t('settings.notifications')]), settings_preferences_notifications_url
+ s.item :other, safe_join([fa_icon('cog fw'), t('preferences.other')]), settings_preferences_other_url
+ end
+ n.item :flavours, safe_join([fa_icon('paint-brush fw'), t('settings.flavours')]), settings_flavours_url do |flavours|
+ Themes.instance.flavours.each do |flavour|
+ flavours.item flavour.to_sym, safe_join([fa_icon('star fw'), t("flavours.#{flavour}.name", default: flavour)]), settings_flavour_url(flavour)
+ end
+ end
+
n.item :relationships, safe_join([fa_icon('users fw'), t('settings.relationships')]), relationships_url
n.item :filters, safe_join([fa_icon('filter fw'), t('filters.index.title')]), filters_path, highlights_on: %r{/filters}