From: Thibaut Girka Date: Mon, 10 Jun 2019 16:30:41 +0000 (+0200) Subject: Merge branch 'master' into glitch-soc/merge-upstream X-Git-Url: https://git.xn--scling-oua.cat.family/?a=commitdiff_plain;h=1b0ff4cd69b00f0d2613be45cc233e25dc1a0d05;p=mastodon.git Merge branch 'master' into glitch-soc/merge-upstream Conflicts: - app/controllers/settings/notifications_controller.rb - app/javascript/packs/public.js - app/views/settings/preferences/show.html.haml - app/views/stream_entries/_simple_status.html.haml - config/locales/simple_form.en.yml - config/locales/simple_form.pl.yml - config/navigation.rb - config/routes.rb --- 1b0ff4cd69b00f0d2613be45cc233e25dc1a0d05 diff --cc app/controllers/settings/preferences_controller.rb index a713ee558,110debd6e..5103cc50e --- a/app/controllers/settings/preferences_controller.rb +++ b/app/controllers/settings/preferences_controller.rb @@@ -47,9 -54,8 +51,9 @@@ class Settings::PreferencesController :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 diff --cc app/javascript/core/public.js index 4be75647a,000000000..33b7a207d mode 100644,000000..100644 --- a/app/javascript/core/public.js +++ b/app/javascript/core/public.js @@@ -1,66 -1,0 +1,66 @@@ +// 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; +}); + - delegate(document, '.status__content__spoiler-link', 'click', ({ target }) => { - const contentEl = target.parentNode.parentNode.querySelector('.e-content'); ++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 = 0; ++ this.parentNode.style.marginBottom = 0; + } else { + contentEl.style.display = 'block'; - target.parentNode.style.marginBottom = null; ++ 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; +}); diff --cc app/javascript/mastodon/locales/ja.json index fb4a814c8,e86142869..d63b20c89 --- a/app/javascript/mastodon/locales/ja.json +++ b/app/javascript/mastodon/locales/ja.json @@@ -250,8 -246,8 +250,9 @@@ "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}さんにフォローされました", diff --cc app/views/settings/preferences/appearance/show.html.haml index 000000000,10f009264..9577c10b5 mode 000000,100644..100644 --- a/app/views/settings/preferences/appearance/show.html.haml +++ b/app/views/settings/preferences/appearance/show.html.haml @@@ -1,0 -1,41 +1,39 @@@ + - content_for :page_title do + = t('settings.appearance') + + = simple_form_for current_user, url: settings_preferences_appearance_path, html: { method: :put } do |f| - .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 ++ .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 diff --cc app/views/settings/preferences/other/show.html.haml index 000000000,c966a16bc..dfbf2a09c mode 000000,100644..100644 --- a/app/views/settings/preferences/other/show.html.haml +++ b/app/views/settings/preferences/other/show.html.haml @@@ -1,0 -1,37 +1,44 @@@ + - 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 diff --cc app/views/stream_entries/_simple_status.html.haml index 4df1a0cdf,0f9c65af0..d383d3443 --- a/app/views/stream_entries/_simple_status.html.haml +++ b/app/views/stream_entries/_simple_status.html.haml @@@ -23,14 -23,14 +23,14 @@@ - 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 diff --cc config/locales/simple_form.en.yml index 97a5e8785,4602f9cd9..e5e12c05a --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@@ -26,12 -26,8 +26,12 @@@ en 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 @@@ -98,12 -93,8 +98,12 @@@ 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 diff --cc config/navigation.rb index 16a99731a,df1024189..e8494ddc2 --- a/config/navigation.rb +++ b/config/navigation.rb @@@ -10,14 -10,12 +10,18 @@@ SimpleNavigation::Configuration.run do 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}