about summary refs log tree commit diff
path: root/app/views
diff options
context:
space:
mode:
Diffstat (limited to 'app/views')
-rw-r--r--app/views/about/more.html.haml6
-rw-r--r--app/views/about/show.html.haml13
-rw-r--r--app/views/accounts/_header.html.haml49
-rw-r--r--app/views/accounts/show.html.haml4
-rw-r--r--app/views/admin/account_moderation_notes/_account_moderation_note.html.haml2
-rw-r--r--app/views/admin/accounts/index.html.haml2
-rw-r--r--app/views/admin/accounts/show.html.haml43
-rw-r--r--app/views/admin/custom_emojis/_custom_emoji.html.haml14
-rw-r--r--app/views/home/index.html.haml12
-rwxr-xr-xapp/views/layouts/application.html.haml5
-rw-r--r--app/views/layouts/embedded.html.haml2
-rw-r--r--app/views/layouts/error.html.haml2
-rw-r--r--app/views/settings/applications/new.html.haml2
-rw-r--r--app/views/settings/applications/show.html.haml2
-rw-r--r--app/views/settings/keyword_mutes/_fields.html.haml11
-rw-r--r--app/views/settings/keyword_mutes/_keyword_mute.html.haml10
-rw-r--r--app/views/settings/keyword_mutes/edit.html.haml6
-rw-r--r--app/views/settings/keyword_mutes/index.html.haml18
-rw-r--r--app/views/settings/keyword_mutes/new.html.haml6
-rw-r--r--app/views/settings/notifications/show.html.haml3
-rw-r--r--app/views/settings/profiles/show.html.haml2
-rw-r--r--app/views/stream_entries/_content_spoiler.html.haml2
-rw-r--r--app/views/stream_entries/_detailed_status.html.haml20
-rw-r--r--app/views/stream_entries/_media.html.haml2
-rw-r--r--app/views/stream_entries/_simple_status.html.haml15
-rw-r--r--app/views/user_mailer/confirmation_instructions.pt-BR.html.erb4
-rw-r--r--app/views/user_mailer/confirmation_instructions.pt-BR.text.erb4
-rw-r--r--app/views/user_mailer/confirmation_instructions.zh-cn.html.erb13
-rw-r--r--app/views/user_mailer/confirmation_instructions.zh-cn.text.erb12
-rw-r--r--app/views/user_mailer/password_change.pt-BR.html.erb2
-rw-r--r--app/views/user_mailer/password_change.pt-BR.text.erb2
-rw-r--r--app/views/user_mailer/password_change.zh-cn.html.erb4
-rw-r--r--app/views/user_mailer/password_change.zh-cn.text.erb4
-rw-r--r--app/views/user_mailer/reset_password_instructions.oc.html.erb2
-rw-r--r--app/views/user_mailer/reset_password_instructions.oc.text.erb2
-rw-r--r--app/views/user_mailer/reset_password_instructions.pt-BR.html.erb4
-rw-r--r--app/views/user_mailer/reset_password_instructions.pt-BR.text.erb4
-rw-r--r--app/views/user_mailer/reset_password_instructions.zh-cn.html.erb9
-rw-r--r--app/views/user_mailer/reset_password_instructions.zh-cn.text.erb9
39 files changed, 221 insertions, 107 deletions
diff --git a/app/views/about/more.html.haml b/app/views/about/more.html.haml
index b012606ce..7ffa5ecc3 100644
--- a/app/views/about/more.html.haml
+++ b/app/views/about/more.html.haml
@@ -55,4 +55,8 @@
     .container
       %p
         = link_to t('about.source_code'), @instance_presenter.source_url
-        = " (#{@instance_presenter.version_number})"
+        - if @instance_presenter.commit_hash == ""
+          %strong= " (#{@instance_presenter.version_number})"
+        - else
+          %strong= "#{@instance_presenter.version_number}, "
+          %strong= "#{@instance_presenter.commit_hash}"
diff --git a/app/views/about/show.html.haml b/app/views/about/show.html.haml
index f8f90ce24..385b0b1dc 100644
--- a/app/views/about/show.html.haml
+++ b/app/views/about/show.html.haml
@@ -47,6 +47,13 @@
                 %p= t('about.closed_registrations')
               - else
                 = @instance_presenter.closed_registrations_message.html_safe
+
+            = simple_form_for(:user, html: { style: 'margin-left: -20px' }, url: session_path(:user)) do |f|
+              = f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
+              = f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password'), :autocomplete => 'off' }
+
+              .actions
+                = f.button :button, t('auth.login'), type: :submit
             = link_to t('about.find_another_instance'), 'https://joinmastodon.org/', class: 'button button-alternative button--block'
 
   .about-short
@@ -68,4 +75,8 @@
     .container
       %p
         = link_to t('about.source_code'), @instance_presenter.source_url
-        = " (#{@instance_presenter.version_number})"
+        - if @instance_presenter.commit_hash == ""
+          %strong= " (#{@instance_presenter.version_number})"
+        - else
+          %strong= " (#{@instance_presenter.version_number}, "
+          %strong= " #{@instance_presenter.commit_hash})"
diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml
index 08c3891d2..94ec5ae5b 100644
--- a/app/views/accounts/_header.html.haml
+++ b/app/views/accounts/_header.html.haml
@@ -1,21 +1,23 @@
+- processed_bio = FrontmatterHandler.instance.process_bio Formatter.instance.simplified_format account
 .card.h-card.p-author{ style: "background-image: url(#{account.header.url(:original)})" }
   .card__illustration
-    - if user_signed_in? && current_account.id != account.id && !current_account.requested?(account)
-      .controls
-        - if current_account.following?(account)
-          = link_to account_unfollow_path(account), data: { method: :post }, class: 'icon-button' do
-            = fa_icon 'user-times'
-            = t('accounts.unfollow')
-        - else
-          = link_to account_follow_path(account), data: { method: :post }, class: 'icon-button' do
-            = fa_icon 'user-plus'
-            = t('accounts.follow')
-    - elsif !user_signed_in?
-      .controls
-        .remote-follow
-          = link_to account_remote_follow_path(account), class: 'icon-button' do
-            = fa_icon 'user-plus'
-            = t('accounts.remote_follow')
+    - unless account.memorial?
+      - if user_signed_in? && current_account.id != account.id && !current_account.requested?(account)
+        .controls
+          - if current_account.following?(account)
+            = link_to account_unfollow_path(account), data: { method: :post }, class: 'icon-button' do
+              = fa_icon 'user-times'
+              = t('accounts.unfollow')
+          - else
+            = link_to account_follow_path(account), data: { method: :post }, class: 'icon-button' do
+              = fa_icon 'user-plus'
+              = t('accounts.follow')
+      - elsif !user_signed_in?
+        .controls
+          .remote-follow
+            = link_to account_remote_follow_path(account), class: 'icon-button' do
+              = fa_icon 'user-plus'
+              = t('accounts.remote_follow')
 
     .avatar= image_tag account.avatar.url(:original), class: 'u-photo'
 
@@ -28,11 +30,20 @@
 
     - if account.user_admin?
       .roles
-        .account-role
+        .account-role.admin
           = t 'accounts.roles.admin'
-
+    - elsif account.user_moderator?
+      .roles
+        .account-role.moderator
+          = t 'accounts.roles.moderator'
     .bio
-      .account__header__content.p-note.emojify= Formatter.instance.simplified_format(account)
+      .account__header__content.p-note.emojify!=processed_bio[:text]
+      - if processed_bio[:metadata].length > 0
+        %table.metadata<
+          - processed_bio[:metadata].each do |i|
+            %tr.metadata-item><
+              %th.emojify>!=i[0]
+              %td.emojify>!=i[1]
 
     .details-counters
       .counter{ class: active_nav_class(short_account_url(account)) }
diff --git a/app/views/accounts/show.html.haml b/app/views/accounts/show.html.haml
index 6c90b2c04..fd8ad5530 100644
--- a/app/views/accounts/show.html.haml
+++ b/app/views/accounts/show.html.haml
@@ -12,7 +12,9 @@
   = opengraph 'og:type', 'profile'
   = render 'og', account: @account, url: short_account_url(@account, only_path: false)
 
-- if show_landing_strip?
+- if @account.memorial?
+  .memoriam-strip= t('in_memoriam_html')
+- elsif show_landing_strip?
   = render partial: 'shared/landing_strip', locals: { account: @account }
 
 .h-feed
diff --git a/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml b/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml
index 4651630e9..6761a4319 100644
--- a/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml
+++ b/app/views/admin/account_moderation_notes/_account_moderation_note.html.haml
@@ -7,4 +7,4 @@
     %time.formatted{ datetime: account_moderation_note.created_at.iso8601, title: l(account_moderation_note.created_at) }
       = l account_moderation_note.created_at
   %td
-    = link_to t('admin.account_moderation_notes.delete'), admin_account_moderation_note_path(account_moderation_note), method: :delete
+    = link_to t('admin.account_moderation_notes.delete'), admin_account_moderation_note_path(account_moderation_note), method: :delete if can?(:destroy, account_moderation_note)
diff --git a/app/views/admin/accounts/index.html.haml b/app/views/admin/accounts/index.html.haml
index 1b56a3a31..27a0682d8 100644
--- a/app/views/admin/accounts/index.html.haml
+++ b/app/views/admin/accounts/index.html.haml
@@ -42,7 +42,7 @@
       - if params[key].present?
         = hidden_field_tag key, params[key]
 
-    - %i(username display_name email ip).each do |key|
+    - %i(username by_domain display_name email ip).each do |key|
       .input.string.optional
         = text_field_tag key, params[key], class: 'string optional', placeholder: I18n.t("admin.accounts.#{key}")
 
diff --git a/app/views/admin/accounts/show.html.haml b/app/views/admin/accounts/show.html.haml
index 1f5c8fcf5..ddb1cf15d 100644
--- a/app/views/admin/accounts/show.html.haml
+++ b/app/views/admin/accounts/show.html.haml
@@ -16,8 +16,27 @@
 
       - if @account.local?
         %tr
+          %th= t('admin.accounts.role')
+          %td
+            = t("admin.accounts.roles.#{@account.user&.role}")
+            = table_link_to 'angle-double-up', t('admin.accounts.promote'), promote_admin_account_role_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:promote, @account.user)
+            = table_link_to 'angle-double-down', t('admin.accounts.demote'), demote_admin_account_role_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') } if can?(:demote, @account.user)
+        %tr
           %th= t('admin.accounts.email')
-          %td= @account.user_email
+          %td
+            = @account.user_email
+
+            - if @account.user_confirmed?
+              = fa_icon('check')
+        %tr
+          %th= t('admin.accounts.login_status')
+          %td
+            - if @account.user&.disabled?
+              = t('admin.accounts.disabled')
+              = table_link_to 'unlock', t('admin.accounts.enable'), enable_admin_account_path(@account.id), method: :post if can?(:enable, @account.user)
+            - else
+              = t('admin.accounts.enabled')
+              = table_link_to 'lock', t('admin.accounts.disable'), disable_admin_account_path(@account.id), method: :post if can?(:disable, @account.user)
         %tr
           %th= t('admin.accounts.most_recent_ip')
           %td= @account.user_current_sign_in_ip
@@ -62,26 +81,28 @@
 %div{ style: 'overflow: hidden' }
   %div{ style: 'float: right' }
     - if @account.local?
-      = link_to t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, class: 'button'
+      = link_to t('admin.accounts.reset_password'), admin_account_reset_path(@account.id), method: :create, class: 'button' if can?(:reset_password, @account.user)
       - if @account.user&.otp_required_for_login?
-        = link_to t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete, class: 'button'
+        = link_to t('admin.accounts.disable_two_factor_authentication'), admin_user_two_factor_authentication_path(@account.user.id), method: :delete, class: 'button' if can?(:disable_2fa, @account.user)
+      - unless @account.memorial?
+        = link_to t('admin.accounts.memorialize'), memorialize_admin_account_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:memorialize, @account)
     - else
-      = link_to t('admin.accounts.redownload'), redownload_admin_account_path(@account.id), method: :post, class: 'button'
+      = link_to t('admin.accounts.redownload'), redownload_admin_account_path(@account.id), method: :post, class: 'button' if can?(:redownload, @account)
 
   %div{ style: 'float: left' }
     - if @account.silenced?
-      = link_to t('admin.accounts.undo_silenced'), admin_account_silence_path(@account.id), method: :delete, class: 'button'
+      = link_to t('admin.accounts.undo_silenced'), admin_account_silence_path(@account.id), method: :delete, class: 'button' if can?(:unsilence, @account)
     - else
-      = link_to t('admin.accounts.silence'), admin_account_silence_path(@account.id), method: :post, class: 'button'
+      = link_to t('admin.accounts.silence'), admin_account_silence_path(@account.id), method: :post, class: 'button' if can?(:silence, @account)
 
     - if @account.local?
       - unless @account.user_confirmed?
-        = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(@account.id), method: :post, class: 'button'
+        = link_to t('admin.accounts.confirm'), admin_account_confirmation_path(@account.id), method: :post, class: 'button' if can?(:confirm, @account.user)
 
     - if @account.suspended?
-      = link_to t('admin.accounts.undo_suspension'), admin_account_suspension_path(@account.id), method: :delete, class: 'button'
+      = link_to t('admin.accounts.undo_suspension'), admin_account_suspension_path(@account.id), method: :delete, class: 'button' if can?(:unsuspend, @account)
     - else
-      = link_to t('admin.accounts.perform_full_suspension'), admin_account_suspension_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button'
+      = link_to t('admin.accounts.perform_full_suspension'), admin_account_suspension_path(@account.id), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }, class: 'button' if can?(:suspend, @account)
 
 - unless @account.local?
   %hr
@@ -107,9 +128,9 @@
 
   %div{ style: 'overflow: hidden' }
     %div{ style: 'float: right' }
-      = link_to @account.subscribed? ? t('admin.accounts.resubscribe') : t('admin.accounts.subscribe'), subscribe_admin_account_path(@account.id), method: :post, class: 'button'
+      = link_to @account.subscribed? ? t('admin.accounts.resubscribe') : t('admin.accounts.subscribe'), subscribe_admin_account_path(@account.id), method: :post, class: 'button' if can?(:subscribe, @account)
       - if @account.subscribed?
-        = link_to t('admin.accounts.unsubscribe'), unsubscribe_admin_account_path(@account.id), method: :post, class: 'button negative'
+        = link_to t('admin.accounts.unsubscribe'), unsubscribe_admin_account_path(@account.id), method: :post, class: 'button negative' if can?(:unsubscribe, @account)
 
   %hr
   %h3 ActivityPub
diff --git a/app/views/admin/custom_emojis/_custom_emoji.html.haml b/app/views/admin/custom_emojis/_custom_emoji.html.haml
index 1fa64908c..bab34bc8d 100644
--- a/app/views/admin/custom_emojis/_custom_emoji.html.haml
+++ b/app/views/admin/custom_emojis/_custom_emoji.html.haml
@@ -1,6 +1,6 @@
 %tr
   %td
-    = image_tag custom_emoji.image.url, class: 'emojione', alt: ":#{custom_emoji.shortcode}:"
+    = custom_emoji_tag(custom_emoji)
   %td
     %samp= ":#{custom_emoji.shortcode}:"
   %td
@@ -9,8 +9,16 @@
     - else
       = custom_emoji.domain
   %td
-    - unless custom_emoji.local?
-      = table_link_to 'copy', t('admin.custom_emojis.copy'), copy_admin_custom_emoji_path(custom_emoji, page: params[:page]), method: :post
+    - if custom_emoji.local?
+      - if custom_emoji.visible_in_picker
+        = table_link_to 'eye', t('admin.custom_emojis.listed'), admin_custom_emoji_path(custom_emoji, custom_emoji: { visible_in_picker: false }), method: :patch
+      - else
+        = table_link_to 'eye-slash', t('admin.custom_emojis.unlisted'), admin_custom_emoji_path(custom_emoji, custom_emoji: { visible_in_picker: true }), method: :patch
+    - else
+      - if custom_emoji.local_counterpart.present?
+        = link_to safe_join([custom_emoji_tag(custom_emoji.local_counterpart), t('admin.custom_emojis.overwrite')]), copy_admin_custom_emoji_path(custom_emoji, page: params[:page]), method: :post, class: 'table-action-link'
+      - else
+        = table_link_to 'copy', t('admin.custom_emojis.copy'), copy_admin_custom_emoji_path(custom_emoji, page: params[:page]), method: :post
   %td
     - if custom_emoji.disabled?
       = table_link_to 'power-off', t('admin.custom_emojis.enable'), enable_admin_custom_emoji_path(custom_emoji), method: :post, data: { confirm: t('admin.accounts.are_you_sure') }
diff --git a/app/views/home/index.html.haml b/app/views/home/index.html.haml
index 659295ebf..63b3a0c26 100644
--- a/app/views/home/index.html.haml
+++ b/app/views/home/index.html.haml
@@ -1,14 +1,12 @@
 - content_for :header_tags do
-  %link{ href: asset_pack_path('features/getting_started.js'), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
-  %link{ href: asset_pack_path('features/compose.js'), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
-  %link{ href: asset_pack_path('features/home_timeline.js'), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
-  %link{ href: asset_pack_path('features/notifications.js'), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
-  %link{ href: asset_pack_path('features/community_timeline.js'), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
-  %link{ href: asset_pack_path('features/public_timeline.js'), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
+  - if theme_data['preload']
+    - theme_data['preload'].each do |link|
+      %link{ href: asset_pack_path("#{link}.js"), crossorigin: 'anonymous', rel: 'preload', as: 'script' }/
   %meta{name: 'applicationServerKey', content: Rails.configuration.x.vapid_public_key}
   %script#initial-state{ type: 'application/json' }!= json_escape(@initial_state_json)
 
-  = javascript_pack_tag 'application', integrity: true, crossorigin: 'anonymous'
+  = javascript_pack_tag "themes/#{current_theme}", integrity: true, crossorigin: 'anonymous'
+  = stylesheet_pack_tag "themes/#{current_theme}", integrity: true, media: 'all'
 
 .app-holder#mastodon{ data: { props: Oj.dump(default_props) } }
   %noscript
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 831858bcf..24b74c787 100755
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -19,15 +19,16 @@
       = title
 
     = stylesheet_pack_tag 'common', media: 'all'
-    = stylesheet_pack_tag current_theme, media: 'all'
     = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous'
     = javascript_pack_tag "locale_#{I18n.locale}", integrity: true, crossorigin: 'anonymous'
     = csrf_meta_tags
 
+    - if controller_name != 'home'
+      = stylesheet_pack_tag 'application', integrity: true, media: 'all'
+
     = yield :header_tags
 
   - body_classes ||= @body_classes || ''
-  - body_classes += ' reduce-motion' if current_account&.user&.setting_reduce_motion
   - body_classes += ' system-font' if current_account&.user&.setting_system_font_ui
 
   %body{ class: add_rtl_body_class(body_classes) }
diff --git a/app/views/layouts/embedded.html.haml b/app/views/layouts/embedded.html.haml
index ac11cfbe7..5fc60be17 100644
--- a/app/views/layouts/embedded.html.haml
+++ b/app/views/layouts/embedded.html.haml
@@ -5,8 +5,8 @@
     %meta{ name: 'robots', content: 'noindex' }/
 
     = stylesheet_pack_tag 'common', media: 'all'
-    = stylesheet_pack_tag Setting.default_settings['theme'], media: 'all'
     = javascript_pack_tag 'common', integrity: true, crossorigin: 'anonymous'
+    = stylesheet_pack_tag 'application', integrity: true, media: 'all'
     = javascript_pack_tag "locale_#{I18n.locale}", integrity: true, crossorigin: 'anonymous'
     = javascript_pack_tag 'public', integrity: true, crossorigin: 'anonymous'
   %body.embed
diff --git a/app/views/layouts/error.html.haml b/app/views/layouts/error.html.haml
index 37359b89b..d0eae4434 100644
--- a/app/views/layouts/error.html.haml
+++ b/app/views/layouts/error.html.haml
@@ -6,7 +6,7 @@
     %title= safe_join([yield(:page_title), Setting.default_settings['site_title']], ' - ')
     %meta{ content: 'width=device-width,initial-scale=1', name: 'viewport' }/
     = stylesheet_pack_tag 'common', media: 'all'
-    = stylesheet_pack_tag Setting.default_settings['theme'], media: 'all'
+    = stylesheet_pack_tag 'application', integrity: true, media: 'all'
   %body.error
     .dialog
       %img{ alt: Setting.default_settings['site_title'], src: '/oops.gif' }/
diff --git a/app/views/settings/applications/new.html.haml b/app/views/settings/applications/new.html.haml
index 5274a430c..aa2281fea 100644
--- a/app/views/settings/applications/new.html.haml
+++ b/app/views/settings/applications/new.html.haml
@@ -3,6 +3,6 @@
 
 = simple_form_for @application, url: settings_applications_path do |f|
   = render 'fields', f: f
-  
+
   .actions
     = f.button :button, t('doorkeeper.applications.buttons.submit'), type: :submit
diff --git a/app/views/settings/applications/show.html.haml b/app/views/settings/applications/show.html.haml
index 12baed088..390682d6f 100644
--- a/app/views/settings/applications/show.html.haml
+++ b/app/views/settings/applications/show.html.haml
@@ -25,7 +25,7 @@
 
 = simple_form_for @application, url: settings_application_path(@application), method: :put do |f|
   = render 'fields', f: f
-    
+
   .actions
     = f.button :button, t('generic.save_changes'), type: :submit
 
diff --git a/app/views/settings/keyword_mutes/_fields.html.haml b/app/views/settings/keyword_mutes/_fields.html.haml
new file mode 100644
index 000000000..892676f18
--- /dev/null
+++ b/app/views/settings/keyword_mutes/_fields.html.haml
@@ -0,0 +1,11 @@
+.fields-group
+  = f.input :keyword
+  = f.check_box :whole_word
+  = f.label :whole_word, t('keyword_mutes.match_whole_word')
+
+.actions
+  - if f.object.persisted?
+    = f.button :button, t('generic.save_changes'), type: :submit
+    = link_to t('keyword_mutes.remove'), settings_keyword_mute_path(f.object), class: 'negative button', method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
+  - else
+    = f.button :button, t('keyword_mutes.add_keyword'), type: :submit
diff --git a/app/views/settings/keyword_mutes/_keyword_mute.html.haml b/app/views/settings/keyword_mutes/_keyword_mute.html.haml
new file mode 100644
index 000000000..c45cc64fb
--- /dev/null
+++ b/app/views/settings/keyword_mutes/_keyword_mute.html.haml
@@ -0,0 +1,10 @@
+%tr
+  %td
+    = keyword_mute.keyword
+  %td
+    - if keyword_mute.whole_word
+      %i.fa.fa-check
+  %td
+    = table_link_to 'edit', t('keyword_mutes.edit'), edit_settings_keyword_mute_path(keyword_mute)
+  %td
+    = table_link_to 'times', t('keyword_mutes.remove'), settings_keyword_mute_path(keyword_mute), method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
diff --git a/app/views/settings/keyword_mutes/edit.html.haml b/app/views/settings/keyword_mutes/edit.html.haml
new file mode 100644
index 000000000..af3949be2
--- /dev/null
+++ b/app/views/settings/keyword_mutes/edit.html.haml
@@ -0,0 +1,6 @@
+- content_for :page_title do
+  = t('keyword_mutes.edit_keyword')
+
+= simple_form_for @keyword_mute, url: settings_keyword_mute_path(@keyword_mute), as: :keyword_mute do |f|
+  = render 'shared/error_messages', object: @keyword_mute
+  = render 'fields', f: f
diff --git a/app/views/settings/keyword_mutes/index.html.haml b/app/views/settings/keyword_mutes/index.html.haml
new file mode 100644
index 000000000..9ef8d55bc
--- /dev/null
+++ b/app/views/settings/keyword_mutes/index.html.haml
@@ -0,0 +1,18 @@
+- content_for :page_title do
+  = t('settings.keyword_mutes')
+
+.table-wrapper
+  %table.table
+    %thead
+      %tr
+        %th= t('keyword_mutes.keyword')
+        %th= t('keyword_mutes.match_whole_word')
+        %th
+        %th
+      %tbody
+        = render partial: 'keyword_mute', collection: @keyword_mutes, as: :keyword_mute
+
+= paginate @keyword_mutes
+.simple_form
+  = link_to t('keyword_mutes.add_keyword'), new_settings_keyword_mute_path, class: 'button'
+  = link_to t('keyword_mutes.remove_all'), destroy_all_settings_keyword_mutes_path, class: 'button negative', method: :delete, data: { confirm: t('admin.accounts.are_you_sure') }
diff --git a/app/views/settings/keyword_mutes/new.html.haml b/app/views/settings/keyword_mutes/new.html.haml
new file mode 100644
index 000000000..5c999c8d2
--- /dev/null
+++ b/app/views/settings/keyword_mutes/new.html.haml
@@ -0,0 +1,6 @@
+- content_for :page_title do
+  = t('keyword_mutes.add_keyword')
+
+= simple_form_for @keyword_mute, url: settings_keyword_mutes_path, as: :keyword_mute do |f|
+  = render 'shared/error_messages', object: @keyword_mute
+  = render 'fields', f: f
diff --git a/app/views/settings/notifications/show.html.haml b/app/views/settings/notifications/show.html.haml
index 80cd615c7..b718b62df 100644
--- a/app/views/settings/notifications/show.html.haml
+++ b/app/views/settings/notifications/show.html.haml
@@ -11,7 +11,7 @@
       = ff.input :reblog, as: :boolean, wrapper: :with_label
       = ff.input :favourite, as: :boolean, wrapper: :with_label
       = ff.input :mention, as: :boolean, wrapper: :with_label
- 
+
   .fields-group
     = f.simple_fields_for :notification_emails, hash_to_object(current_user.settings.notification_emails) do |ff|
       = ff.input :digest, as: :boolean, wrapper: :with_label
@@ -20,6 +20,7 @@
     = f.simple_fields_for :interactions, hash_to_object(current_user.settings.interactions) do |ff|
       = ff.input :must_be_follower, as: :boolean, wrapper: :with_label
       = ff.input :must_be_following, as: :boolean, wrapper: :with_label
+      = ff.input :must_be_following_dm, as: :boolean, wrapper: :with_label
 
   .actions
     = f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/settings/profiles/show.html.haml b/app/views/settings/profiles/show.html.haml
index 7a06cd014..551a7ca49 100644
--- a/app/views/settings/profiles/show.html.haml
+++ b/app/views/settings/profiles/show.html.haml
@@ -6,7 +6,7 @@
 
   .fields-group
     = f.input :display_name, placeholder: t('simple_form.labels.defaults.display_name'), hint: t('simple_form.hints.defaults.display_name', count: 30 - @account.display_name.size).html_safe
-    = f.input :note, placeholder: t('simple_form.labels.defaults.note'), hint: t('simple_form.hints.defaults.note', count: 160 - @account.note.size).html_safe
+    = f.input :note, placeholder: t('simple_form.labels.defaults.note'), hint: t('simple_form.hints.defaults.note', count: 500 - @account.note.size).html_safe
 
   .card.compact{ style: "background-image: url(#{@account.header.url(:original)})", data: { original_src: @account.header.url(:original) } }
     .avatar= image_tag @account.avatar.url(:original), data: { original_src: @account.avatar.url(:original) }
diff --git a/app/views/stream_entries/_content_spoiler.html.haml b/app/views/stream_entries/_content_spoiler.html.haml
index 798dfce67..fb42d3f57 100644
--- a/app/views/stream_entries/_content_spoiler.html.haml
+++ b/app/views/stream_entries/_content_spoiler.html.haml
@@ -1,4 +1,4 @@
-.media-spoiler-wrapper{ class: sensitive == false && 'media-spoiler-wrapper__visible' }
+.media-spoiler-wrapper{ class: sensitive == false && 'media-spoiler-wrapper__visible' }><
   .spoiler-button
     .icon-button.overlayed
       %i.fa.fa-fw.fa-eye
diff --git a/app/views/stream_entries/_detailed_status.html.haml b/app/views/stream_entries/_detailed_status.html.haml
index 3119ebf4b..b488bd9ba 100644
--- a/app/views/stream_entries/_detailed_status.html.haml
+++ b/app/views/stream_entries/_detailed_status.html.haml
@@ -17,16 +17,16 @@
       %p{ style: 'margin-bottom: 0' }<
         %span.p-summary> #{Formatter.instance.format_spoiler(status)}&nbsp;
         %a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more')
-    .e-content{ lang: status.language, style: "display: #{status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true)
-
-  - if !status.media_attachments.empty?
-    - if status.media_attachments.first.video?
-      - video = status.media_attachments.first
-      %div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive?, width: 670, height: 380) }}
-    - else
-      %div{ data: { component: 'MediaGallery', props: Oj.dump(height: 380, sensitive: status.sensitive?, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }}
-  - elsif status.preview_cards.first
-    %div{ data: { component: 'Card', props: Oj.dump('maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_cards.first, serializer: REST::PreviewCardSerializer).as_json) }}
+    .e-content{ lang: status.language, style: "display: #{status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }<
+      = Formatter.instance.format(status, custom_emojify: true)
+      - if !status.media_attachments.empty?
+        - if status.media_attachments.first.video?
+          - video = status.media_attachments.first
+          %div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive?, width: 670, height: 380) }}<
+        - else
+          %div{ data: { component: 'MediaGallery', props: Oj.dump(height: 380, sensitive: status.sensitive?, standalone: true, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, 'reduceMotion': current_account&.user&.setting_reduce_motion, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }}<
+      - elsif status.preview_cards.first
+        %div{ data: { component: 'Card', props: Oj.dump('maxDescription': 160, card: ActiveModelSerializers::SerializableResource.new(status.preview_cards.first, serializer: REST::PreviewCardSerializer).as_json) }}<
 
   .detailed-status__meta
     %data.dt-published{ value: status.created_at.to_time.iso8601 }
diff --git a/app/views/stream_entries/_media.html.haml b/app/views/stream_entries/_media.html.haml
index 779f02c8d..32d024cf6 100644
--- a/app/views/stream_entries/_media.html.haml
+++ b/app/views/stream_entries/_media.html.haml
@@ -1,4 +1,4 @@
-.media-item
+.media-item><
   = link_to media.remote_url.blank? ? media.file.url(:original) : media.remote_url, style: media.image? ? "background-image: url(#{media.file.url(:original)})" : '', target: '_blank', rel: 'noopener', class: "u-#{media.video? || media.gifv? ? 'video' : 'photo'}" do
     - unless media.image?
       %video{ src: media.file.url(:original), autoplay: true, loop: true }/
diff --git a/app/views/stream_entries/_simple_status.html.haml b/app/views/stream_entries/_simple_status.html.haml
index b594c9da6..0b45ff308 100644
--- a/app/views/stream_entries/_simple_status.html.haml
+++ b/app/views/stream_entries/_simple_status.html.haml
@@ -18,11 +18,12 @@
       %p{ style: 'margin-bottom: 0' }<
         %span.p-summary> #{Formatter.instance.format_spoiler(status)}&nbsp;
         %a.status__content__spoiler-link{ href: '#' }= t('statuses.show_more')
-    .e-content{ lang: status.language, style: "display: #{status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }= Formatter.instance.format(status, custom_emojify: true)
+    .e-content{ lang: status.language, style: "display: #{status.spoiler_text? ? 'none' : 'block'}; direction: #{rtl_status?(status) ? 'rtl' : 'ltr'}" }<
+      = Formatter.instance.format(status, custom_emojify: true)
 
-  - unless status.media_attachments.empty?
-    - if status.media_attachments.first.video?
-      - video = status.media_attachments.first
-      %div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive?, width: 610, height: 343) }}
-    - else
-      %div{ data: { component: 'MediaGallery', props: Oj.dump(height: 343, sensitive: status.sensitive?, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }}
+      - unless status.media_attachments.empty?
+        - if status.media_attachments.first.video?
+          - video = status.media_attachments.first
+          %div{ data: { component: 'Video', props: Oj.dump(src: video.file.url(:original), preview: video.file.url(:small), sensitive: status.sensitive?, width: 610, height: 343) }}><
+        - else
+          %div{ data: { component: 'MediaGallery', props: Oj.dump(height: 343, sensitive: status.sensitive?, 'autoPlayGif': current_account&.user&.setting_auto_play_gif, media: status.media_attachments.map { |a| ActiveModelSerializers::SerializableResource.new(a, serializer: REST::MediaAttachmentSerializer).as_json }) }}><
diff --git a/app/views/user_mailer/confirmation_instructions.pt-BR.html.erb b/app/views/user_mailer/confirmation_instructions.pt-BR.html.erb
index 80edcfda7..0be16d994 100644
--- a/app/views/user_mailer/confirmation_instructions.pt-BR.html.erb
+++ b/app/views/user_mailer/confirmation_instructions.pt-BR.html.erb
@@ -1,6 +1,6 @@
 <p>Boas vindas, <%= @resource.email %>!</p>
 
-<p>Você acabou de criar uma conta no <%= @instance %>.</p>
+<p>Você acabou de criar uma conta na instância <%= @instance %>.</p>
 
 <p>Para confirmar o seu cadastro, por favor clique no link a seguir: <br>
 <%= link_to 'Confirmar cadastro', confirmation_url(@resource, confirmation_token: @token) %>
@@ -9,4 +9,4 @@
 
 <p>Atenciosamente,<p>
 
-<p>A equipe do <%= @instance %></p>
+<p>A equipe da instância <%= @instance %></p>
diff --git a/app/views/user_mailer/confirmation_instructions.pt-BR.text.erb b/app/views/user_mailer/confirmation_instructions.pt-BR.text.erb
index 95efb3436..578f7acb5 100644
--- a/app/views/user_mailer/confirmation_instructions.pt-BR.text.erb
+++ b/app/views/user_mailer/confirmation_instructions.pt-BR.text.erb
@@ -1,6 +1,6 @@
 Boas vindas, <%= @resource.email %>!
 
-Você acabou de criar uma conta no <%= @instance %>.
+Você acabou de criar uma conta na instância <%= @instance %>.
 
 Para confirmar o seu cadastro, por favor clique no link a seguir:
 <%= confirmation_url(@resource, confirmation_token: @token) %>
@@ -9,4 +9,4 @@ Por favor, leia também os nossos termos e condições de uso <%= terms_url %>
 
 Atenciosamente,
 
-A equipe do <%= @instance %>
+A equipe da instância <%= @instance %>
diff --git a/app/views/user_mailer/confirmation_instructions.zh-cn.html.erb b/app/views/user_mailer/confirmation_instructions.zh-cn.html.erb
index de2f8b6e0..8a676498a 100644
--- a/app/views/user_mailer/confirmation_instructions.zh-cn.html.erb
+++ b/app/views/user_mailer/confirmation_instructions.zh-cn.html.erb
@@ -1,10 +1,13 @@
-<p><%= @resource.email %> ,嗨呀!</p>
+<p><%= @resource.email %>,你好呀!</p>
 
-<p>你刚刚在 <%= @instance %> 创建了帐号。</p>
+<p>你刚刚在 <%= @instance %> 创建了一个帐户呢。</p>
 
-<p>点击下面的链接来完成注册啦 : <br>
+<p>点击下面的链接来完成注册啦:<br>
 <%= link_to '确认帐户', confirmation_url(@resource, confirmation_token: @token) %>
 
-<p>别忘了看看 <%= link_to '使用条款', terms_url %>。</p>
+<p>上面的链接按不动?把下面的链接复制到地址栏再试试:<br>
+<span><%= confirmation_url(@resource, confirmation_token: @token) %></span>
 
-<p> <%= @instance %> 敬上</p>
\ No newline at end of file
+<p>记得读一读我们的<%= link_to '使用条款', terms_url %>哦。</p>
+
+<p>来自 <%= @instance %> 管理团队</p>
diff --git a/app/views/user_mailer/confirmation_instructions.zh-cn.text.erb b/app/views/user_mailer/confirmation_instructions.zh-cn.text.erb
index d7d4b4b23..25d901f16 100644
--- a/app/views/user_mailer/confirmation_instructions.zh-cn.text.erb
+++ b/app/views/user_mailer/confirmation_instructions.zh-cn.text.erb
@@ -1,10 +1,10 @@
-<%= @resource.email %> ,嗨呀!
+<%= @resource.email %>,你好呀!
 
-你刚刚在 <%= @instance %> 创建了帐号。
+你刚刚在 <%= @instance %> 创建了一个帐户呢。
 
-点击下面的链接来完成注册啦 : <br>
-<%= link_to '确认帐户', confirmation_url(@resource, confirmation_token: @token) %>
+点击下面的链接来完成注册啦:
+<%= confirmation_url(@resource, confirmation_token: @token) %>
 
-别忘了看看 <%= link_to 'terms and conditions', terms_url %>。
+记得读一读我们的使用条款哦:<%= terms_url %>
 
-<%= @instance %> 敬上
\ No newline at end of file
+来自 <%= @instance %> 管理团队
\ No newline at end of file
diff --git a/app/views/user_mailer/password_change.pt-BR.html.erb b/app/views/user_mailer/password_change.pt-BR.html.erb
index 5f707ba09..a1aaa265e 100644
--- a/app/views/user_mailer/password_change.pt-BR.html.erb
+++ b/app/views/user_mailer/password_change.pt-BR.html.erb
@@ -1,3 +1,3 @@
 <p>Olá, <%= @resource.email %>!</p>
 
-<p>Estamos te contatando para te notificar que a senha senha no <%= @instance %> foi modificada.</p>
+<p>Estamos te contatando para te notificar que a sua senha na instância <%= @instance %> foi modificada.</p>
diff --git a/app/views/user_mailer/password_change.pt-BR.text.erb b/app/views/user_mailer/password_change.pt-BR.text.erb
index d8b76648c..eb7368ba9 100644
--- a/app/views/user_mailer/password_change.pt-BR.text.erb
+++ b/app/views/user_mailer/password_change.pt-BR.text.erb
@@ -1,3 +1,3 @@
 Olá, <%= @resource.email %>!
 
-Estamos te contatando para te notificar que a senha senha no <%= @instance %> foi modificada.
+Estamos te contatando para te notificar que a sua senha na instância <%= @instance %> foi modificada.
diff --git a/app/views/user_mailer/password_change.zh-cn.html.erb b/app/views/user_mailer/password_change.zh-cn.html.erb
index 115030af4..64e8b6b2f 100644
--- a/app/views/user_mailer/password_change.zh-cn.html.erb
+++ b/app/views/user_mailer/password_change.zh-cn.html.erb
@@ -1,3 +1,3 @@
-<p><%= @resource.email %>,嗨呀!</p>
+<p><%= @resource.email %>,你好呀!</p>
 
-<p>这只是一封用来通知你的密码已经被修改的邮件。_(:3」∠)_</p>
+<p>提醒一下,你在 <%= @instance %> 上的密码被更改了哦。</p>
diff --git a/app/views/user_mailer/password_change.zh-cn.text.erb b/app/views/user_mailer/password_change.zh-cn.text.erb
index 5a989d324..dbc065173 100644
--- a/app/views/user_mailer/password_change.zh-cn.text.erb
+++ b/app/views/user_mailer/password_change.zh-cn.text.erb
@@ -1,3 +1,3 @@
-<%= @resource.email %>,嗨呀!
+<%= @resource.email %>,你好呀!
 
-这只是一封用来通知你的密码已经被修改的邮件。_(:3」∠)_
+提醒一下,你在 <%= @instance %> 上的密码被更改了哦。
diff --git a/app/views/user_mailer/reset_password_instructions.oc.html.erb b/app/views/user_mailer/reset_password_instructions.oc.html.erb
index 6c775b3a1..92e4b8f8b 100644
--- a/app/views/user_mailer/reset_password_instructions.oc.html.erb
+++ b/app/views/user_mailer/reset_password_instructions.oc.html.erb
@@ -1,6 +1,6 @@
 <p>Bonjorn <%= @resource.email %> !</p>
 
-<p>Qualqu’un a demandat la reĩnicializacion de vòstre senhal per Mastodon. Podètz realizar la reĩnicializacion en clicant sul ligam çai-jos.</p>
+<p>Qualqu’un a demandat la reïnicializacion de vòstre senhal per Mastodon. Podètz realizar la reïnicializacion en clicant sul ligam çai-jos.</p>
 
 <p><%= link_to 'Modificar mon senhal', edit_password_url(@resource, reset_password_token: @token) %></p>
 
diff --git a/app/views/user_mailer/reset_password_instructions.oc.text.erb b/app/views/user_mailer/reset_password_instructions.oc.text.erb
index 26432d2df..5a5219589 100644
--- a/app/views/user_mailer/reset_password_instructions.oc.text.erb
+++ b/app/views/user_mailer/reset_password_instructions.oc.text.erb
@@ -1,6 +1,6 @@
 Bonjorn <%= @resource.email %> !
 
-Qualqu’un a demandat la reĩnicializacion de vòstre senhal per Mastodon. Podètz realizar la reĩnicializacion en clicant sul ligam çai-jos.</p>
+Qualqu’un a demandat la reïnicializacion de vòstre senhal per Mastodon. Podètz realizar la reïnicializacion en clicant sul ligam çai-jos.</p>
 
 <%= link_to 'Modificar mon senhal', edit_password_url(@resource, reset_password_token: @token) %>
 
diff --git a/app/views/user_mailer/reset_password_instructions.pt-BR.html.erb b/app/views/user_mailer/reset_password_instructions.pt-BR.html.erb
index 940438b7c..9b21aae92 100644
--- a/app/views/user_mailer/reset_password_instructions.pt-BR.html.erb
+++ b/app/views/user_mailer/reset_password_instructions.pt-BR.html.erb
@@ -1,8 +1,8 @@
 <p>Olá, <%= @resource.email %>!</p>
 
-<p>Alguém solicitou um link para mudar a sua senha no <%= @instance %>. Você pode fazer isso através do link abaixo:</p>
+<p>Alguém solicitou um link para mudar a sua senha na instância <%= @instance %>. Você pode fazer isso através do link abaixo:</p>
 
 <p><%= link_to 'Mudar a minha senha', edit_password_url(@resource, reset_password_token: @token) %></p>
 
 <p>Se você não solicitou isso, por favor ignore este e-mail.</p>
-<p>A senha senha não será modificada até que você acesse o link acima e crie uma nova.</p>
+<p>A senha não será modificada até que você acesse o link acima e crie uma nova.</p>
diff --git a/app/views/user_mailer/reset_password_instructions.pt-BR.text.erb b/app/views/user_mailer/reset_password_instructions.pt-BR.text.erb
index f574fe08f..2abff0c0d 100644
--- a/app/views/user_mailer/reset_password_instructions.pt-BR.text.erb
+++ b/app/views/user_mailer/reset_password_instructions.pt-BR.text.erb
@@ -1,8 +1,8 @@
 Olá, <%= @resource.email %>!
 
-Alguém solicitou um link para mudar a sua senha no <%= @instance %>. Você pode fazer isso através do link abaixo:
+Alguém solicitou um link para mudar a sua senha na instância <%= @instance %>. Você pode fazer isso através do link abaixo:
 
 <%= edit_password_url(@resource, reset_password_token: @token) %>
 
 Se você não solicitou isso, por favor ignore este e-mail.
-A senha senha não será modificada até que você acesse o link acima e crie uma nova.
+A senha não será modificada até que você acesse o link acima e crie uma nova.
diff --git a/app/views/user_mailer/reset_password_instructions.zh-cn.html.erb b/app/views/user_mailer/reset_password_instructions.zh-cn.html.erb
index 51e3073f1..124305675 100644
--- a/app/views/user_mailer/reset_password_instructions.zh-cn.html.erb
+++ b/app/views/user_mailer/reset_password_instructions.zh-cn.html.erb
@@ -1,7 +1,8 @@
-<p><%= @resource.email %> ,嗨呀!!</p>
+<p><%= @resource.email %>,你好呀!</p>
 
-<p>有人(但愿是你)请求更改你Mastodon帐户的密码。如果是你的话,请点击下面的链接:</p>
+<p>有人想修改你在 <%= @instance %> 上的密码呢。如果你确实想修改密码的话,点击下面的链接吧:</p>
 
-<p><%= link_to '更改密码', edit_password_url(@resource, reset_password_token: @token) %></p>
+<p><%= link_to '修改密码', edit_password_url(@resource, reset_password_token: @token) %></p>
 
-<p>如果不是的话,忘了它吧。只有你本人通过上面的链接设置新的密码以后你的新密码才会生效。</p>
+<p>如果你不想修改密码的话,还请忽略这封邮件哦。</p>
+<p>在你点击上面的链接并修改密码前,你的密码是不会改变的。</p>
diff --git a/app/views/user_mailer/reset_password_instructions.zh-cn.text.erb b/app/views/user_mailer/reset_password_instructions.zh-cn.text.erb
index 7df590f78..f7cd88847 100644
--- a/app/views/user_mailer/reset_password_instructions.zh-cn.text.erb
+++ b/app/views/user_mailer/reset_password_instructions.zh-cn.text.erb
@@ -1,7 +1,8 @@
-<%= @resource.email %> ,嗨呀!!
+<%= @resource.email %>,你好呀!
 
-有人(但愿是你)请求更改你Mastodon帐户的密码。如果是你的话,请点击下面的链接:
+有人想修改你在 <%= @instance %> 上的密码呢。如果你确实想修改密码的话,点击下面的链接吧:
 
-<%= link_to '更改密码', edit_password_url(@resource, reset_password_token: @token) %>
+<%= edit_password_url(@resource, reset_password_token: @token) %>
 
-如果不是的话,忘了它吧。只有你本人通过上面的链接设置新的密码以后你的新密码才会生效。
+如果你不想修改密码的话,还请忽略这封邮件哦。
+在你点击上面的链接并修改密码前,你的密码是不会改变的。