diff --git a/app/controllers/api/v1/accounts/email_subscriptions_controller.rb b/app/controllers/api/v1/accounts/email_subscriptions_controller.rb
new file mode 100644
index 0000000000..dcdd41f6db
--- /dev/null
+++ b/app/controllers/api/v1/accounts/email_subscriptions_controller.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class Api::V1::Accounts::EmailSubscriptionsController < Api::BaseController
+ before_action :set_account
+ before_action :require_feature_enabled!
+ before_action :require_account_permissions!
+
+ def create
+ @account.email_subscriptions.create!(email: params[:email], locale: I18n.locale)
+ render_empty
+ end
+
+ private
+
+ def set_account
+ @account = Account.local.find(params[:account_id])
+ end
+
+ def require_feature_enabled!
+ head 404 unless Mastodon::Feature.email_subscriptions_enabled?
+ end
+
+ def require_account_permissions!
+ head 404 if @account.unavailable? || !@account.user_can?(:manage_email_subscriptions) || !@account.user_email_subscriptions_enabled?
+ end
+end
diff --git a/app/controllers/email_subscriptions/confirmations_controller.rb b/app/controllers/email_subscriptions/confirmations_controller.rb
new file mode 100644
index 0000000000..2750b68d4f
--- /dev/null
+++ b/app/controllers/email_subscriptions/confirmations_controller.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class EmailSubscriptions::ConfirmationsController < ApplicationController
+ layout 'auth'
+
+ before_action :set_email_subscription
+
+ def show
+ @email_subscription.confirm! unless @email_subscription.confirmed?
+ end
+
+ private
+
+ def set_email_subscription
+ @email_subscription = EmailSubscription.find_by!(confirmation_token: params[:confirmation_token])
+ end
+end
diff --git a/app/controllers/mail_subscriptions_controller.rb b/app/controllers/mail_subscriptions_controller.rb
deleted file mode 100644
index 34df75f63a..0000000000
--- a/app/controllers/mail_subscriptions_controller.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# frozen_string_literal: true
-
-class MailSubscriptionsController < ApplicationController
- layout 'auth'
-
- skip_before_action :require_functional!
-
- before_action :set_user
- before_action :set_type
-
- protect_from_forgery with: :null_session
-
- def show; end
-
- def create
- @user.settings[email_type_from_param] = false
- @user.save!
- end
-
- private
-
- def set_user
- @user = GlobalID::Locator.locate_signed(params[:token], for: 'unsubscribe')
- not_found unless @user
- end
-
- def set_type
- @type = email_type_from_param
- end
-
- def email_type_from_param
- case params[:type]
- when 'follow', 'reblog', 'favourite', 'mention', 'follow_request'
- "notification_emails.#{params[:type]}"
- else
- not_found
- end
- end
-end
diff --git a/app/controllers/settings/privacy_controller.rb b/app/controllers/settings/privacy_controller.rb
index 96efa03ccf..2716fce806 100644
--- a/app/controllers/settings/privacy_controller.rb
+++ b/app/controllers/settings/privacy_controller.rb
@@ -2,6 +2,7 @@
class Settings::PrivacyController < Settings::BaseController
before_action :set_account
+ before_action :set_email_subscriptions_count
def show; end
@@ -24,4 +25,8 @@ class Settings::PrivacyController < Settings::BaseController
def set_account
@account = current_account
end
+
+ def set_email_subscriptions_count
+ @email_subscriptions_count = with_read_replica { @account.email_subscriptions.confirmed.count }
+ end
end
diff --git a/app/controllers/unsubscriptions_controller.rb b/app/controllers/unsubscriptions_controller.rb
new file mode 100644
index 0000000000..aac58a3806
--- /dev/null
+++ b/app/controllers/unsubscriptions_controller.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+class UnsubscriptionsController < ApplicationController
+ layout 'auth'
+
+ skip_before_action :require_functional!
+
+ before_action :set_recipient
+ before_action :set_type
+ before_action :set_scope
+ before_action :require_type_if_user!
+
+ protect_from_forgery with: :null_session
+
+ def show; end
+
+ def create
+ case @scope
+ when :user
+ @recipient.settings[@type] = false
+ @recipient.save!
+ when :email_subscription
+ @recipient.destroy!
+ end
+ end
+
+ private
+
+ def set_recipient
+ @recipient = GlobalID::Locator.locate_signed(params[:token], for: 'unsubscribe')
+ not_found unless @recipient
+ end
+
+ def set_scope
+ if @recipient.is_a?(User)
+ @scope = :user
+ elsif @recipient.is_a?(EmailSubscription)
+ @scope = :email_subscription
+ else
+ not_found
+ end
+ end
+
+ def set_type
+ @type = email_type_from_param
+ end
+
+ def require_type_if_user!
+ not_found if @recipient.is_a?(User) && @type.blank?
+ end
+
+ def email_type_from_param
+ case params[:type]
+ when 'follow', 'reblog', 'favourite', 'mention', 'follow_request'
+ "notification_emails.#{params[:type]}"
+ end
+ end
+end
diff --git a/app/javascript/styles/entrypoints/mailer.scss b/app/javascript/styles/entrypoints/mailer.scss
index fcbbd66f4c..725f4e4de4 100644
--- a/app/javascript/styles/entrypoints/mailer.scss
+++ b/app/javascript/styles/entrypoints/mailer.scss
@@ -721,6 +721,52 @@ table + p {
line-height: 24px;
}
+// Banner item
+.email-banner-table {
+ border-radius: 12px;
+ background-color: #1b001f;
+ background-image: url('../../images/mailer-new/common/header-bg-start.png');
+ background-position: left top;
+ background-repeat: repeat;
+}
+
+.email-banner-td {
+ padding: 24px 24px 14px;
+}
+
+.email-banner-text-td {
+ p {
+ margin: 0 0 12px;
+ color: #fff;
+ font-size: 14px;
+ font-weight: 600;
+ line-height: 16.8px;
+ }
+
+ .email-desktop-flex {
+ align-items: center;
+ }
+
+ .email-btn-table {
+ background-color: #fff;
+ }
+
+ .email-btn-td {
+ mso-padding-alt: 10px;
+ }
+
+ .email-btn-a {
+ color: #181820;
+ padding-left: 10px;
+ padding-right: 10px;
+ }
+
+ div + div {
+ margin-inline-start: auto;
+ margin-bottom: 12px;
+ }
+}
+
// Checklist item
.email-checklist-wrapper-td {
padding: 4px 0;
diff --git a/app/javascript/styles/mastodon/tables.scss b/app/javascript/styles/mastodon/tables.scss
index 8e303aff68..1088781417 100644
--- a/app/javascript/styles/mastodon/tables.scss
+++ b/app/javascript/styles/mastodon/tables.scss
@@ -93,6 +93,26 @@
}
}
+ &.mini-table {
+ border-top: 1px solid var(--color-border-primary);
+ width: 50%;
+
+ & > tbody > tr > th,
+ & > tbody > tr > td {
+ padding: 12px 0;
+ }
+
+ & > tbody > tr > th {
+ color: var(--color-text-secondary);
+ font-weight: 400;
+ }
+
+ & > tbody > tr > td {
+ color: var(--color-text-primary);
+ font-weight: 600;
+ }
+ }
+
&.batch-table {
& > thead > tr > th {
background: var(--color-bg-primary);
diff --git a/app/mailers/email_subscription_mailer.rb b/app/mailers/email_subscription_mailer.rb
new file mode 100644
index 0000000000..35bd6da2f9
--- /dev/null
+++ b/app/mailers/email_subscription_mailer.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+class EmailSubscriptionMailer < ApplicationMailer
+ include BulkMailSettingsConcern
+ include Redisable
+
+ layout 'mailer'
+
+ helper :accounts
+ helper :routing
+ helper :statuses
+
+ before_action :set_subscription
+ before_action :set_unsubscribe_url
+ before_action :set_instance
+ before_action :set_skip_preferences_link
+
+ after_action :use_bulk_mail_delivery_settings, except: [:confirmation]
+ after_action :set_list_headers
+
+ default to: -> { @subscription.email }
+
+ def confirmation
+ I18n.with_locale(locale) do
+ mail subject: default_i18n_subject
+ end
+ end
+
+ def notification(statuses)
+ @statuses = statuses
+
+ I18n.with_locale(locale) do
+ mail subject: default_i18n_subject(count: @statuses.size, name: @subscription.account.display_name, excerpt: @statuses.first.text.truncate(17))
+ end
+ end
+
+ private
+
+ def set_list_headers
+ headers(
+ 'List-ID' => "<#{@subscription.account.username}.#{Rails.configuration.x.local_domain}>",
+ 'List-Unsubscribe-Post' => 'List-Unsubscribe=One-Click',
+ 'List-Unsubscribe' => "<#{@unsubscribe_url}>"
+ )
+ end
+
+ def set_subscription
+ @subscription = params[:subscription]
+ end
+
+ def set_unsubscribe_url
+ @unsubscribe_url = unsubscribe_url(token: @subscription.to_sgid(for: 'unsubscribe').to_s)
+ end
+
+ def set_instance
+ @instance = Rails.configuration.x.local_domain
+ end
+
+ def set_skip_preferences_link
+ @skip_preferences_link = true
+ end
+
+ def locale
+ @subscription.locale.presence || I18n.default_locale
+ end
+end
diff --git a/app/models/account.rb b/app/models/account.rb
index ceb5f857a9..8c44db813a 100644
--- a/app/models/account.rb
+++ b/app/models/account.rb
@@ -193,8 +193,10 @@ class Account < ApplicationRecord
:role,
:locale,
:shows_application?,
+ :email_subscriptions_enabled?,
:prefers_noindex?,
:time_zone,
+ :can?,
to: :user,
prefix: true,
allow_nil: true
diff --git a/app/models/concerns/account/associations.rb b/app/models/concerns/account/associations.rb
index 089f08fc59..db2e996d0f 100644
--- a/app/models/concerns/account/associations.rb
+++ b/app/models/concerns/account/associations.rb
@@ -38,6 +38,7 @@ module Account::Associations
has_many :status_pins
has_many :statuses
has_many :keypairs
+ has_many :email_subscriptions
has_one :deletion_request, class_name: 'AccountDeletionRequest'
has_one :follow_recommendation_suppression
diff --git a/app/models/concerns/user/has_settings.rb b/app/models/concerns/user/has_settings.rb
index f46a2ac53d..4fa8ab53fa 100644
--- a/app/models/concerns/user/has_settings.rb
+++ b/app/models/concerns/user/has_settings.rb
@@ -15,6 +15,10 @@ module User::HasSettings
settings['noindex']
end
+ def email_subscriptions_enabled?
+ settings['email_subscriptions']
+ end
+
def preferred_posting_language
valid_locale_cascade(settings['default_language'], locale, I18n.locale)
end
diff --git a/app/models/email_subscription.rb b/app/models/email_subscription.rb
new file mode 100644
index 0000000000..a965f06e31
--- /dev/null
+++ b/app/models/email_subscription.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+# == Schema Information
+#
+# Table name: email_subscriptions
+#
+# id :bigint(8) not null, primary key
+# confirmation_token :string
+# confirmed_at :datetime
+# email :string not null
+# locale :string not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# account_id :bigint(8) not null
+#
+
+class EmailSubscription < ApplicationRecord
+ belongs_to :account
+
+ normalizes :email, with: ->(str) { str.squish.downcase }
+
+ validates :email, presence: true, email_address: true, uniqueness: { scope: :account_id }
+
+ scope :confirmed, -> { where.not(confirmed_at: nil) }
+ scope :unconfirmed, -> { where(confirmed_at: nil) }
+
+ before_create :set_confirmation_token
+
+ after_create_commit :send_confirmation_email
+
+ def confirmed?
+ confirmed_at.present?
+ end
+
+ def confirm!
+ touch(:confirmed_at)
+ end
+
+ private
+
+ def set_confirmation_token
+ self.confirmation_token = Devise.friendly_token unless confirmed?
+ end
+
+ def send_confirmation_email
+ EmailSubscriptionMailer.with(subscription: self).confirmation.deliver_later
+ end
+end
diff --git a/app/models/user_role.rb b/app/models/user_role.rb
index f2597e1c43..e98d9bc479 100644
--- a/app/models/user_role.rb
+++ b/app/models/user_role.rb
@@ -39,6 +39,7 @@ class UserRole < ApplicationRecord
delete_user_data: (1 << 19),
view_feeds: (1 << 20),
invite_bypass_approval: (1 << 21),
+ manage_email_subscriptions: (1 << 22),
}.freeze
EVERYONE_ROLE_ID = -99
@@ -60,6 +61,10 @@ class UserRole < ApplicationRecord
invite_bypass_approval
).freeze,
+ email: %i(
+ manage_email_subscriptions
+ ).freeze,
+
moderation: %i(
view_dashboard
view_audit_log
diff --git a/app/models/user_settings.rb b/app/models/user_settings.rb
index c5f02ae2e9..3a6e6f249b 100644
--- a/app/models/user_settings.rb
+++ b/app/models/user_settings.rb
@@ -16,6 +16,7 @@ class UserSettings
setting :default_sensitive, default: false
setting :default_privacy, default: nil, in: %w(public unlisted private)
setting :default_quote_policy, default: 'public', in: %w(public followers nobody)
+ setting :email_subscriptions, default: false
setting_inverse_alias :indexable, :noindex
diff --git a/app/serializers/rest/account_serializer.rb b/app/serializers/rest/account_serializer.rb
index e97baa8612..9fc5acee9d 100644
--- a/app/serializers/rest/account_serializer.rb
+++ b/app/serializers/rest/account_serializer.rb
@@ -22,6 +22,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
attribute :memorial, if: :memorial?
attribute :feature_approval, if: -> { Mastodon::Feature.collections_enabled? }
+ attribute :email_subscriptions, if: -> { Mastodon::Feature.email_subscriptions_enabled? }
class AccountDecorator < SimpleDelegator
def self.model_name
@@ -176,4 +177,8 @@ class REST::AccountSerializer < ActiveModel::Serializer
current_user: object.feature_policy_for_account(current_user&.account),
}
end
+
+ def email_subscriptions
+ object.user_can?(:manage_email_subscriptions) && object.user_email_subscriptions_enabled?
+ end
end
diff --git a/app/services/post_status_service.rb b/app/services/post_status_service.rb
index e44ddda54c..3ef1502cd6 100644
--- a/app/services/post_status_service.rb
+++ b/app/services/post_status_service.rb
@@ -5,6 +5,12 @@ class PostStatusService < BaseService
include Lockable
include LanguagesHelper
+ # How much to delay sending an e-mail about a new post, to allow grouping multiple posts
+ EMAIL_DISTRIBUTION_DELAY = 5.minutes.freeze
+
+ # If the job is not executed within this timeframe, it will lose its arguments
+ EMAIL_DISTRIBUTION_TTL = 1.hour.to_i
+
class UnexpectedMentionsError < StandardError
attr_reader :accounts
@@ -158,11 +164,26 @@ class PostStatusService < BaseService
Trends.tags.register(@status)
LinkCrawlWorker.perform_async(@status.id)
DistributionWorker.perform_async(@status.id)
+ process_email_subscriptions!
ActivityPub::DistributionWorker.perform_async(@status.id)
PollExpirationNotifyWorker.perform_at(@status.poll.expires_at, @status.poll.id) if @status.poll
ActivityPub::QuoteRequestWorker.perform_async(@status.quote.id) if @status.quote&.quoted_status.present? && !@status.quote&.quoted_status&.local?
end
+ def process_email_subscriptions!
+ return unless Mastodon::Feature.email_subscriptions_enabled? &&
+ @status.public_visibility? && (!@status.reply? || @status.in_reply_to_account_id == @status.account_id) &&
+ @status.account.user_can?(:manage_email_subscriptions) &&
+ @status.account.user_email_subscriptions_enabled?
+
+ # To allow e-mail grouping, pass the arguments via a redis set and schedule
+ # a unique worker a few minutes in the future, in case the user makes subsequent
+ # posts within that time window
+ redis.sadd("email_subscriptions:#{@status.account_id}:next_batch", @status.id)
+ redis.expire("email_subscriptions:#{@status.account_id}:next_batch", EMAIL_DISTRIBUTION_TTL)
+ EmailDistributionWorker.perform_in(EMAIL_DISTRIBUTION_DELAY, @status.account_id)
+ end
+
def validate_media!
if @options[:media_ids].blank? || !@options[:media_ids].is_a?(Enumerable)
@media = []
diff --git a/app/views/email_subscription_mailer/confirmation.html.haml b/app/views/email_subscription_mailer/confirmation.html.haml
new file mode 100644
index 0000000000..7d14d9ff59
--- /dev/null
+++ b/app/views/email_subscription_mailer/confirmation.html.haml
@@ -0,0 +1,20 @@
+= content_for :heading do
+ = render 'application/mailer/heading',
+ image_url: full_asset_url(@subscription.account.avatar.url),
+ title: t('.title', name: display_name(@subscription.account))
+
+%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
+ %tr
+ %td.email-body-padding-td
+ %table.email-inner-card-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
+ %tr
+ %td.email-inner-card-td.email-prose
+ %p= t '.instructions_to_confirm', name: display_name(@subscription.account), acct: "#{@subscription.account.username}@#{@instance}"
+
+ = render 'application/mailer/button', text: t('.action'), url: email_subscriptions_confirmation_url(confirmation_token: @subscription.confirmation_token)
+
+ %p= t '.instructions_to_ignore'
+
+- content_for :footer do
+ %p.email-footer-p= t('email_subscription_mailer.notification.footer.reason_for_email_html', name: display_name(@subscription.account), unsubscribe_path: @unsubscribe_url)
+ %p.email-footer-p= t('email_subscription_mailer.notification.footer.privacy_html', domain: @instance, privacy_policy_path: privacy_policy_path)
diff --git a/app/views/email_subscription_mailer/confirmation.text.erb b/app/views/email_subscription_mailer/confirmation.text.erb
new file mode 100644
index 0000000000..4d80bebc0d
--- /dev/null
+++ b/app/views/email_subscription_mailer/confirmation.text.erb
@@ -0,0 +1,9 @@
+<%= t '.title', name: display_name(@subscription.account) %>
+
+===
+
+<%= t '.instructions_to_confirm', name: display_name(@subscription.account), acct: "#{@subscription.account.username}@#{@instance}" %>
+
+=> <%= root_url(confirmation_token: @subscription.confirmation_token) %>
+
+<%= t '.instructions_to_ignore' %>
diff --git a/app/views/email_subscription_mailer/notification.html.haml b/app/views/email_subscription_mailer/notification.html.haml
new file mode 100644
index 0000000000..ad816ba460
--- /dev/null
+++ b/app/views/email_subscription_mailer/notification.html.haml
@@ -0,0 +1,36 @@
+%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
+ - @statuses.each do |status|
+ %tr
+ %td.email-body-padding-td
+ %table.email-inner-card-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
+ %tr
+ %td.email-inner-card-td
+ = render 'notification_mailer/status', status: status, time_zone: nil
+
+%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
+ %tr
+ %td.email-body-padding-td
+ %table.email-w-full.email-checklist-wrapper-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
+ %tr
+ %td.email-checklist-wrapper-td
+ %table.email-w-full.email-banner-table{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
+ %tr
+ %td.email-banner-td
+ %table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
+ %tr
+ %td.email-banner-text-td
+ .email-desktop-flex
+ /[if mso]
+
|
+ %div
+ %p= t('.interact_with_this_post', count: @statuses.size)
+ /[if mso]
+ |
+ %div
+ = render 'application/mailer/button', text: t('.create_account'), url: available_sign_up_path, has_arrow: false
+ /[if mso]
+ |
+
+- content_for :footer do
+ %p.email-footer-p= t('.footer.reason_for_email_html', name: display_name(@subscription.account), unsubscribe_path: @unsubscribe_url)
+ %p.email-footer-p= t('.footer.privacy_html', domain: @instance, privacy_policy_path: privacy_policy_path)
diff --git a/app/views/email_subscription_mailer/notification.text.erb b/app/views/email_subscription_mailer/notification.text.erb
new file mode 100644
index 0000000000..7da5261b64
--- /dev/null
+++ b/app/views/email_subscription_mailer/notification.text.erb
@@ -0,0 +1,7 @@
+<%= t '.title', count: @statuses.size, name: display_name(@subscription.account), excerpt: truncate(@statuses.first.text, length: 17) %>
+
+===
+
+<%- @statuses.each do |status| %>
+<%= render 'notification_mailer/status', status: status %>
+<%- end %>
diff --git a/app/views/email_subscriptions/confirmations/show.html.haml b/app/views/email_subscriptions/confirmations/show.html.haml
new file mode 100644
index 0000000000..a13504bb48
--- /dev/null
+++ b/app/views/email_subscriptions/confirmations/show.html.haml
@@ -0,0 +1,11 @@
+- content_for :page_title do
+ = t('.title')
+
+.simple_form
+ %h1.title
+ = t('.title')
+ %p.lead
+ = t('.success_html', name: content_tag(:strong, display_name(@email_subscription.account)), sender: content_tag(:strong, EmailSubscriptionMailer.default[:from]))
+ %p.lead
+ = t('.changed_your_mind')
+ = link_to t('.unsubscribe'), unsubscribe_url(token: @email_subscription.to_sgid(for: 'unsubscribe'))
diff --git a/app/views/layouts/mailer.html.haml b/app/views/layouts/mailer.html.haml
index 842312b853..5862f79712 100644
--- a/app/views/layouts/mailer.html.haml
+++ b/app/views/layouts/mailer.html.haml
@@ -12,6 +12,7 @@
%style{ 'data-premailer': 'ignore' }
\.email a { color: inherit; text-decoration: none; }
\.email-btn-hover:hover { background-color: #563acc !important; }
+ \.email-banner-text-td .email-btn-hover:hover { background-color: #fff !important; }
/[if mso]
@@ -73,15 +74,18 @@
%table.email-w-full{ cellspacing: 0, cellpadding: 0, border: 0, role: 'presentation' }
%tr
%td.email-footer-td
- %p.email-footer-p
- = link_to root_url, class: 'email-footer-logo-a' do
- = image_tag frontend_asset_url('images/mailer-new/common/logo-footer.png'), alt: 'Mastodon', width: 44, height: 44
- %p.email-footer-p
- = t 'about.hosted_on', domain: site_hostname
- %p.email-footer-p
- = link_to t('application_mailer.notification_preferences'), settings_preferences_notifications_url
- - if defined?(@unsubscribe_url)
- ·
- = link_to t('application_mailer.unsubscribe'), @unsubscribe_url
+ - if content_for?(:footer)
+ = yield :footer
+ - else
+ %p.email-footer-p
+ = link_to root_url, class: 'email-footer-logo-a' do
+ = image_tag frontend_asset_url('images/mailer-new/common/logo-footer.png'), alt: 'Mastodon', width: 44, height: 44
+ %p.email-footer-p
+ = t 'about.hosted_on', domain: site_hostname
+ %p.email-footer-p
+ = link_to t('application_mailer.notification_preferences'), settings_preferences_notifications_url
+ - if defined?(@unsubscribe_url)
+ ·
+ = link_to t('application_mailer.unsubscribe'), @unsubscribe_url
/[if mso]
diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb
index 87b0b2929c..1a78f33110 100644
--- a/app/views/layouts/mailer.text.erb
+++ b/app/views/layouts/mailer.text.erb
@@ -1,5 +1,9 @@
<%= yield %>
---
-<%= t 'about.hosted_on', domain: site_hostname %>
-<%= t('application_mailer.settings', link: settings_preferences_url) %>
+<%- unless defined?(@skip_preferences_link) %>
+<%= t('application_mailer.notification_preferences') %>: <%= settings_preferences_url %>
+<%- end %>
+<%- if defined?(@unsubscribe_url) %>
+<%= t('application_mailer.unsubscribe') %>: <%= @unsubscribe_url %>
+<%- end %>
diff --git a/app/views/mail_subscriptions/create.html.haml b/app/views/mail_subscriptions/create.html.haml
deleted file mode 100644
index 16ee486b00..0000000000
--- a/app/views/mail_subscriptions/create.html.haml
+++ /dev/null
@@ -1,9 +0,0 @@
-- content_for :page_title do
- = t('mail_subscriptions.unsubscribe.title')
-
-.simple_form
- %h1.title= t('mail_subscriptions.unsubscribe.complete')
- %p.lead
- = t('mail_subscriptions.unsubscribe.success_html', domain: content_tag(:strong, site_hostname), type: content_tag(:strong, I18n.t(@type, scope: 'mail_subscriptions.unsubscribe.emails')), email: content_tag(:strong, @user.email))
- %p.lead
- = t('mail_subscriptions.unsubscribe.resubscribe_html', settings_path: settings_preferences_notifications_path)
diff --git a/app/views/mail_subscriptions/show.html.haml b/app/views/mail_subscriptions/show.html.haml
deleted file mode 100644
index 78de486457..0000000000
--- a/app/views/mail_subscriptions/show.html.haml
+++ /dev/null
@@ -1,20 +0,0 @@
-- content_for :page_title do
- = t('mail_subscriptions.unsubscribe.title')
-
-.simple_form
- %h1.title= t('mail_subscriptions.unsubscribe.title')
- %p.lead
- = t 'mail_subscriptions.unsubscribe.confirmation_html',
- domain: content_tag(:strong, site_hostname),
- type: content_tag(:strong, I18n.t(@type, scope: 'mail_subscriptions.unsubscribe.emails')),
- email: content_tag(:strong, @user.email),
- settings_path: settings_preferences_notifications_path
-
- = form_with url: unsubscribe_path do |form|
- = form.hidden_field :token,
- value: params[:token]
- = form.hidden_field :type,
- value: params[:type]
- = form.button t('mail_subscriptions.unsubscribe.action'),
- type: :submit,
- class: 'btn'
diff --git a/app/views/settings/privacy/show.html.haml b/app/views/settings/privacy/show.html.haml
index 542d7b34a2..282f63f19e 100644
--- a/app/views/settings/privacy/show.html.haml
+++ b/app/views/settings/privacy/show.html.haml
@@ -41,5 +41,25 @@
.fields-group
= ff.input :show_application, wrapper: :with_label
+ - if Mastodon::Feature.email_subscriptions_enabled? && current_user.can?(:manage_email_subscriptions)
+ %h2= t('privacy.email_subscriptions')
+
+ %p.lead= t('privacy.email_subscriptions_hint_html')
+
+ - if @email_subscriptions_count.positive? || @account.user_email_subscriptions_enabled?
+ .table-wrapper
+ %table.table.mini-table
+ %tbody
+ %tr
+ %th= t('email_subscriptions.status')
+ %td= @account.user_email_subscriptions_enabled? ? t('email_subscriptions.active') : t('email_subscriptions.inactive')
+ %tr
+ %th= t('email_subscriptions.subscribers')
+ %td= number_with_delimiter @email_subscriptions_count
+
+ = f.simple_fields_for :settings, current_user.settings do |ff|
+ .fields-group
+ = ff.input :email_subscriptions, wrapper: :with_label
+
.actions
= f.button :button, t('generic.save_changes'), type: :submit
diff --git a/app/views/unsubscriptions/create.html.haml b/app/views/unsubscriptions/create.html.haml
new file mode 100644
index 0000000000..157cf26226
--- /dev/null
+++ b/app/views/unsubscriptions/create.html.haml
@@ -0,0 +1,12 @@
+- content_for :page_title do
+ = t('.title')
+
+.simple_form
+ %h1.title= t('.title')
+ %p.lead
+ - if @scope == :email_subscription
+ = t('.email_subscription.confirmation_html', name: display_name(@recipient.account))
+ - elsif @scope == :user
+ = t('.user.confirmation_html', type: I18n.t(@type, scope: 'unsubscriptions.notification_emails'), domain: site_hostname)
+
+ = link_to t('.action'), root_path, class: 'btn'
diff --git a/app/views/unsubscriptions/show.html.haml b/app/views/unsubscriptions/show.html.haml
new file mode 100644
index 0000000000..6f5f007612
--- /dev/null
+++ b/app/views/unsubscriptions/show.html.haml
@@ -0,0 +1,26 @@
+- content_for :page_title do
+ - if @scope == :user
+ = t('.user.title', type: I18n.t(@type, scope: 'unsubscriptions.notification_emails'))
+ - elsif @scope == :email_subscription
+ = t('.email_subscription.title', name: display_name(@recipient.account))
+
+.simple_form
+ %h1.title
+ - if @scope == :user
+ = t('.user.title', type: I18n.t(@type, scope: 'unsubscriptions.notification_emails'))
+ - elsif @scope == :email_subscription
+ = t('.email_subscription.title', name: display_name(@recipient.account))
+ %p.lead
+ - if @scope == :user
+ = t('.user.confirmation_html')
+ - elsif @scope == :email_subscription
+ = t('.email_subscription.confirmation_html')
+
+ = form_with url: unsubscribe_path do |form|
+ = form.hidden_field :token,
+ value: params[:token]
+ = form.hidden_field :type,
+ value: params[:type]
+ = form.button t('.action'),
+ type: :submit,
+ class: 'btn'
diff --git a/app/workers/email_distribution_worker.rb b/app/workers/email_distribution_worker.rb
new file mode 100644
index 0000000000..41edcb932c
--- /dev/null
+++ b/app/workers/email_distribution_worker.rb
@@ -0,0 +1,37 @@
+# frozen_string_literal: true
+
+class EmailDistributionWorker
+ include Sidekiq::Worker
+ include Redisable
+
+ sidekiq_options lock: :until_executed, lock_ttl: 1.day.to_i
+
+ def perform(account_id)
+ return unless Mastodon::Feature.email_subscriptions_enabled?
+
+ @account = Account.find(account_id)
+
+ return unless @account.user_can?(:manage_email_subscriptions) && @account.user_email_subscriptions_enabled?
+
+ with_redis do |redis|
+ @status_ids = redis.smembers("email_subscriptions:#{account_id}:next_batch")
+ redis.srem("email_subscriptions:#{account_id}:next_batch", @status_ids)
+ end
+
+ return if @account.email_subscriptions.confirmed.empty? || @status_ids.empty?
+
+ statuses = Status.without_replies
+ .without_reblogs
+ .public_visibility
+ .where(id: @status_ids)
+ .to_a
+
+ return if statuses.empty?
+
+ @account.email_subscriptions.confirmed.find_each do |email_subscription|
+ EmailSubscriptionMailer.with(subscription: email_subscription).notification(statuses).deliver_later
+ end
+ rescue ActiveRecord::RecordNotFound
+ nil
+ end
+end
diff --git a/app/workers/scheduler/user_cleanup_scheduler.rb b/app/workers/scheduler/user_cleanup_scheduler.rb
index 03544e2e98..20d895551a 100644
--- a/app/workers/scheduler/user_cleanup_scheduler.rb
+++ b/app/workers/scheduler/user_cleanup_scheduler.rb
@@ -11,6 +11,7 @@ class Scheduler::UserCleanupScheduler
def perform
clean_unconfirmed_accounts!
clean_discarded_statuses!
+ clean_unconfirmed_email_subscriptions!
end
private
@@ -32,4 +33,10 @@ class Scheduler::UserCleanupScheduler
end
end
end
+
+ def clean_unconfirmed_email_subscriptions!
+ EmailSubscription.unconfirmed.where(created_at: ..UNCONFIRMED_ACCOUNTS_MAX_AGE_DAYS.days.ago).find_in_batches do |batch|
+ EmailSubscription.where(id: batch.map(&:id)).delete_all
+ end
+ end
end
diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml
index b934696bda..49858b22d1 100644
--- a/config/i18n-tasks.yml
+++ b/config/i18n-tasks.yml
@@ -65,6 +65,7 @@ ignore_unused:
- 'move_handler.carry_{mutes,blocks}_over_text'
- 'admin_mailer.*.subject'
- 'user_mailer.*.subject'
+ - 'email_subscription_mailer.*'
- 'notification_mailer.*'
- 'imports.overwrite_preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html.*'
- 'imports.preambles.{following,blocking,muting,domain_blocking,bookmarks,lists}_html.*'
diff --git a/config/locales/ar.yml b/config/locales/ar.yml
index f689f79007..218b12a065 100644
--- a/config/locales/ar.yml
+++ b/config/locales/ar.yml
@@ -1267,7 +1267,6 @@ ar:
application_mailer:
notification_preferences: تغيير تفضيلات البريد الإلكتروني
salutation: "%{name}،"
- settings: 'تغيير تفضيلات البريد الإلكتروني: %{link}'
unsubscribe: إلغاء الاشتراك
view: 'اعرض:'
view_profile: اعرض الصفحة التعريفية
@@ -1764,9 +1763,6 @@ ar:
title: تاريخ المصادقة
mail_subscriptions:
unsubscribe:
- action: نعم، ألغِ الاشتراك
- complete: غير مشترك
- confirmation_html: هل أنت متأكد أنك تريد إلغاء الاشتراك عن تلقي %{type} لماستدون على %{domain} إلى بريدك الإلكتروني %{email}؟ يمكنك دائمًا إعادة الاشتراك من إعدادات إشعارات البريد الإلكتروني.
emails:
notification_emails:
favourite: إرسال إشعارات التفضيلات بالبريد الإلكتروني
@@ -1774,9 +1770,6 @@ ar:
follow_request: إرسال إشعارات الطلبات بالبريد الإلكتروني
mention: إشعارات رسائل البريد عندما يَذكُرك أحدهم
reblog: رسائل البريد الخاصة بالمنشورات المعاد نشرها
- resubscribe_html: إذا قمت بإلغاء الاشتراك عن طريق الخطأ، يمكنك إعادة الاشتراك من إعدادات إشعارات البريد الإلكتروني.
- success_html: لن تتلقّ بعد الآن %{type} لماستدون مِن %{domain} على بريدك الإلكتروني %{email}.
- title: إلغاء الاشتراك
media_attachments:
validations:
images_and_video: ليس بالإمكان إرفاق فيديو في منشور يحتوي مسبقا على صور
diff --git a/config/locales/be.yml b/config/locales/be.yml
index 9d06a26030..7a30f3a6ec 100644
--- a/config/locales/be.yml
+++ b/config/locales/be.yml
@@ -1273,7 +1273,6 @@ be:
application_mailer:
notification_preferences: Змяніць налады эл. пошты
salutation: "%{name},"
- settings: 'Змяніць налады эл. пошты: %{link}'
unsubscribe: Адпісацца
view: 'Паглядзець:'
view_profile: Паглядзець профіль
@@ -1737,9 +1736,6 @@ be:
title: Гісторыя ўваходаў
mail_subscriptions:
unsubscribe:
- action: Так, адпісацца
- complete: Адпісаны
- confirmation_html: Вы ўпэўнены, што жадаеце адмовіцца ад атрымання %{type} з Mastodon на дамене %{domain} на сваю электронную пошту %{email}? Вы заўсёды можаце паўторна падпісацца ў наладах апавяшчэнняў па электроннай пошце.
emails:
notification_emails:
favourite: апавяшчэнні на пошту пра упадабанае
@@ -1747,9 +1743,6 @@ be:
follow_request: апавяшчэнні на пошту пра запыты на падпіску
mention: апавяшчэнні на пошту пра згадванні
reblog: апавяшчэнні на пошту пра пашырэнні
- resubscribe_html: Калі вы адмовіліся ад падпіскі памылкова, вы можаце зноў падпісацца ў наладах апавяшчэнняў па электроннай пошце.
- success_html: Вы больш не будзеце атрымліваць %{type} на сваю электронную пошту %{email} ад Mastodon на дамене %{domain}.
- title: Адпісацца
media_attachments:
validations:
images_and_video: Немагчыма далучыць відэа да допісу, які ўжо змяшчае выявы
diff --git a/config/locales/bg.yml b/config/locales/bg.yml
index 514cb2f6e9..35ef73d521 100644
--- a/config/locales/bg.yml
+++ b/config/locales/bg.yml
@@ -1186,7 +1186,6 @@ bg:
application_mailer:
notification_preferences: Промяна на предпочитанията за е-поща
salutation: "%{name},"
- settings: 'Промяна на предпочитанията за имейл: %{link}'
unsubscribe: Стоп на абонамента
view: 'Преглед:'
view_profile: Преглед на профила
@@ -1601,9 +1600,6 @@ bg:
title: Историята на удостоверяване
mail_subscriptions:
unsubscribe:
- action: Да, да се спре абонамента
- complete: Спрян абонамент
- confirmation_html: Наистина ли искате да спрете абонамента от получаването на %{type} за Mastodon в %{domain} към имейла си при %{email}? Може винаги пак да се абонирате от своите настройки за известяване по е-поща.
emails:
notification_emails:
favourite: е-писма за известия с любими
@@ -1611,9 +1607,6 @@ bg:
follow_request: е-писма със заявки за следване
mention: е-писма с известия за споменаване
reblog: е-писма с известия за подсилване
- resubscribe_html: Ако погрешка сте спрели абонамента, то може пак да се абонирате от своите настройки за известия по е-поща.
- success_html: Повече няма да получавате %{type} за Mastodon на %{domain} към имейла си при %{email}.
- title: Спиране на абонамента
media_attachments:
validations:
images_and_video: Не мога да прикача видеоклип към публикация, която вече съдържа изображения
diff --git a/config/locales/br.yml b/config/locales/br.yml
index c1b2906548..850d7dc093 100644
--- a/config/locales/br.yml
+++ b/config/locales/br.yml
@@ -683,9 +683,6 @@ br:
authentication_methods:
password: ger-tremen
webauthn: alc’hwezioù surentez
- mail_subscriptions:
- unsubscribe:
- action: Ya, digoumanantiñ
media_attachments:
validations:
images_and_video: N'haller stagañ ur video ouzh un embannadur a zo fotoioù gantañ dija
diff --git a/config/locales/ca.yml b/config/locales/ca.yml
index a7ef2e7c38..6ac65afd6f 100644
--- a/config/locales/ca.yml
+++ b/config/locales/ca.yml
@@ -1194,7 +1194,6 @@ ca:
application_mailer:
notification_preferences: Canviar les preferències de correu-e
salutation: "%{name},"
- settings: 'Canviar les preferències de correu-e: %{link}'
unsubscribe: Cancel·la la subscripció
view: 'Visualització:'
view_profile: Mostra el perfil
@@ -1616,9 +1615,6 @@ ca:
title: Historial d'autenticació
mail_subscriptions:
unsubscribe:
- action: Sí, canceŀla la subscripció
- complete: Subscripció cancel·lada
- confirmation_html: Segur que vols donar-te de baixa de rebre %{type} de Mastodon a %{domain} a %{email}? Sempre pots subscriure't de nou des de la configuració de les notificacions per correu electrònic.
emails:
notification_emails:
favourite: notificacions dels favorits per correu electrònic
@@ -1626,9 +1622,6 @@ ca:
follow_request: correus electrònics de peticions de seguiment
mention: correus electrònics de notificacions de mencions
reblog: correus electrònics de notificacions d'impulsos
- resubscribe_html: Si ets dones de baixa per error pots donar-te d'alta des de la configuració de les notificacions per correu electrònic.
- success_html: Ja no rebràs %{type} de Mastodon a %{domain} a %{email}.
- title: Cancel·la la subscripció
media_attachments:
validations:
images_and_video: No es pot adjuntar un vídeo a una publicació que ja contingui imatges
diff --git a/config/locales/cs.yml b/config/locales/cs.yml
index 0d324d1453..6b2bfd4539 100644
--- a/config/locales/cs.yml
+++ b/config/locales/cs.yml
@@ -1267,7 +1267,6 @@ cs:
application_mailer:
notification_preferences: Změnit předvolby e-mailu
salutation: "%{name},"
- settings: 'Změnit předvolby e-mailu: %{link}'
unsubscribe: Přestat odebírat
view: 'Zobrazit:'
view_profile: Zobrazit profil
@@ -1729,9 +1728,6 @@ cs:
title: Historie přihlášení
mail_subscriptions:
unsubscribe:
- action: Ano, odeberte odběr
- complete: Odběr byl odhlášen
- confirmation_html: Jste si jisti, že chcete odhlásit odběr %{type} pro Mastodon na %{domain} na váš e-mail %{email}? Vždy se můžete znovu přihlásit ve svém nastavení e-mailových oznámení.
emails:
notification_emails:
favourite: e-mailové oznámení při oblíbení
@@ -1739,9 +1735,6 @@ cs:
follow_request: e-mail při žádost o sledování
mention: e-mailové oznámení při zmínění
reblog: e-mailové oznámení při boostu
- resubscribe_html: Pokud jste se odhlásili omylem, můžete se znovu přihlásit ve svých nastavení e-mailových oznámení.
- success_html: Již nebudete dostávat %{type} pro Mastodon na %{domain} na vaši e-mailovou adresu %{email}.
- title: Odhlásit odběr
media_attachments:
validations:
images_and_video: K příspěvku, který již obsahuje obrázky, nelze připojit video
diff --git a/config/locales/cy.yml b/config/locales/cy.yml
index 560bc3e6f3..a81826d7c2 100644
--- a/config/locales/cy.yml
+++ b/config/locales/cy.yml
@@ -1313,7 +1313,6 @@ cy:
application_mailer:
notification_preferences: Newid dewisiadau e-bost
salutation: "%{name},"
- settings: 'Newid dewisiadau e-bost: %{link}'
unsubscribe: Dad-danysgrifio
view: 'Gweld:'
view_profile: Gweld proffil
@@ -1817,9 +1816,6 @@ cy:
title: Hanes dilysu
mail_subscriptions:
unsubscribe:
- action: Iawn, dad-danysgrifio
- complete: Dad-danysgrifiwyd
- confirmation_html: Ydych chi'n siŵr eich bod am ddad-danysgrifio rhag derbyn %{type} Mastodon ar %{domain} i'ch e-bost yn %{email}? Gallwch ail-danysgrifio o'ch gosodiadau hysbysu e-bost rhywbryd eto.
emails:
notification_emails:
favourite: e-bost hysbysu hoffi
@@ -1827,9 +1823,6 @@ cy:
follow_request: e-byst ceisiadau dilyn
mention: e-byst hysbysu crybwylliadau
reblog: e-byst hysbysiadau hybu
- resubscribe_html: Os ydych wedi dad-danysgrifio trwy gamgymeriad, gallwch ail-danysgrifio drwy'ch gosodiadau hysbysu e-bost.
- success_html: Ni fyddwch bellach yn derbyn %{type} ar gyfer Mastodon ar %{domain} i'ch e-bost am %{email}.
- title: Dad-danysgrifio
media_attachments:
validations:
images_and_video: Methu atodi fideo i bostiad sydd eisoes yn cynnwys delweddau
diff --git a/config/locales/da.yml b/config/locales/da.yml
index c83750d58c..ca3d45aca3 100644
--- a/config/locales/da.yml
+++ b/config/locales/da.yml
@@ -1231,7 +1231,6 @@ da:
application_mailer:
notification_preferences: Skift e-mailpræferencer
salutation: "%{name}"
- settings: 'Skift e-mailpræferencer: %{link}'
unsubscribe: Afmeld notifikationer
view: 'Vis:'
view_profile: Vis profil
@@ -1655,9 +1654,6 @@ da:
title: Godkendelseshistorik
mail_subscriptions:
unsubscribe:
- action: Ja, afmeld
- complete: Afmeldt
- confirmation_html: Er du sikker på, at du vil afmelde modtagelse af %{type} for Mastodon på %{domain} til din e-mail på %{email}? Du kan altid tilmelde dig igen fra dine indstillinger for e-mail-notifikationer.
emails:
notification_emails:
favourite: e-mailnotifikationer om favoritmarkeringer
@@ -1665,9 +1661,6 @@ da:
follow_request: e-mailnotifikationer om følgeanmodninger
mention: e-mailnotifikationer om omtaler
reblog: e-mailnotifikationer om fremhævelser
- resubscribe_html: Har du afmeldt dig ved en fejl, kan du gentilmelde dig via indstillingerne for e-mail-notifikationer.
- success_html: Du vil ikke længere modtage %{type} for Mastodon på %{domain} til din e-mail %{email}.
- title: Opsig abonnement
media_attachments:
validations:
images_and_video: En video kan ikke vedhæftes et indlæg med billedindhold
diff --git a/config/locales/de.yml b/config/locales/de.yml
index 4981257442..f95f2f7940 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -1231,7 +1231,6 @@ de:
application_mailer:
notification_preferences: E-Mail-Einstellungen ändern
salutation: "%{name},"
- settings: 'E-Mail-Einstellungen ändern: %{link}'
unsubscribe: Abbestellen
view: 'Siehe:'
view_profile: Profil anzeigen
@@ -1655,9 +1654,6 @@ de:
title: Anmeldeverlauf
mail_subscriptions:
unsubscribe:
- action: Ja, abbestellen
- complete: Abbestellt
- confirmation_html: Möchtest du %{type} für Mastodon auf %{domain} an deine E-Mail-Adresse %{email} wirklich abbestellen? Du kannst dies später in den Einstellungen Benachrichtigungen per E-Mail rückgängig machen.
emails:
notification_emails:
favourite: E-Mail-Benachrichtigungen bei Favoriten
@@ -1665,9 +1661,6 @@ de:
follow_request: E-Mail-Benachrichtigungen bei Follower-Anfragen
mention: E-Mail-Benachrichtigungen bei Erwähnungen
reblog: E-Mail-Benachrichtigungen bei geteilten Beiträgen
- resubscribe_html: Falls du etwas irrtümlich abbestellt hast, kannst du das in den Einstellungen Benachrichtigungen per E-Mail rückgängig machen.
- success_html: Du wirst nicht länger %{type} für Mastodon auf %{domain} an deine E-Mail-Adresse %{email} erhalten.
- title: Abbestellen
media_attachments:
validations:
images_and_video: Es kann kein Video an einen Beitrag angehängt werden, der bereits Bilder enthält
diff --git a/config/locales/el.yml b/config/locales/el.yml
index de95a5b725..5b834356fb 100644
--- a/config/locales/el.yml
+++ b/config/locales/el.yml
@@ -1231,7 +1231,6 @@ el:
application_mailer:
notification_preferences: Αλλαγή προτιμήσεων email
salutation: "%{name},"
- settings: 'Αλλαγή προτιμήσεων email: %{link}'
unsubscribe: Κατάργηση εγγραφής
view: 'Προβολή:'
view_profile: Προβολή προφίλ
@@ -1655,9 +1654,6 @@ el:
title: Ιστορικό ελέγχου ταυτότητας
mail_subscriptions:
unsubscribe:
- action: Ναι, κατάργηση συνδρομής
- complete: Η συνδρομή καταργήθηκε
- confirmation_html: Σίγουρα θες να καταργήσεις την εγγραφή σου για %{type} για το Mastodon στο %{domain} στο email σου %{email}; Μπορείς πάντα να εγγραφείς ξανά από τις ρυθμίσεις ειδοποιήσεων email.
emails:
notification_emails:
favourite: ειδοποιήσεις email για αγαπημένα
@@ -1665,9 +1661,6 @@ el:
follow_request: email για αιτήματα ακολούθησης
mention: ειδοποιήσεις email για επισημάνσεις
reblog: ειδοποιήσεις email για ενίσχυση
- resubscribe_html: Αν έχεις καταργήσει την εγγραφή σου κατά λάθος, μπορείς να εγγραφείς εκ νέου από τις ρυθμίσεις ειδοποίησης email.
- success_html: Δεν θα λαμβάνεις πλέον %{type} για το Mastodon στο %{domain} στο email σου στο %{email}.
- title: Κατάργηση συνδρομής
media_attachments:
validations:
images_and_video: Δεν γίνεται να προσθέσεις βίντεο σε ανάρτηση που ήδη περιέχει εικόνες
diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml
index 815378fbdd..81843c2c4d 100644
--- a/config/locales/en-GB.yml
+++ b/config/locales/en-GB.yml
@@ -1229,7 +1229,6 @@ en-GB:
application_mailer:
notification_preferences: Change email preferences
salutation: "%{name},"
- settings: 'Change email preferences: %{link}'
unsubscribe: Unsubscribe
view: 'View:'
view_profile: View profile
@@ -1651,9 +1650,6 @@ en-GB:
title: Authentication history
mail_subscriptions:
unsubscribe:
- action: Yes, unsubscribe
- complete: Unsubscribed
- confirmation_html: Are you sure you want to unsubscribe from receiving %{type} for Mastodon on %{domain} to your email at %{email}? You can always re-subscribe from your email notification settings.
emails:
notification_emails:
favourite: favourite notification emails
@@ -1661,9 +1657,6 @@ en-GB:
follow_request: follow request emails
mention: mention notification emails
reblog: boost notification emails
- resubscribe_html: If you've unsubscribed by mistake, you can re-subscribe from your email notification settings.
- success_html: You'll no longer receive %{type} for Mastodon on %{domain} to your email at %{email}.
- title: Unsubscribe
media_attachments:
validations:
images_and_video: Cannot attach a video to a post that already contains images
diff --git a/config/locales/en.yml b/config/locales/en.yml
index a745021dc1..97c4809aa3 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -762,6 +762,7 @@ en:
categories:
administration: Administration
devops: DevOps
+ email: Email
invites: Invites
moderation: Moderation
special: Special
@@ -790,6 +791,8 @@ en:
manage_blocks_description: Allows users to block email providers and IP addresses
manage_custom_emojis: Manage Custom Emojis
manage_custom_emojis_description: Allows users to manage custom emojis on the server
+ manage_email_subscriptions: Manage Email Subscriptions
+ manage_email_subscriptions_description: Allow users to subscribe to users with this permission by email
manage_federation: Manage Federation
manage_federation_description: Allows users to block or allow federation with other domains, and control deliverability
manage_invites: Manage Invites
@@ -1231,7 +1234,6 @@ en:
application_mailer:
notification_preferences: Change email preferences
salutation: "%{name},"
- settings: 'Change email preferences: %{link}'
unsubscribe: Unsubscribe
view: 'View:'
view_profile: View profile
@@ -1419,6 +1421,38 @@ en:
basic_information: Basic information
hint_html: "Customize what people see on your public profile and next to your posts. Other people are more likely to follow you back and interact with you when you have a filled out profile and a profile picture."
other: Other
+ email_subscription_mailer:
+ confirmation:
+ action: Confirm email address
+ instructions_to_confirm: Confirm you'd like to receive emails from %{name} (@%{acct}) when they publish new posts.
+ instructions_to_ignore: If you're not sure why you received this email, you can delete it. You will not be subscribed if you don't click on the link above.
+ subject: Confirm your email address
+ title: Get email updates from %{name}?
+ notification:
+ create_account: Create a Mastodon account
+ footer:
+ privacy_html: Emails are sent from %{domain}, a server powered by Mastodon. To understand how this server processes your personal data, refer to the Privacy Policy.
+ reason_for_email_html: You're receiving this email because you opted into email updates from %{name}. Don't want to receive these emails? Unsubscribe
+ interact_with_this_post:
+ one: Interact with this post and discover more like it.
+ other: Interact with these posts and discover more.
+ subject:
+ one: 'New post: "%{excerpt}"'
+ other: New posts from %{name}
+ title:
+ one: 'New post: "%{excerpt}"'
+ other: New posts from %{name}
+ email_subscriptions:
+ active: Active
+ confirmations:
+ show:
+ changed_your_mind: Changed your mind?
+ success_html: You'll now start receiving emails when %{name} publishes new posts. Add %{sender} to your contacts so these posts don't end up in your Spam folder.
+ title: You're signed up
+ unsubscribe: Unsubscribe
+ inactive: Inactive
+ status: Status
+ subscribers: Subscribers
emoji_styles:
auto: Auto
native: Native
@@ -1653,21 +1687,6 @@ en:
failed_sign_in_html: Failed sign-in attempt with %{method} from %{ip} (%{browser})
successful_sign_in_html: Successful sign-in with %{method} from %{ip} (%{browser})
title: Authentication history
- mail_subscriptions:
- unsubscribe:
- action: Yes, unsubscribe
- complete: Unsubscribed
- confirmation_html: Are you sure you want to unsubscribe from receiving %{type} for Mastodon on %{domain} to your email at %{email}? You can always re-subscribe from your email notification settings.
- emails:
- notification_emails:
- favourite: favorite notification emails
- follow: follow notification emails
- follow_request: follow request emails
- mention: mention notification emails
- reblog: boost notification emails
- resubscribe_html: If you've unsubscribed by mistake, you can re-subscribe from your email notification settings.
- success_html: You'll no longer receive %{type} for Mastodon on %{domain} to your email at %{email}.
- title: Unsubscribe
media_attachments:
validations:
images_and_video: Cannot attach a video to a post that already contains images
@@ -1806,6 +1825,8 @@ en:
posting_defaults: Posting defaults
public_timelines: Public timelines
privacy:
+ email_subscriptions: Send posts via email
+ email_subscriptions_hint_html: Add an email sign-up form to your profile that appears for logged-out users. When visitors enter their email address and opt in, Mastodon will send email updates for your public posts.
hint_html: "Customize how you want your profile and your posts to be found. A variety of features in Mastodon can help you reach a wider audience when enabled. Take a moment to review these settings to make sure they fit your use case."
privacy: Privacy
privacy_hint_html: Control how much you want to disclose for the benefit of others. People discover interesting profiles and cool apps by browsing other people's follows and seeing which apps they post from, but you may prefer to keep it hidden.
@@ -2069,6 +2090,28 @@ en:
resume_app_authorization: Resume application authorization
role_requirement: "%{domain} requires you to set up Two-Factor Authentication before you can use Mastodon."
webauthn: Security keys
+ unsubscriptions:
+ create:
+ action: Go to server homepage
+ email_subscription:
+ confirmation_html: You'll no longer receive emails from %{name}.
+ title: You are unsubscribed
+ user:
+ confirmation_html: You'll no longer receive %{type} from Mastodon on %{domain}.
+ notification_emails:
+ favourite: favorite notification emails
+ follow: follow notification emails
+ follow_request: follow request emails
+ mention: mention notification emails
+ reblog: boost notification emails
+ show:
+ action: Unsubscribe
+ email_subscription:
+ confirmation_html: You'll stop receiving emails when this account publishes new posts.
+ title: Unsubscribe from %{name}?
+ user:
+ confirmation_html: You'll stop receiving %{type} from Mastodon on %{domain}.
+ title: Unsubscribe from %{type}?
user_mailer:
announcement_published:
description: 'The administrators of %{domain} are making an announcement:'
diff --git a/config/locales/eo.yml b/config/locales/eo.yml
index de46b0a7be..d9712beb53 100644
--- a/config/locales/eo.yml
+++ b/config/locales/eo.yml
@@ -1182,7 +1182,6 @@ eo:
application_mailer:
notification_preferences: Ŝanĝi retpoŝtajn preferojn
salutation: "%{name},"
- settings: 'Ŝanĝi retpoŝtajn preferojn: %{link}'
unsubscribe: Malabonu
view: 'Vidi:'
view_profile: Vidi profilon
@@ -1592,9 +1591,6 @@ eo:
title: Aŭtentiga historio
mail_subscriptions:
unsubscribe:
- action: Jes, malabonu
- complete: Malabonita
- confirmation_html: Ĉu vi certas, ke vi volas malaboni je ricevi %{type} por Mastodon ĉe %{domain} al via retpoŝto ĉe %{email}? Vi ĉiam povas reaboni de viaj retpoŝtaj sciigaj agordoj.
emails:
notification_emails:
favourite: sciigoj retpoŝtaj de ŝatataj
@@ -1602,9 +1598,6 @@ eo:
follow_request: retpoŝtajn petoj de sekvado
mention: sciigoj retpoŝtaj de mencioj
reblog: sciigoj retpoŝtaj de diskonigoj
- resubscribe_html: Se vi malabonis erare, vi povas reaboni de viaj retpoŝtaj sciigaj agordoj.
- success_html: Vi ne plu ricevos %{type} por Mastodon ĉe %{domain} al via retpoŝto ĉe %{email}.
- title: Malaboni
media_attachments:
validations:
images_and_video: Aldoni videon al mesaĝo, kiu jam havas bildojn ne eblas
diff --git a/config/locales/es-AR.yml b/config/locales/es-AR.yml
index e4c8e85622..248c3db979 100644
--- a/config/locales/es-AR.yml
+++ b/config/locales/es-AR.yml
@@ -1231,7 +1231,6 @@ es-AR:
application_mailer:
notification_preferences: Cambiar configuración de correo electrónico
salutation: "%{name}:"
- settings: 'Cambiar configuración de correo electrónico: %{link}'
unsubscribe: Desuscribirse
view: 'Visitá:'
view_profile: Ver perfil
@@ -1655,9 +1654,6 @@ es-AR:
title: Historial de autenticación
mail_subscriptions:
unsubscribe:
- action: Sí, desuscribir
- complete: Desuscripto
- confirmation_html: ¿Estás seguro que querés dejar de recibir %{type} de Mastodon en %{domain} a tu correo electrónico %{email}? Siempre podrás volver a suscribirte desde la configuración de notificaciones por correo electrónico..
emails:
notification_emails:
favourite: notificaciones de favoritos por correo electrónico
@@ -1665,9 +1661,6 @@ es-AR:
follow_request: notificaciones de solicitudes de seguimiento por correo electrónico
mention: notificaciones de menciones por correo electrónico
reblog: notificaciones de adhesiones por correo electrónico
- resubscribe_html: Si te desuscribiste por error, podés resuscribirte desde la configuración de notificaciones por correo electrónico.
- success_html: Ya no recibirás %{type} de mastodon en %{domain} a tu correo electrónico %{email}.
- title: Desuscribirse
media_attachments:
validations:
images_and_video: No se puede adjuntar un video a un mensaje que ya contenga imágenes
diff --git a/config/locales/es-MX.yml b/config/locales/es-MX.yml
index 44677285a7..48e19919f0 100644
--- a/config/locales/es-MX.yml
+++ b/config/locales/es-MX.yml
@@ -1231,7 +1231,6 @@ es-MX:
application_mailer:
notification_preferences: Cambiar preferencias de correo electrónico
salutation: "%{name}:"
- settings: 'Cambiar preferencias de correo: %{link}'
unsubscribe: Cancelar suscripción
view: 'Vista:'
view_profile: Ver perfil
@@ -1655,9 +1654,6 @@ es-MX:
title: Historial de autenticación
mail_subscriptions:
unsubscribe:
- action: Sí, darse de baja
- complete: Has cancelado tu suscripción
- confirmation_html: ¿Estás seguro de que quieres dejar de recibir %{type} de Mastodon en %{domain} a tu correo %{email}? Siempre podrás volver a suscribirte de nuevo desde los ajustes de notificación por correo.
emails:
notification_emails:
favourite: correos de notificación de favoritos
@@ -1665,9 +1661,6 @@ es-MX:
follow_request: correos electrónicos de solicitud de seguimiento
mention: correos de notificación de menciones
reblog: correos de notificación de impulsos
- resubscribe_html: Si te has dado de baja por error, puedes volver a darte de alta desde tus ajustes de notificaciones por correo.
- success_html: Ya no recibirás %{type} de Mastodon en %{domain} a tu correo %{email}.
- title: Cancelar suscripción
media_attachments:
validations:
images_and_video: No se puede adjuntar un video a una publicación que ya contenga imágenes
diff --git a/config/locales/es.yml b/config/locales/es.yml
index c7de434673..15c7d44ba5 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -1231,7 +1231,6 @@ es:
application_mailer:
notification_preferences: Cambiar preferencias de correo electrónico
salutation: "%{name}:"
- settings: 'Cambiar preferencias de correo: %{link}'
unsubscribe: Cancelar suscripción
view: 'Vista:'
view_profile: Ver perfil
@@ -1655,9 +1654,6 @@ es:
title: Historial de autenticación
mail_subscriptions:
unsubscribe:
- action: Sí, cancelar suscripción
- complete: Has cancelado tu suscripción
- confirmation_html: ¿Estás seguro de que quieres dejar de recibir %{type} de Mastodon en %{domain} a tu correo %{email}? Siempre podrás volver a suscribirte de nuevo desde los ajustes de notificación por correo.
emails:
notification_emails:
favourite: correos de notificación de favoritos
@@ -1665,9 +1661,6 @@ es:
follow_request: correos de notificación de solicitud de seguidor
mention: correos de notificación de menciones
reblog: correos de notificación de impulsos
- resubscribe_html: Si te has dado de baja por error, puedes volver a darte de alta desde tus ajustes de notificaciones por correo.
- success_html: Ya no recibirás %{type} de Mastodon en %{domain} a tu correo %{email}.
- title: Cancelar suscripición
media_attachments:
validations:
images_and_video: No se puede adjuntar un video a una publicación que ya contenga imágenes
diff --git a/config/locales/et.yml b/config/locales/et.yml
index ddd0572cfc..91b227b5aa 100644
--- a/config/locales/et.yml
+++ b/config/locales/et.yml
@@ -1214,7 +1214,6 @@ et:
application_mailer:
notification_preferences: Muuda e-posti eelistusi
salutation: "%{name}!"
- settings: 'Muuda e-posti eelistusi: %{link}'
unsubscribe: Loobu tellimisest
view: 'Vaade:'
view_profile: Vaata profiili
@@ -1636,9 +1635,6 @@ et:
title: Autentimise ajalugu
mail_subscriptions:
unsubscribe:
- action: Jah, lõpeta tellimine
- complete: Tellimine lõpetatud
- confirmation_html: Kas oled kindel, et soovid loobuda %{type} tellimisest oma e-postiaadressile %{email} Mastodonist kohas %{domain}? Saad alati uuesti tellida oma e-posti teavituste seadetest.
emails:
notification_emails:
favourite: lemmikuks märkimise teavituskirjade
@@ -1646,9 +1642,6 @@ et:
follow_request: jälgimistaotluste teavituskirjade
mention: mainimiste teavituskirjade
reblog: jagamiste teavituskirjade
- resubscribe_html: Kui loobusid tellimisest ekslikult, saad uuesti tellida oma e-posti teavituste seadetest.
- success_html: Sa ei saa enam %{type} teateid oma e-postile %{email} Mastodonist kohas %{domain}.
- title: Loobu tellimisest
media_attachments:
validations:
images_and_video: Ei saa lisada video postitusele, milles on juba pildid
diff --git a/config/locales/eu.yml b/config/locales/eu.yml
index 0102508797..41a6d57895 100644
--- a/config/locales/eu.yml
+++ b/config/locales/eu.yml
@@ -1171,7 +1171,6 @@ eu:
application_mailer:
notification_preferences: Posta elektronikoaren lehentasunak aldatu
salutation: "%{name},"
- settings: 'Posta elektronikoaren lehentasunak aldatu: %{link}'
unsubscribe: Kendu harpidetza
view: 'Ikusi:'
view_profile: Ikusi profila
@@ -1538,11 +1537,6 @@ eu:
title: Autentifikazioen historia
mail_subscriptions:
unsubscribe:
- action: Bai, kendu harpidetza
- complete: Harpidetza kenduta
- confirmation_html: |-
- Ziur Mastodonen %{domain} zerbitzariko %{type} %{email} helbide elektronikoan jasotzeari utzi nahi diozula?
- Beti harpidetu zaitezke berriro eposta jakinarazpenen hobespenetan.
emails:
notification_emails:
favourite: zure argitalpena gogoko egin dutenaren jakinarazpen e-mailak
@@ -1550,9 +1544,6 @@ eu:
follow_request: jarraipen-eskaeren jakinarazpen e-mailak
mention: aipamenen jakinarazpen e-mailak
reblog: bultzaden jakinarazpen e-mailak
- resubscribe_html: Nahi gabe utzi badiozu jakinarazpenak jasotzeari, berriro harpidetu zaitezke e-mail jakinarazpenen hobespenetan.
- success_html: Ez duzu Mastodonen %{domain} zerbitzariko %{type} jasoko %{email} helbide elektronikoan.
- title: Kendu harpidetza
media_attachments:
validations:
images_and_video: Ezin da irudiak dituen bidalketa batean bideo bat erantsi
diff --git a/config/locales/fa.yml b/config/locales/fa.yml
index b166d1f304..1fd310cb8f 100644
--- a/config/locales/fa.yml
+++ b/config/locales/fa.yml
@@ -1210,7 +1210,6 @@ fa:
application_mailer:
notification_preferences: تغییر ترجیحات رایانامه
salutation: "%{name}،"
- settings: 'تغییر ترجیحات رایانامه: %{link}'
unsubscribe: لغو اشتراک
view: 'نمایش:'
view_profile: دیدن نمایه
@@ -1632,9 +1631,6 @@ fa:
title: تاریخچهٔ تأیید هویت
mail_subscriptions:
unsubscribe:
- action: بله. لغو اشتراک
- complete: لغو اشتراک شد
- confirmation_html: مطمئنید که میخواهید اشتراک %{type} را از ماستودون روی %{domain} برای رایانامهٔ %{email} لغو کنید؟ همواره میتوانید از تنظیمات آگاهی رایانامهای دوباره مشترک شوید.
emails:
notification_emails:
favourite: رایانامههای آگاهی برگزیدن
@@ -1642,9 +1638,6 @@ fa:
follow_request: رایانامههای درخواست پیگیری
mention: رایانامههای آگاهی اشاره
reblog: رایانامههای آگاهی تقویت
- resubscribe_html: اگر اشتراک را اشتباهی لغو کردید میتوانید از تنظیمات آگاهی رایانامهای دوباره مشترک شوید.
- success_html: دیگر %{type} را از ماستودون روی %{domain} برای رایانامهٔ %{email} نخواهید گرفت.
- title: لغو اشتراک
media_attachments:
validations:
images_and_video: نمیتوان برای نوشتهای که تصویر دارد ویدیو بارگذاری کرد
diff --git a/config/locales/fi.yml b/config/locales/fi.yml
index 77d938b6b7..782d59c315 100644
--- a/config/locales/fi.yml
+++ b/config/locales/fi.yml
@@ -1231,7 +1231,6 @@ fi:
application_mailer:
notification_preferences: Muuta sähköpostiasetuksia
salutation: "%{name}"
- settings: 'Muuta sähköpostiasetuksia: %{link}'
unsubscribe: Lopeta tilaus
view: 'Näytä:'
view_profile: Näytä profiili
@@ -1655,9 +1654,6 @@ fi:
title: Todennushistoria
mail_subscriptions:
unsubscribe:
- action: Kyllä, peru tilaus
- complete: Tilaus lopetettiin
- confirmation_html: Haluatko varmasti lopettaa Mastodonin sähköposti-ilmoitusten vastaanottamisen aiheesta %{type} palvelimelta %{domain} osoitteeseesi %{email}? Voit tilata ilmoitusviestejä milloin tahansa uudelleen sähköposti-ilmoitusten asetuksista.
emails:
notification_emails:
favourite: sähköposti-ilmoituksia suosikkeihin lisäämisistä
@@ -1665,9 +1661,6 @@ fi:
follow_request: sähköposti-ilmoituksia seurantapyynnöistä
mention: sähköposti-ilmoituksia maininnoista
reblog: sähköposti-ilmoituksia tehostuksista
- resubscribe_html: Jos olet perunut tilauksen erehdyksessä, voit tilata ilmoitusviestejä uudelleen sähköposti-ilmoitusten asetuksista.
- success_html: Sinulle ei enää lähetetä Mastodonin %{type} palvelimelta %{domain} osoitteeseen %{email}.
- title: Lopeta tilaus
media_attachments:
validations:
images_and_video: Videota ei voi liittää tilapäivitykseen, jossa on jo kuvia
diff --git a/config/locales/fo.yml b/config/locales/fo.yml
index 36b2dc5c68..49e768f4a3 100644
--- a/config/locales/fo.yml
+++ b/config/locales/fo.yml
@@ -1229,7 +1229,6 @@ fo:
application_mailer:
notification_preferences: Broyt teldupostastillingar
salutation: "%{name}"
- settings: 'Broyt teldupostastillingar: %{link}'
unsubscribe: Strika hald
view: 'Vís:'
view_profile: Vís vanga
@@ -1651,9 +1650,6 @@ fo:
title: Samgildissøga
mail_subscriptions:
unsubscribe:
- action: Ja, strika hald
- complete: Hald strikað
- confirmation_html: Ert tú vís/ur í, at tú vil gevast at móttaka %{type} fyri Mastodon á %{domain} til tína teldupostadressu á %{email}? Tú kanst altíð gera haldið virkið aftur frá tínum teldupostfráboðanarstillingum.
emails:
notification_emails:
favourite: yndisfráboðanarteldupostar
@@ -1661,9 +1657,6 @@ fo:
follow_request: fylg umbønir um teldupost
mention: nevn fráboðanarteldupostar
reblog: framhevja fráboðanarpostar
- resubscribe_html: Um tú hevur strikað haldið av misgávum, so kanst tú tekna haldið av nýggjum í tínum teldupostfráboðarstillingum.
- success_html: Tú fer ikki longur at móttaka %{type} fyri Mastodon á %{domain} til tín teldupost á %{email}.
- title: Strika hald
media_attachments:
validations:
images_and_video: Kann ikki viðfesta sjónfílu til ein post, sum longu inniheldur myndir
diff --git a/config/locales/fr-CA.yml b/config/locales/fr-CA.yml
index 14e7e5a3d8..dca8edc581 100644
--- a/config/locales/fr-CA.yml
+++ b/config/locales/fr-CA.yml
@@ -1234,7 +1234,6 @@ fr-CA:
application_mailer:
notification_preferences: Modification des préférences de la messagerie
salutation: "%{name},"
- settings: 'Modifier les préférences de la messagerie : %{link}'
unsubscribe: Se désabonner
view: 'Voir :'
view_profile: Voir le profil
@@ -1658,9 +1657,6 @@ fr-CA:
title: Historique d'authentification
mail_subscriptions:
unsubscribe:
- action: Oui, me désabonner
- complete: Désabonné·e
- confirmation_html: Êtes-vous sûr de vouloir vous désabonner de la réception de %{type} pour Mastodon sur %{domain} à votre adresse e-mail %{email} ? Vous pouvez toujours vous réabonner à partir de vos paramètres de notification par messagerie.
emails:
notification_emails:
favourite: e-mails de notifications de favoris
@@ -1668,9 +1664,6 @@ fr-CA:
follow_request: e-mails de demandes d’abonnements
mention: e-mails de notifications de mentions
reblog: e-mails de notifications de partages
- resubscribe_html: Si vous vous êtes désinscrit par erreur, vous pouvez vous réinscrire à partir de vos paramètres de notification par e-mail.
- success_html: Vous ne recevrez plus de %{type} pour Mastodon sur %{domain} à votre adresse e-mail à %{email}.
- title: Se désabonner
media_attachments:
validations:
images_and_video: Impossible de joindre une vidéo à un message contenant déjà des images
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 3407c4515b..7b7968b7ce 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -1234,7 +1234,6 @@ fr:
application_mailer:
notification_preferences: Modification des préférences de la messagerie
salutation: "%{name},"
- settings: 'Modifier les préférences de la messagerie : %{link}'
unsubscribe: Se désabonner
view: 'Voir :'
view_profile: Voir le profil
@@ -1658,9 +1657,6 @@ fr:
title: Historique d'authentification
mail_subscriptions:
unsubscribe:
- action: Oui, se désinscrire
- complete: Désinscrit
- confirmation_html: Êtes-vous sûr de vouloir vous désabonner de la réception de %{type} pour Mastodon sur %{domain} à votre adresse e-mail %{email} ? Vous pouvez toujours vous réabonner à partir de vos paramètres de notification par messagerie.
emails:
notification_emails:
favourite: e-mails de notifications de favoris
@@ -1668,9 +1664,6 @@ fr:
follow_request: e-mails de demandes d’abonnements
mention: e-mails de notifications de mentions
reblog: e-mails de notifications de partages
- resubscribe_html: Si vous vous êtes désinscrit par erreur, vous pouvez vous réinscrire à partir de vos paramètres de notification par e-mail.
- success_html: Vous ne recevrez plus de %{type} pour Mastodon sur %{domain} à votre adresse e-mail à %{email}.
- title: Se désinscrire
media_attachments:
validations:
images_and_video: Impossible de joindre une vidéo à un message contenant déjà des images
diff --git a/config/locales/fy.yml b/config/locales/fy.yml
index 4959b1adaa..c017132e75 100644
--- a/config/locales/fy.yml
+++ b/config/locales/fy.yml
@@ -1189,7 +1189,6 @@ fy:
application_mailer:
notification_preferences: E-mailynstellingen wizigje
salutation: "%{name},"
- settings: 'E-mailfoarkarren wizigje: %{link}'
unsubscribe: Ofmelde
view: 'Besjoch:'
view_profile: Profyl besjen
@@ -1597,9 +1596,6 @@ fy:
title: Oanmeldskiednis
mail_subscriptions:
unsubscribe:
- action: Ja, ôfmelde
- complete: Ofmelden
- confirmation_html: Binne jo wis dat jo jo ôfmelde wolle foar it ûntfangen fan %{type} fan Mastodon op %{domain} op jo e-mailadres %{email}? Jo kinne jo altyd opnij abonnearje yn jo ynstellingen foar e-mailmeldingen.
emails:
notification_emails:
favourite: e-mailmeldingen foar favoriten
@@ -1607,9 +1603,6 @@ fy:
follow_request: e-mailmeldingen foar folchfersiken
mention: e-mailmeldingen foar fermeldingen
reblog: e-mailmeldingen foar boosts
- resubscribe_html: As jo jo mei fersin ôfmeld hawwe, kinne jo jo opnij abonnearje yn jo ynstellingen foar e-mailmeldingen.
- success_html: Jo ûntfange net langer %{type} fan Mastodon op %{domain} op jo e-mailadres %{email}.
- title: Ofmelde
media_attachments:
validations:
images_and_video: In fideo kin net oan in berjocht mei ôfbyldingen keppele wurde
diff --git a/config/locales/ga.yml b/config/locales/ga.yml
index 1295a4efc5..d75af42526 100644
--- a/config/locales/ga.yml
+++ b/config/locales/ga.yml
@@ -1296,7 +1296,6 @@ ga:
application_mailer:
notification_preferences: Athraigh roghanna ríomhphoist
salutation: "%{name},"
- settings: 'Athraigh sainroghanna ríomhphoist: %{link}'
unsubscribe: Díliostáil
view: 'Amharc:'
view_profile: Féach ar phróifíl
@@ -1780,9 +1779,6 @@ ga:
title: Stair fíordheimhnithe
mail_subscriptions:
unsubscribe:
- action: Sea, díliostáil
- complete: Gan liostáil
- confirmation_html: An bhfuil tú cinnte gur mhaith leat díliostáil ó %{type} a fháil do Mastodon ar %{domain} chuig do ríomhphost ag %{email}? Is féidir leat liostáil arís i gcónaí ó do socruithe fógra ríomhphoist.
emails:
notification_emails:
favourite: ríomhphoist fógra is fearr leat
@@ -1790,9 +1786,6 @@ ga:
follow_request: lean ríomhphoist iarratais
mention: trácht ar ríomhphoist fógra
reblog: ríomhphoist fógraí a threisiú
- resubscribe_html: Má dhíliostáil tú de dhearmad, is féidir leat liostáil arís ó do socruithe fógra ríomhphoist.
- success_html: Ní bhfaighidh tú %{type} le haghaidh Mastodon ar %{domain} chuig do ríomhphost ag %{email} a thuilleadh.
- title: Díliostáil
media_attachments:
validations:
images_and_video: Ní féidir físeán a cheangal le postáil a bhfuil íomhánna ann cheana féin
diff --git a/config/locales/gd.yml b/config/locales/gd.yml
index c619e7818b..fc11600ca4 100644
--- a/config/locales/gd.yml
+++ b/config/locales/gd.yml
@@ -1248,7 +1248,6 @@ gd:
application_mailer:
notification_preferences: Atharraich roghainnean a’ phuist-d
salutation: "%{name},"
- settings: 'Atharraich roghainnean a’ phuist-d: %{link}'
unsubscribe: Cuir crìoch air an fho-sgrìobhadh
view: 'Faic:'
view_profile: Seall a’ phròifil
@@ -1710,9 +1709,6 @@ gd:
title: Eachdraidh an dearbhaidh
mail_subscriptions:
unsubscribe:
- action: Tha, cuir crìoch air an fho-sgrìobhadh
- complete: Chaidh crìoch a chur air an fho-sgrìobhadh
- confirmation_html: A bheil thu cinnteach nach eil thu airson %{type} fhaighinn tuilleadh o Mhastodon air %{domain} dhan post-d agad aig %{email}? ’S urrainn dhut fo-sgrìobhadh a-rithist uair sam bith o roghainnean a’ puist-d agad.
emails:
notification_emails:
favourite: puist-d le brathan mu annsachdan
@@ -1720,9 +1716,6 @@ gd:
follow_request: puist-d le brathan mu iarrtasan leantainn
mention: puist-d le brathan mu iomraidhean
reblog: puist-d le brathan mu bhrosnachaidhean
- resubscribe_html: Ma chuir thu crìoch air an fho-sgrìobhadh le mearachd, ’s urrainn dhut fo-sgrìobhadh a-rithist o roghainnean a’ puist-d agad.
- success_html: Chan fhaigh thu %{type} o Mhastodon air %{domain} dhan phost-d agad aig %{email} tuilleadh.
- title: Cuir crìoch air an fho-sgrìobhadh
media_attachments:
validations:
images_and_video: Chan urrainn dhut video a cheangal ri post sa bheil dealbh mu thràth
diff --git a/config/locales/gl.yml b/config/locales/gl.yml
index 469f7badd7..307029de98 100644
--- a/config/locales/gl.yml
+++ b/config/locales/gl.yml
@@ -1231,7 +1231,6 @@ gl:
application_mailer:
notification_preferences: Cambiar preferencias de correo
salutation: "%{name},"
- settings: 'Cambiar preferencias de correo: %{link}'
unsubscribe: Anular subscrición
view: 'Vista:'
view_profile: Ver perfil
@@ -1655,9 +1654,6 @@ gl:
title: Historial de autenticación
mail_subscriptions:
unsubscribe:
- action: Si, retirar subscrición
- complete: Subscrición anulada
- confirmation_html: Tes a certeza de querer retirar a subscrición a Mastodon en %{domain} para recibir %{type} no teu correo electrónico en %{email}? Poderás volver a subscribirte desde os axustes de notificacións por correo.
emails:
notification_emails:
favourite: notificacións de favorecidas
@@ -1665,9 +1661,6 @@ gl:
follow_request: notificacións de solicitudes de seguimento
mention: notificacións de mencións
reblog: notificacións de promocións
- resubscribe_html: Se por un erro eliminaches a subscrición, podes volver a subscribirte desde os axustes de notificacións por correo electrónico.
- success_html: Non vas recibir %{type} de Mastodon en %{domain} no enderezo %{email}.
- title: Anular subscrición
media_attachments:
validations:
images_and_video: Non podes anexar un vídeo a unha publicación que xa contén imaxes
diff --git a/config/locales/he.yml b/config/locales/he.yml
index d18d44689d..2fe1446b4e 100644
--- a/config/locales/he.yml
+++ b/config/locales/he.yml
@@ -1273,7 +1273,6 @@ he:
application_mailer:
notification_preferences: שינוי העדפות דוא"ל
salutation: "%{name},"
- settings: 'שינוי הגדרות דוא"ל: %{link}'
unsubscribe: בטל מנוי
view: 'תצוגה:'
view_profile: צפיה בפרופיל
@@ -1737,9 +1736,6 @@ he:
title: הסטוריית אימותים
mail_subscriptions:
unsubscribe:
- action: כן, לבטל הרשמה
- complete: הפסקת הרשמה
- confirmation_html: יש לאשר את ביטול ההרשמה להודעות %{type} ממסטודון בשרת %{domain} לכתובת הדואל %{email}. תמיד אפשר להרשם מחדש בכיוונוני הודעות דואל.
emails:
notification_emails:
favourite: הודעות דואל לגבי חיבובים
@@ -1747,9 +1743,6 @@ he:
follow_request: הודעות דואל לגבי בקשות מעקב
mention: הודעות דואל לגבי איזכורים
reblog: הודעות דואל לגבי הידהודים
- resubscribe_html: אם ביטול ההרשמה היה בטעות, ניתן להרשם מחדש מתוך מסך הגדרות ההרשמה שלך.
- success_html: לא יגיעו אליך יותר הודעות %{type} משרת מסטודון %{domain} לכתובת הדואל %{email}.
- title: הפסקת הרשמה
media_attachments:
validations:
images_and_video: לא ניתן להוסיף וידאו להודעה שכבר מכילה תמונות
diff --git a/config/locales/hu.yml b/config/locales/hu.yml
index f8cbce5cc3..921f05f2b8 100644
--- a/config/locales/hu.yml
+++ b/config/locales/hu.yml
@@ -1231,7 +1231,6 @@ hu:
application_mailer:
notification_preferences: E-mail-beállítások módosítása
salutation: "%{name}!"
- settings: 'E-mail-beállítások módosítása: %{link}'
unsubscribe: Leiratkozás
view: 'Megtekintés:'
view_profile: Profil megtekintése
@@ -1655,9 +1654,6 @@ hu:
title: Hitelesítési történet
mail_subscriptions:
unsubscribe:
- action: Igen, leiratkozás
- complete: Leiratkozva
- confirmation_html: 'Biztos, hogy leiratkozol arról, hogy %{type} típusú üzeneteket kapj a(z) %{domain} Mastodon-kiszolgálótól erre a címedre: %{email}? Bármikor újra feliratkozhatsz az e-mail-értesítési beállításokban.'
emails:
notification_emails:
favourite: kedvencnek jelölés értesítő e-mailjei
@@ -1665,9 +1661,6 @@ hu:
follow_request: követési kérések e-mailjei
mention: megemlítés értesítő e-mailjei
reblog: megtolás értesítő e-mailjei
- resubscribe_html: Ha tévedésből iratkoztál le, újra feliratkozhatsz az e-mail-értesítési beállításoknál.
- success_html: 'Mostantól nem kapsz %{type} típusú üzeneket a(z) %{domain} Mastodon-kiszolgálón erre a címedre: %{email}.'
- title: Leiratkozás
media_attachments:
validations:
images_and_video: Nem csatolhatsz videót olyan bejegyzéshez, amelyhez már csatoltál képet
diff --git a/config/locales/ia.yml b/config/locales/ia.yml
index 3fea1ed91c..f090d52469 100644
--- a/config/locales/ia.yml
+++ b/config/locales/ia.yml
@@ -1207,7 +1207,6 @@ ia:
application_mailer:
notification_preferences: Cambiar preferentias de e-mail
salutation: "%{name},"
- settings: 'Cambiar preferentias de e-mail: %{link}'
unsubscribe: Cancellar subscription
view: 'Visita:'
view_profile: Vider profilo
@@ -1622,9 +1621,6 @@ ia:
title: Historia de authentication
mail_subscriptions:
unsubscribe:
- action: Si, cancellar subscription
- complete: Desubscribite
- confirmation_html: Es tu secur de voler cancellar le subscription al %{type} de Mastodon sur %{domain} pro tu adresse de e-mail %{email}? Tu pote sempre resubscriber te a partir del parametros de notification in e-mail.
emails:
notification_emails:
favourite: notificationes de favorites in e-mail
@@ -1632,9 +1628,6 @@ ia:
follow_request: requestas de sequimento in e-mail
mention: notificationes de mentiones in e-mail
reblog: notificationes de impulsos in e-mail
- resubscribe_html: Si tu ha cancellate le subscription in error, tu pote resubscriber te a partir del parametros de notification in e-mail.
- success_html: Tu non recipera plus %{type} pro Mastodon sur %{domain} a tu adresse de e-mail %{email}.
- title: Desubcriber
media_attachments:
validations:
images_and_video: Impossibile annexar un video a un message que jam contine imagines
diff --git a/config/locales/ie.yml b/config/locales/ie.yml
index 1576504444..b28cbbb70b 100644
--- a/config/locales/ie.yml
+++ b/config/locales/ie.yml
@@ -1328,11 +1328,6 @@ ie:
failed_sign_in_html: Fallit prova de apertion de session per %{method} de %{ip} (%{browser})
successful_sign_in_html: Successosi apertion de session per %{method} de %{ip} (%{browser})
title: Historie de autentication
- mail_subscriptions:
- unsubscribe:
- action: Yes, desabonnar
- complete: Desabonnat
- title: Desabonnar
media_attachments:
validations:
images_and_video: On ne posse atachar un video a un posta quel ja contene images
diff --git a/config/locales/io.yml b/config/locales/io.yml
index 58ae0f015d..85aa06234a 100644
--- a/config/locales/io.yml
+++ b/config/locales/io.yml
@@ -1104,7 +1104,6 @@ io:
application_mailer:
notification_preferences: Chanjar retpostopreferaji
salutation: "%{name},"
- settings: 'Chanjar retpostopreferaji: %{link}'
unsubscribe: Desabonez
view: 'Vidar:'
view_profile: Videz profilo
@@ -1461,11 +1460,6 @@ io:
failed_sign_in_html: Falita enirprob per %{method} de %{ip} (%{browser})
successful_sign_in_html: Sucesoza eniro per %{method} de %{ip} (%{browser})
title: Yurizeshistorio
- mail_subscriptions:
- unsubscribe:
- action: Yes, desabonez
- complete: Desabonita
- title: Desabonez
media_attachments:
validations:
images_and_video: Ne povas addonar video ad afisho qua ja enhavas imaji
diff --git a/config/locales/is.yml b/config/locales/is.yml
index 1ea18a39d4..77a4feb512 100644
--- a/config/locales/is.yml
+++ b/config/locales/is.yml
@@ -1233,7 +1233,6 @@ is:
application_mailer:
notification_preferences: Breyta kjörstillingum tölvupósts
salutation: "%{name},"
- settings: 'Breyta kjörstillingum tölvupósts: %{link}'
unsubscribe: Taka úr áskrift
view: 'Skoða:'
view_profile: Skoða notandasnið
@@ -1659,9 +1658,6 @@ is:
title: Auðkenningarferill
mail_subscriptions:
unsubscribe:
- action: Já, hætta í áskrift
- complete: Hætta í áskrift
- confirmation_html: Ertu viss um að þú viljir hætta áskrift sendinga á %{type} fyrir Mastodon á %{domain} til póstfangsins þíns %{email}? Þú getur alltaf aftur gerst áskrifandi í stillingunum fyrir tilkynningar í tölvupósti.
emails:
notification_emails:
favourite: tilkynningum í tölvupósti um eftirlæti
@@ -1669,9 +1665,6 @@ is:
follow_request: tilkynningum í tölvupósti um beiðnir um að fylgjast með
mention: tilkynningum í tölvupósti um tilvísanir
reblog: tilkynningum í tölvupósti um endurbirtingar
- resubscribe_html: Ef þú hættir áskrift fyrir mistök, geturðu alltaf aftur gerst áskrifandi í stillingunum fyrir tilkynningar í tölvupósti.
- success_html: Þú munt ekki lengur fá sendingar með %{type} fyrir Mastodon á %{domain} á póstfangið þitt %{email}.
- title: Taka úr áskrift
media_attachments:
validations:
images_and_video: Ekki er hægt að hengja myndskeið við færslu sem þegar inniheldur myndir
diff --git a/config/locales/it.yml b/config/locales/it.yml
index e01bed8b97..ed80d9b377 100644
--- a/config/locales/it.yml
+++ b/config/locales/it.yml
@@ -1231,7 +1231,6 @@ it:
application_mailer:
notification_preferences: Modifica le preferenze e-mail
salutation: "%{name},"
- settings: 'Modifica le preferenze e-mail: %{link}'
unsubscribe: Disiscriviti
view: 'Guarda:'
view_profile: Mostra profilo
@@ -1655,9 +1654,6 @@ it:
title: Cronologia delle autenticazioni
mail_subscriptions:
unsubscribe:
- action: Sì, annulla l'iscrizione
- complete: Iscrizione annullata
- confirmation_html: Si è sicuri di voler annullare l'iscrizione per non ricevere %{type} per Mastodon su %{domain} sulla tua e-mail %{email}? Puoi sempre reiscriverti dalle tue impostazioni di notifica e-mail.
emails:
notification_emails:
favourite: e-mail di notifica preferite
@@ -1665,9 +1661,6 @@ it:
follow_request: segui le e-mail di richiesta
mention: menziona le e-mail di notifica
reblog: e-mail di notifica per le condivisioni
- resubscribe_html: Se hai annullato l'iscrizione per errore, puoi reiscriverti tramite le impostazioni di notifica e-mail.
- success_html: Non riceverai più %{type} per Mastodon su %{domain} al tuo indirizzo e-mail %{email}.
- title: Disiscriviti
media_attachments:
validations:
images_and_video: Impossibile allegare video a un post che contiene già immagini
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index b1e2fdbef7..df8967eebe 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -1169,7 +1169,6 @@ ja:
application_mailer:
notification_preferences: メール設定の変更
salutation: "%{name}さん"
- settings: 'メール設定の変更: %{link}'
unsubscribe: 購読解除
view: 'リンク:'
view_profile: プロフィールを表示
@@ -1560,9 +1559,6 @@ ja:
title: 認証履歴
mail_subscriptions:
unsubscribe:
- action: 購読を解除する
- complete: 購読を解除しました
- confirmation_html: Mastodon (%{domain}) による %{email} 宛の「%{type}」の配信を停止します。再度必要になった場合はメール通知の設定からいつでも再開できます。
emails:
notification_emails:
favourite: お気に入りの通知メール
@@ -1570,9 +1566,6 @@ ja:
follow_request: フォローリクエストの通知メール
mention: 返信の通知メール
reblog: ブーストの通知メール
- resubscribe_html: 誤って解除した場合はメール通知の設定から再購読できます。
- success_html: Mastodon (%{domain}) から %{email} への「%{type}」の配信が停止されました。
- title: 購読の解除
media_attachments:
validations:
images_and_video: 既に画像が追加されているため、動画を追加することはできません
diff --git a/config/locales/kab.yml b/config/locales/kab.yml
index 35bffc2810..93dc72865c 100644
--- a/config/locales/kab.yml
+++ b/config/locales/kab.yml
@@ -567,7 +567,6 @@ kab:
application_mailer:
notification_preferences: Snifel imenyafen n imayl
salutation: "%{name},"
- settings: 'Snifel imenyafen n imayl: %{link}'
view: 'Ẓaṛ:'
view_profile: Ssken-d amaɣnu
view_status: Ssken-d tasuffiɣt
diff --git a/config/locales/ko.yml b/config/locales/ko.yml
index a5e90f9894..ae7d13ff0f 100644
--- a/config/locales/ko.yml
+++ b/config/locales/ko.yml
@@ -1194,7 +1194,6 @@ ko:
application_mailer:
notification_preferences: 이메일 설정 변경
salutation: "%{name} 님,"
- settings: '이메일 설정 변경: %{link}'
unsubscribe: 구독 해제
view: '보기:'
view_profile: 프로필 보기
@@ -1596,9 +1595,6 @@ ko:
title: 인증 이력
mail_subscriptions:
unsubscribe:
- action: 네, 구독 취소합니다
- complete: 구독 취소됨
- confirmation_html: 정말로 %{domain}에서 %{email}로 보내는 마스토돈의 %{type}에 대한 구독을 취소하시겠습니까? 언제든지 이메일 알림 설정에서 다시 구독할 수 있습니다.
emails:
notification_emails:
favourite: 좋아요 알림 이메일
@@ -1606,9 +1602,6 @@ ko:
follow_request: 팔로우 요청 이메일
mention: 멘션 알림 이메일
reblog: 부스트 알림 이메일
- resubscribe_html: 만약 실수로 구독 취소를 했다면 이메일 알림 설정에서 다시 구독할 수 있습니다.
- success_html: 이제 더이상 %{domain}의 마스토돈에서 %{email}로 %{type} 알림을 보내지 않습니다.
- title: 구독 취소
media_attachments:
validations:
images_and_video: 이미 사진이 첨부된 게시물엔 동영상을 첨부할 수 없습니다.
diff --git a/config/locales/lad.yml b/config/locales/lad.yml
index aeffb477be..78eadbb953 100644
--- a/config/locales/lad.yml
+++ b/config/locales/lad.yml
@@ -1135,7 +1135,6 @@ lad:
application_mailer:
notification_preferences: Troka preferensyas de posta
salutation: "%{name},"
- settings: 'Troka preferensyas de posta: %{link}'
unsubscribe: Dezabona
view: 'Mira:'
view_profile: Ve profil
@@ -1505,9 +1504,6 @@ lad:
title: Estoria de autentifikasyon
mail_subscriptions:
unsubscribe:
- action: Si, dezabona
- complete: Dezabonado
- confirmation_html: Estas siguro de ke ya no keres risivir %{type} de Mastodon en %{domain} a tu posta elektronika %{email}? Syempre podras reabonarte dizde las opsyones de avizos por posta..
emails:
notification_emails:
favourite: avizos de favoritos por posta
@@ -1515,9 +1511,6 @@ lad:
follow_request: avizos de solisitasyones de segimyento por posta
mention: avizos de enmentaduras por posta
reblog: avizos de repartajasyones por posta
- resubscribe_html: Si tyenes deabonado por yerro, puedes reabonar en tus opsyones de avizos por posta elektronika.
- success_html: Ya no risiviras %{type} de Mastodon en %{domain} a tu posta en %{email}.
- title: Dezabona
media_attachments:
validations:
images_and_video: No se puede adjuntar un video a un estado ke ya kontenga imajes
diff --git a/config/locales/lt.yml b/config/locales/lt.yml
index b807451ece..8ce2304a40 100644
--- a/config/locales/lt.yml
+++ b/config/locales/lt.yml
@@ -1078,7 +1078,6 @@ lt:
emails:
notification_emails:
reblog: dalintis pranešimų el. pašto laiškais
- success_html: Daugiau negausi %{type} „Mastodon“ domene %{domain} į savo el. paštą %{email}.
media_attachments:
validations:
images_and_video: Negalima pridėti video prie statuso, kuris jau turi nuotrauką
diff --git a/config/locales/lv.yml b/config/locales/lv.yml
index 1a31034a59..fb96e9400a 100644
--- a/config/locales/lv.yml
+++ b/config/locales/lv.yml
@@ -1174,7 +1174,6 @@ lv:
application_mailer:
notification_preferences: Mainīt e-pasta uztādījumus
salutation: "%{name},"
- settings: 'Mainīt e-pasta uztādījumus: %{link}'
unsubscribe: Atcelt abonēšanu
view: 'Skatīt:'
view_profile: Skatīt profilu
@@ -1598,9 +1597,6 @@ lv:
title: Autentifikācijas vēsture
mail_subscriptions:
unsubscribe:
- action: Jā, atcelt abonēšanu
- complete: Anulēts
- confirmation_html: Vai tiešām atteikties no %{type} saņemšanas savā e-pasta adresē %{email} par %{domain} esošo Mastodon? Vienmēr var abonēt no jauna savos e-pasta paziņojumu iestatījumos.
emails:
notification_emails:
favourite: izlases paziņojumu e-pasta ziņojumi
@@ -1608,9 +1604,6 @@ lv:
follow_request: sekošanas pieprasījumu e-pasta ziņojumi
mention: pieminēšanas paziņojumu e-pasta ziņojumi
reblog: pastiprinājumu paziņojumu e-pasta ziņojumi
- resubscribe_html: Ja abonements tika atcelts kļūdas dēļ, abonēt no jauna var savos e-pasta paziņojumu iestatījumos.
- success_html: Tu vairs savā e-pasta adresē %{email} nesaņemsi %{type} par %{domain} esošo Mastodon.
- title: Atcelt abonēšanu
media_attachments:
validations:
images_and_video: Nevar pievienot videoklipu tādai ziņai, kura jau satur attēlus
diff --git a/config/locales/ms.yml b/config/locales/ms.yml
index 6edddd4323..21470409e2 100644
--- a/config/locales/ms.yml
+++ b/config/locales/ms.yml
@@ -1280,12 +1280,9 @@ ms:
title: Sejarah pengesahan
mail_subscriptions:
unsubscribe:
- action: Ya, nyahlanggan
- complete: Menyahlanggan
emails:
notification_emails:
favourite: emel pemberitahuan sukaan
- title: Hentikan langganan
media_attachments:
validations:
images_and_video: Tidak boleh melampirkan video pada pos yang sudah mengandungi imej
diff --git a/config/locales/my.yml b/config/locales/my.yml
index f8f69586a9..fd0bbcb005 100644
--- a/config/locales/my.yml
+++ b/config/locales/my.yml
@@ -1275,11 +1275,6 @@ my:
failed_sign_in_html: "%{ip} (%{browser}) မှ %{method} ဖြင့် အကောင့်ဝင်ရောက်ခြင်း မအောင်မြင်ပါ"
successful_sign_in_html: "%{ip} (%{browser}) မှ %{method} ဖြင့် အကောင့်ဝင်၍ရပါပြီ"
title: အထောက်အထားမှတ်တမ်း
- mail_subscriptions:
- unsubscribe:
- action: ဟုတ်ကဲ့၊ စာရင်းမှ ဖြုတ်လိုက်ပါပြီ
- complete: စာရင်းမှထွက်ရန်
- title: စာရင်းမှထွက်ရန်
media_attachments:
validations:
images_and_video: ရုပ်ပုံပါရှိပြီးသားပို့စ်တွင် ဗီဒီယို ပူးတွဲ၍မရပါ
diff --git a/config/locales/nan-TW.yml b/config/locales/nan-TW.yml
index dc471a9c2c..deba967257 100644
--- a/config/locales/nan-TW.yml
+++ b/config/locales/nan-TW.yml
@@ -1210,7 +1210,6 @@ nan-TW:
application_mailer:
notification_preferences: 改電子phue ê偏好
salutation: "%{name}、"
- settings: 改電子phue ê偏好:%{link}
unsubscribe: 取消訂
view: 檢視:
view_profile: 看個人資料
@@ -1614,9 +1613,6 @@ nan-TW:
title: 認證歷史
mail_subscriptions:
unsubscribe:
- action: Hennh,mài訂
- complete: 無訂ah
- confirmation_html: Lí kám確定beh取消訂 %{domain} ê Mastodon 內底 ê %{type} kàu lí ê電子批 %{email}?Lí ē當隨時對lí ê電子批通知設定重訂。
emails:
notification_emails:
favourite: 收藏通知電子批
@@ -1624,9 +1620,6 @@ nan-TW:
follow_request: 跟tuè請求電子批
mention: 提起通知電子批
reblog: 轉送通知電子批
- resubscribe_html: Nā出tshê取消訂,lí通重訂tuì lí ê電子批通知設定。
- success_html: Lí bē koh收著佇 %{domain} ê Mastodon內底ê %{type} kàu lí ê電子批 %{email}。
- title: 取消訂
media_attachments:
validations:
images_and_video: Bē當佇有影像ê PO文內底加影片
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 69ff56febd..8549e7e17c 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -1231,7 +1231,6 @@ nl:
application_mailer:
notification_preferences: E-mailvoorkeuren wijzigen
salutation: "%{name},"
- settings: 'E-mailvoorkeuren wijzigen: %{link}'
unsubscribe: Afmelden
view: 'Bekijk:'
view_profile: Profiel bekijken
@@ -1655,9 +1654,6 @@ nl:
title: Inloggeschiedenis
mail_subscriptions:
unsubscribe:
- action: Ja, afmelden
- complete: Afgemeld
- confirmation_html: Weet je zeker dat je je wilt afmelden voor het ontvangen van %{type} van Mastodon op %{domain} op je e-mailadres %{email}? Je kunt je altijd opnieuw abonneren in jouw instellingen voor e-mailmeldingen.
emails:
notification_emails:
favourite: e-mailmeldingen voor favorieten
@@ -1665,9 +1661,6 @@ nl:
follow_request: e-mailmeldingen voor volgverzoeken
mention: e-mailmeldingen voor vermeldingen
reblog: e-mailmeldingen voor boosts
- resubscribe_html: Als je je per ongeluk hebt afgemeld, kun je je opnieuw abonneren in jouw instellingen voor e-mailmeldingen.
- success_html: Je ontvangt niet langer %{type} van Mastodon op %{domain} op je e-mailadres %{email}.
- title: Afmelden
media_attachments:
validations:
images_and_video: Een video kan niet aan een bericht met afbeeldingen worden gekoppeld
diff --git a/config/locales/nn.yml b/config/locales/nn.yml
index f59ba33334..04c021d5cc 100644
--- a/config/locales/nn.yml
+++ b/config/locales/nn.yml
@@ -1229,7 +1229,6 @@ nn:
application_mailer:
notification_preferences: Endre e-post-innstillingane
salutation: Hei %{name},
- settings: 'Endre e-post-innstillingar: %{link}'
unsubscribe: Meld av
view: 'Sjå:'
view_profile: Sjå profil
@@ -1653,9 +1652,6 @@ nn:
title: Autentiseringshistorikk
mail_subscriptions:
unsubscribe:
- action: Ja, meld av
- complete: Meldt av
- confirmation_html: Er du sikker på at du ikkje lenger ynskjer å motta %{type} frå Mastodon på %{domain} til e-posten din %{email}? Du kan alltids gjera om på dette i innstillingar for e-postvarsling.
emails:
notification_emails:
favourite: e-postar om favorittmarkeringar
@@ -1663,9 +1659,6 @@ nn:
follow_request: e-postar om fylgjeførespurnadar
mention: e-postar om omtaler
reblog: e-postar om framhevingar
- resubscribe_html: Om du har avslutta abonnementet ved ein feil, kan du abonnera på nytt i innstillingar for e-postvarsling.
- success_html: Du vil ikkje lenger få %{type} frå Mastodon på %{domain} til e-posten på %{email}.
- title: Meld av
media_attachments:
validations:
images_and_video: Kan ikkje leggja ved video til status som allereie inneheld bilete
diff --git a/config/locales/no.yml b/config/locales/no.yml
index f6dd1e9c8d..e2bf55a229 100644
--- a/config/locales/no.yml
+++ b/config/locales/no.yml
@@ -1352,11 +1352,6 @@
failed_sign_in_html: Mislykket innloggingsforsøk med %{method} fra %{ip} (%{browser})
successful_sign_in_html: Vellykket innlogging med %{method} fra %{ip} (%{browser})
title: Autentiseringshistorikk
- mail_subscriptions:
- unsubscribe:
- action: Ja, avslutt abonnement
- complete: Abonnement avsluttet
- title: Avslutt abonnement
media_attachments:
validations:
images_and_video: Kan ikke legge ved video på en status som allerede inneholder bilder
diff --git a/config/locales/pl.yml b/config/locales/pl.yml
index e0ae1f7106..af03c4f7cf 100644
--- a/config/locales/pl.yml
+++ b/config/locales/pl.yml
@@ -1230,7 +1230,6 @@ pl:
application_mailer:
notification_preferences: Zmień ustawienia e-maili
salutation: "%{name},"
- settings: 'Zmień ustawienia e-maili: %{link}'
unsubscribe: Anuluj subskrypcję
view: 'Zobacz:'
view_profile: Wyświetl profil
@@ -1689,9 +1688,6 @@ pl:
title: Historia uwierzytelniania
mail_subscriptions:
unsubscribe:
- action: Tak, wypisuję się
- complete: Anulowano subskrypcję
- confirmation_html: Czy na pewno chcesz wypisać się z otrzymywania %{type} z Mastodona na %{domain} na adres %{email}? Zawsze możesz zapisać się ponownie ze strony ustawień powiadomień mejlowych.
emails:
notification_emails:
favourite: powiadomień mejlowych o polubieniach
@@ -1699,9 +1695,6 @@ pl:
follow_request: mejli o prośbach o możliwość obserwowania
mention: powiadomień mejlowych o wspomnieniach
reblog: powiadomień mejlowych o podbiciach
- resubscribe_html: W przypadku przypadkowego wypisania możesz zapisać się ponownie z ustawień powiadomień mejlowych.
- success_html: Już nie będziesz otrzymywać %{type} z Mastodona na %{domain} na adres %{email}.
- title: Anuluj subskrypcję
media_attachments:
validations:
images_and_video: Nie możesz załączyć pliku wideo do wpisu, który zawiera już zdjęcia
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index e8789d4236..2b4a820851 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -1229,7 +1229,6 @@ pt-BR:
application_mailer:
notification_preferences: Alterar preferências de e-mail
salutation: "%{name},"
- settings: 'Alterar preferências de e-mail: %{link}'
unsubscribe: Desinscrever
view: 'Ver:'
view_profile: Ver perfil
@@ -1651,9 +1650,6 @@ pt-BR:
title: Histórico de autenticação
mail_subscriptions:
unsubscribe:
- action: Sim, cancelar subscrição
- complete: Desinscrito
- confirmation_html: Tem certeza que deseja cancelar a assinatura de %{type} para Mastodon no %{domain} para o seu endereço de e-mail %{email}? Você sempre pode se inscrever novamente nas configurações de notificação de email.
emails:
notification_emails:
favourite: emails de notificação favoritos
@@ -1661,9 +1657,6 @@ pt-BR:
follow_request: emails de seguidores pendentes
mention: emails de notificação de menções
reblog: emails de notificação de impulsos
- resubscribe_html: Se você cancelou sua inscrição por engano, você pode se inscrever novamente em suas configurações de notificações por e-mail.
- success_html: Você não mais receberá %{type} no Mastodon em %{domain} ao seu endereço de e-mail %{email}.
- title: Cancelar inscrição
media_attachments:
validations:
images_and_video: Não foi possível anexar um vídeo a uma publicação que já contém imagens
diff --git a/config/locales/pt-PT.yml b/config/locales/pt-PT.yml
index c388a0a48e..21550b348d 100644
--- a/config/locales/pt-PT.yml
+++ b/config/locales/pt-PT.yml
@@ -1229,7 +1229,6 @@ pt-PT:
application_mailer:
notification_preferences: Alterar preferências de e-mail
salutation: "%{name},"
- settings: 'Alterar preferências de e-mail: %{link}'
unsubscribe: Cancelar subscrição
view: 'Ver:'
view_profile: Ver perfil
@@ -1651,9 +1650,6 @@ pt-PT:
title: Histórico de autenticação
mail_subscriptions:
unsubscribe:
- action: Sim, cancelar subscrição
- complete: Subscrição cancelada
- confirmation_html: Tens a certeza que desejas cancelar a subscrição para receber %{type} pelo Mastodon em %{domain} no teu e-mail em %{email}? Podes sempre subscrever novamente nas tuas definições de notificação por e-mail.
emails:
notification_emails:
favourite: e-mails de notificação de favoritos
@@ -1661,9 +1657,6 @@ pt-PT:
follow_request: e-mails de pedido de seguidor
mention: e-mails de notificação de menção
reblog: e-mails de notificação de partilhas
- resubscribe_html: Se tiveres anulado a subscrição por engano, podes voltar a subscrevê-la nas definições de notificação por e-mail.
- success_html: Não receberás novamente %{type} do Mastodon em %{domain} para o teu e-mail em %{email}.
- title: Cancelar subscrição
media_attachments:
validations:
images_and_video: Não é possível anexar um vídeo a uma publicação que já contém imagens
diff --git a/config/locales/ru.yml b/config/locales/ru.yml
index 626870709d..c56574643b 100644
--- a/config/locales/ru.yml
+++ b/config/locales/ru.yml
@@ -1227,7 +1227,6 @@ ru:
application_mailer:
notification_preferences: Настроить оповещения по электронной почте
salutation: Привет, %{name}!
- settings: 'Настроить оповещения по электронной почте можно здесь: %{link}'
unsubscribe: Отписаться
view: 'Открыть в браузере:'
view_profile: Перейти к профилю
@@ -1675,9 +1674,6 @@ ru:
title: История входов
mail_subscriptions:
unsubscribe:
- action: Да, я хочу отписаться
- complete: Подписка отменена
- confirmation_html: Вы уверены в том, что хотите отписаться от всех %{type}, которые вы получаете на адрес %{email} для учётной записи на сервере Mastodon %{domain}? Вы всегда сможете подписаться снова в настройках уведомлений по электронной почте.
emails:
notification_emails:
favourite: уведомлений о добавлении ваших постов в избранное
@@ -1685,9 +1681,6 @@ ru:
follow_request: уведомлений о новых запросах на подписку
mention: уведомлений о новых упоминаниях
reblog: уведомлений о продвижении ваших постов
- resubscribe_html: Если вы отписались по ошибке и хотите подписаться снова, перейдите на страницу настройки уведомлений по электронной почте.
- success_html: Вы отказались от %{type}, которые вы получали на адрес %{email} для вашей учётной записи на сервере Mastodon %{domain}.
- title: Отписаться
media_attachments:
validations:
images_and_video: Нельзя добавить видео к посту с изображениями
diff --git a/config/locales/sc.yml b/config/locales/sc.yml
index 6924ba67c4..2c94bc3a10 100644
--- a/config/locales/sc.yml
+++ b/config/locales/sc.yml
@@ -913,9 +913,6 @@ sc:
authentication_methods:
password: crae
webauthn: craes de seguresa
- mail_subscriptions:
- unsubscribe:
- title: Annulla sa sutiscritzione
media_attachments:
validations:
images_and_video: Non si podet allegare unu vìdeu in una publicatzione chi cuntenet giai immàgines
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index 87334b14e7..be92d56a8a 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -134,6 +134,7 @@ en:
otp: 'Enter the two-factor code generated by your phone app or use one of your recovery codes:'
webauthn: If it's an USB key be sure to insert it and, if necessary, tap it.
settings:
+ email_subscriptions: Disabling retains existing subscribers but stops sending emails.
indexable: Your profile page may appear in search results on Google, Bing, and others.
show_application: You will always be able to see which app published your post regardless.
tag:
@@ -356,6 +357,7 @@ en:
hint: Additional information
text: Rule
settings:
+ email_subscriptions: Enable email sign-ups
indexable: Include profile page in search engines
show_application: Display from which app you sent a post
tag:
diff --git a/config/locales/sk.yml b/config/locales/sk.yml
index 0a684eeb4c..25bc48a198 100644
--- a/config/locales/sk.yml
+++ b/config/locales/sk.yml
@@ -1085,7 +1085,6 @@ sk:
emails:
notification_emails:
reblog: e-mailové upozornenia na zdieľania
- title: Ukonči odber
media_attachments:
validations:
images_and_video: K príspevku ktorý už obsahuje obrázky nemôžeš priložiť video
diff --git a/config/locales/sl.yml b/config/locales/sl.yml
index 6061b6fc8e..8e2372a4cc 100644
--- a/config/locales/sl.yml
+++ b/config/locales/sl.yml
@@ -1227,7 +1227,6 @@ sl:
application_mailer:
notification_preferences: Spremenite e-poštne nastavitve
salutation: "%{name},"
- settings: 'Spremenite e-poštne nastavitve: %{link}'
unsubscribe: Odjavi od naročnine
view: 'Pogled:'
view_profile: Ogled profila
@@ -1687,9 +1686,6 @@ sl:
title: Zgodovina overjanja
mail_subscriptions:
unsubscribe:
- action: Da, odjavi me
- complete: Odjavljeni
- confirmation_html: Ali se res želite odjaviti od prejemanja %{type} za Mastodon na %{domain} na svojo e-pošto %{email}? Kadarkoli se lahko znova prijavite iz svojih nastavitev e-poštnih obvestil.
emails:
notification_emails:
favourite: e-sporočil z obvestili o priljubljenosti
@@ -1697,9 +1693,6 @@ sl:
follow_request: e-sporočil o zahtevah za sledenje
mention: e-sporočil z obvestili o omembah
reblog: e-sporočil z obvestili o izpostavljanju
- resubscribe_html: Če ste se odjavili po pomoti, se lahko znova prijavite iz svojih nastavitev e-poštnih obvestil.
- success_html: Nič več ne boste prejemali %{type} za Mastodon na %{domain} na svoj e-naslov %{email}.
- title: Odjavi od naročnine
media_attachments:
validations:
images_and_video: Videoposnetka ni mogoče priložiti objavi, ki že vsebuje slike
diff --git a/config/locales/sq.yml b/config/locales/sq.yml
index caf915df78..dc52f54b24 100644
--- a/config/locales/sq.yml
+++ b/config/locales/sq.yml
@@ -1220,7 +1220,6 @@ sq:
application_mailer:
notification_preferences: Ndryshoni parapëlqime rreth email-esh
salutation: "%{name},"
- settings: 'Ndryshoni parapëlqime rreth email-esh: %{link}'
unsubscribe: Shpajtohuni
view: 'Parje:'
view_profile: Shihni profilin
@@ -1640,9 +1639,6 @@ sq:
title: Historik mirëfilltësimesh
mail_subscriptions:
unsubscribe:
- action: Po, shpajtomëni
- complete: U shpajtuat
- confirmation_html: Jeni i sigurt se doni të shpajtoheni nga marrje %{type} për Mastodon te %{domain} në email-in tuaj %{email}? Mundeni përherë të ripajtoheni që nga rregullimet tuaja për njoftime me email.
emails:
notification_emails:
favourite: email-e njoftimesh parapëlqimesh
@@ -1650,9 +1646,6 @@ sq:
follow_request: email-e kërkesash ndjekjeje
mention: email-e njoftimesh përmendjesh
reblog: email-e njoftimesh përforcimesh
- resubscribe_html: Nëse u shpajtuat gabimisht, mund të ripajtoheni që nga rregullimet tuaja për njoftime me email.
- success_html: S’do të merrni më %{type} për Mastodon te %{domain} në email-in tuaj te %{email}.
- title: Shpajtohuni
media_attachments:
validations:
images_and_video: S’mund të bashkëngjitet video te një gjendje që përmban figura tashmë
diff --git a/config/locales/sr-Latn.yml b/config/locales/sr-Latn.yml
index 3f9eee3cae..d75f5f76d3 100644
--- a/config/locales/sr-Latn.yml
+++ b/config/locales/sr-Latn.yml
@@ -1357,11 +1357,6 @@ sr-Latn:
failed_sign_in_html: Neuspešan pokušaj prijavljivanja putem %{method} sa %{ip} (%{browser})
successful_sign_in_html: Uspešan pokušaj prijavljivanja putem %{method} sa %{ip} (%{browser})
title: Istorija autentifikacije
- mail_subscriptions:
- unsubscribe:
- action: Da, odjavi me
- complete: Odjavljen
- title: Odjavi se
media_attachments:
validations:
images_and_video: Ne može da se prikači video na status koji već ima slike
diff --git a/config/locales/sr.yml b/config/locales/sr.yml
index 35d845bb1e..8bc89180d4 100644
--- a/config/locales/sr.yml
+++ b/config/locales/sr.yml
@@ -1387,11 +1387,6 @@ sr:
failed_sign_in_html: Неуспешан покушај пријављивања путем %{method} са %{ip} (%{browser})
successful_sign_in_html: Успешан покушај пријављивања путем %{method} са %{ip} (%{browser})
title: Историја аутентификације
- mail_subscriptions:
- unsubscribe:
- action: Да, одјави ме
- complete: Одјављен
- title: Одјави се
media_attachments:
validations:
images_and_video: Не може да се прикачи видео на статус који већ има слике
diff --git a/config/locales/sv.yml b/config/locales/sv.yml
index a514556ba9..3180a0ba98 100644
--- a/config/locales/sv.yml
+++ b/config/locales/sv.yml
@@ -1228,7 +1228,6 @@ sv:
application_mailer:
notification_preferences: Ändra e-postpreferenser
salutation: "%{name},"
- settings: 'Ändra e-postinställningar: %{link}'
unsubscribe: Avprenumerera
view: 'Granska:'
view_profile: Visa profil
@@ -1652,9 +1651,6 @@ sv:
title: Autentiseringshistorik
mail_subscriptions:
unsubscribe:
- action: Ja, avsluta prenumerationen
- complete: Prenumeration avslutad
- confirmation_html: Är du säker på att du vill avregistrera dig från att ta emot %{type} för Mastodon på %{domain} med din e-post på %{email}? Du kan alltid återprenumerera bland dina e-postmeddelandeinställningar.
emails:
notification_emails:
favourite: aviseringsmejl för favoriserade inlägg
@@ -1662,9 +1658,6 @@ sv:
follow_request: aviseringsmejl för följdförfrågningar
mention: aviseringsmejl för inlägg där du nämns
reblog: aviseringsmejl för förhöjda inlägg
- resubscribe_html: Om du slutat prenumerera av misstag kan du återprenumerera i dina e-postaviseringsinställningar.
- success_html: Du får inte längre %{type} för Mastodon på %{domain} till din e-post på %{email}.
- title: Avsluta prenumeration
media_attachments:
validations:
images_and_video: Det går inte att bifoga en video till ett inlägg som redan innehåller bilder
diff --git a/config/locales/th.yml b/config/locales/th.yml
index b3e2413235..a90f1a2555 100644
--- a/config/locales/th.yml
+++ b/config/locales/th.yml
@@ -1124,7 +1124,6 @@ th:
application_mailer:
notification_preferences: เปลี่ยนการกำหนดลักษณะอีเมล
salutation: "%{name},"
- settings: 'เปลี่ยนการกำหนดลักษณะอีเมล: %{link}'
unsubscribe: เลิกบอกรับ
view: 'ดู:'
view_profile: ดูโปรไฟล์
@@ -1510,9 +1509,6 @@ th:
title: ประวัติการรับรองความถูกต้อง
mail_subscriptions:
unsubscribe:
- action: ใช่ เลิกบอกรับ
- complete: เลิกบอกรับแล้ว
- confirmation_html: คุณแน่ใจหรือไม่ว่าต้องการเลิกบอกรับจากการรับ %{type} สำหรับ Mastodon ใน %{domain} ไปยังอีเมลของคุณที่ %{email}? คุณสามารถบอกรับใหม่ได้เสมอจาก การตั้งค่าการแจ้งเตือนอีเมล ของคุณ
emails:
notification_emails:
favourite: อีเมลการแจ้งเตือนการชื่นชอบ
@@ -1520,9 +1516,6 @@ th:
follow_request: อีเมลคำขอติดตาม
mention: อีเมลการแจ้งเตือนการกล่าวถึง
reblog: อีเมลการแจ้งเตือนการดัน
- resubscribe_html: หากคุณได้เลิกบอกรับโดยไม่ได้ตั้งใจ คุณสามารถบอกรับใหม่ได้จาก การตั้งค่าการแจ้งเตือนอีเมล ของคุณ
- success_html: คุณจะไม่ได้รับ %{type} สำหรับ Mastodon ใน %{domain} ไปยังอีเมลของคุณที่ %{email} อีกต่อไป
- title: เลิกบอกรับ
media_attachments:
validations:
images_and_video: ไม่สามารถแนบวิดีโอกับโพสต์ที่มีภาพอยู่แล้ว
diff --git a/config/locales/tr.yml b/config/locales/tr.yml
index d58aab2664..1ad87c39d3 100644
--- a/config/locales/tr.yml
+++ b/config/locales/tr.yml
@@ -1231,7 +1231,6 @@ tr:
application_mailer:
notification_preferences: E-posta tercihlerini değiştir
salutation: "%{name},"
- settings: 'E-posta tercihlerini değiştir: %{link}'
unsubscribe: Abonelikten çık
view: 'Görüntüle:'
view_profile: Profili görüntüle
@@ -1655,9 +1654,6 @@ tr:
title: Kimlik doğrulama geçmişi
mail_subscriptions:
unsubscribe:
- action: Evet, abonelikten çık
- complete: Abonelikten çık
- confirmation_html: '%{domain} üzerindeki Mastodon için %{type} almayı durdurarak %{email} adresinize aboneliğinizi iptal etmek istediğinizden emin misiniz? e-posta bildirim ayarlarınızdan her zaman yeniden abone olabilirsiniz.'
emails:
notification_emails:
favourite: favori bildirim e-postaları
@@ -1665,9 +1661,6 @@ tr:
follow_request: takip isteği bildirim e-postaları
mention: bahsetme bildirim e-postaları
reblog: öne çıkanlar bildirim e-postaları
- resubscribe_html: Abonelikten yanlışlıkla çıktıysanız, e-posta bildirim ayarlarınızdan yeniden abone olabilirsiniz.
- success_html: Artık %{email} adresindeki e-postanıza %{domain} üzerindeki Mastodon için %{type} almayacaksınız.
- title: Abonelikten çık
media_attachments:
validations:
images_and_video: Zaten resim içeren bir duruma video eklenemez
diff --git a/config/locales/uk.yml b/config/locales/uk.yml
index 11dcf51c6e..e5ddc13b1f 100644
--- a/config/locales/uk.yml
+++ b/config/locales/uk.yml
@@ -1180,7 +1180,6 @@ uk:
application_mailer:
notification_preferences: Змінити налаштування електронної пошти
salutation: "%{name},"
- settings: 'Змінити налаштування електронної пошти: %{link}'
unsubscribe: Відписатися
view: 'Перегляд:'
view_profile: Показати профіль
@@ -1572,9 +1571,6 @@ uk:
title: Історія входів
mail_subscriptions:
unsubscribe:
- action: Так, відписатися
- complete: Відписалися
- confirmation_html: Ви впевнені, що хочете відписатися від отримання %{type} для Mastodon на %{domain} до своєї скриньки %{email}? Ви можете повторно підписатися у налаштуваннях сповіщень електронною поштою.
emails:
notification_emails:
favourite: отримувати сповіщення про вподобання електронною поштою
@@ -1582,9 +1578,6 @@ uk:
follow_request: отримувати сповіщення про запити на стеження електронною поштою
mention: отримувати сповіщення про згадки електронною поштою
reblog: отримувати сповіщення про поширення електронною поштою
- resubscribe_html: Якщо ви відписалися помилково, ви можете повторно підписатися в налаштуваннях сповіщень електронною поштою.
- success_html: Ви більше не отримуватимете %{type} для Mastodon %{domain} на адресу %{email}.
- title: Відписатися
media_attachments:
validations:
images_and_video: Не можна додати відео до допису з зображеннями
diff --git a/config/locales/vi.yml b/config/locales/vi.yml
index f773dda729..02862dcd73 100644
--- a/config/locales/vi.yml
+++ b/config/locales/vi.yml
@@ -1210,7 +1210,6 @@ vi:
application_mailer:
notification_preferences: Thay đổi thiết lập email
salutation: "%{name},"
- settings: 'Thay đổi thiết lập email: %{link}'
unsubscribe: Hủy đăng ký
view: 'Chi tiết:'
view_profile: Xem trang hồ sơ
@@ -1614,9 +1613,6 @@ vi:
title: Lịch sử đăng nhập
mail_subscriptions:
unsubscribe:
- action: Đúng, hủy đăng ký
- complete: Đã hủy đăng ký
- confirmation_html: Bạn có chắc muốn hủy đăng ký %{type} Mastodon trên %{domain} tới %{email}? Bạn có thể đăng ký lại từ cài đặt thông báo email.
emails:
notification_emails:
favourite: email thông báo lượt thích
@@ -1624,9 +1620,6 @@ vi:
follow_request: email thông báo yêu cầu theo dõi
mention: email thông báo lượt nhắc đến
reblog: email thông báo lượt đăng lại
- resubscribe_html: Nếu đổi ý, bạn có thể đăng ký lại từ cài đặt thông báo email.
- success_html: Bạn sẽ không còn nhận %{type} Mastodon trên %{domain} tới %{email}.
- title: Hủy đăng ký
media_attachments:
validations:
images_and_video: Không thể đính kèm video vào tút đã chứa hình ảnh
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index c161b99681..80ead9ee79 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -1210,7 +1210,6 @@ zh-CN:
application_mailer:
notification_preferences: 更改邮件偏好
salutation: "%{name}:"
- settings: 更改邮件偏好: %{link}
unsubscribe: 取消订阅
view: 点此链接查看详情:
view_profile: 查看个人资料
@@ -1614,9 +1613,6 @@ zh-CN:
title: 认证历史
mail_subscriptions:
unsubscribe:
- action: 是,取消订阅
- complete: 已取消订阅
- confirmation_html: 你确定要退订来自 %{domain} 上的 Mastodon 的 %{type} 到你的邮箱 %{email} 吗?你可以随时在邮件通知设置中重新订阅。
emails:
notification_emails:
favourite: 嘟文被喜欢邮件通知
@@ -1624,9 +1620,6 @@ zh-CN:
follow_request: 关注请求邮件通知
mention: 账号被提及邮件通知
reblog: 嘟文被转嘟邮件通知
- resubscribe_html: 如果你不小心取消了订阅,可以在你的邮件通知设置中重新订阅。
- success_html: 你将不会在你的邮箱 %{email} 中收到 %{domain} 上的 Mastodon的 %{type}
- title: 取消订阅
media_attachments:
validations:
images_and_video: 无法在嘟文中同时插入视频和图片
diff --git a/config/locales/zh-HK.yml b/config/locales/zh-HK.yml
index ac26ce9af4..6caf362fa7 100644
--- a/config/locales/zh-HK.yml
+++ b/config/locales/zh-HK.yml
@@ -1341,11 +1341,6 @@ zh-HK:
failed_sign_in_html: 以 %{method} 從 %{ip} (%{browser}) 登入失敗
successful_sign_in_html: 以 %{method} 從 %{ip} (%{browser}) 成功登入
title: 驗證操作歷史
- mail_subscriptions:
- unsubscribe:
- action: 沒錯,取消訂閱
- complete: 已取消訂閱
- title: 取消訂閱
media_attachments:
validations:
images_and_video: 不能在已有圖片的文章上加入影片
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index 4585b729bc..8d3cfc6ee6 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -1212,7 +1212,6 @@ zh-TW:
application_mailer:
notification_preferences: 變更電子郵件設定
salutation: "%{name}、"
- settings: 變更電子郵件設定︰%{link}
unsubscribe: 取消訂閱
view: 進入瀏覽:
view_profile: 檢視個人檔案
@@ -1616,9 +1615,6 @@ zh-TW:
title: 認證歷史紀錄
mail_subscriptions:
unsubscribe:
- action: 是的,取消訂閱
- complete: 取消訂閱
- confirmation_html: 您確定要取要取消訂閱自 Mastodon 上 %{domain} 之 %{type} 至您電子郵件 %{email} 嗎?您隨時可以自電子郵件通知設定重新訂閱。
emails:
notification_emails:
favourite: 最愛通知電子郵件
@@ -1626,9 +1622,6 @@ zh-TW:
follow_request: 跟隨請求通知電子郵件
mention: 提及通知電子郵件
reblog: 轉嘟通知電子郵件
- resubscribe_html: 若您不慎錯誤地取消訂閱,您可以自電子郵件通知設定重新訂閱。
- success_html: 您將不再收到來自 Mastodon 上 %{domain} 之 %{type} 至您電子郵件 %{email}。
- title: 取消訂閱
media_attachments:
validations:
images_and_video: 無法於已有圖片之嘟文中加入影片
diff --git a/config/routes.rb b/config/routes.rb
index 1bc32a2861..d31331a6c1 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -71,7 +71,7 @@ Rails.application.routes.draw do
devise_scope :user do
get '/invite/:invite_code', to: 'auth/registrations#new', as: :public_invite
- resource :unsubscribe, only: [:show, :create], controller: :mail_subscriptions
+ resource :unsubscribe, only: [:show, :create], controller: :unsubscriptions
namespace :auth do
resource :setup, only: [:show, :update], controller: :setup
@@ -188,6 +188,10 @@ Rails.application.routes.draw do
resources :statuses, only: :show
end
+ namespace :email_subscriptions do
+ resource :confirmation, only: :show
+ end
+
resources :media, only: [:show] do
get :player
end
diff --git a/config/routes/api.rb b/config/routes/api.rb
index 285b032d01..61d74f4cd9 100644
--- a/config/routes/api.rb
+++ b/config/routes/api.rb
@@ -221,6 +221,7 @@ namespace :api, format: false do
resources :identity_proofs, only: :index
resources :featured_tags, only: :index
resources :endorsements, only: :index
+ resources :email_subscriptions, only: :create
end
member do
diff --git a/db/migrate/20260311212130_create_email_subscriptions.rb b/db/migrate/20260311212130_create_email_subscriptions.rb
new file mode 100644
index 0000000000..b750ccc7fc
--- /dev/null
+++ b/db/migrate/20260311212130_create_email_subscriptions.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class CreateEmailSubscriptions < ActiveRecord::Migration[8.1]
+ def change
+ create_table :email_subscriptions do |t|
+ t.references :account, null: false, foreign_key: { on_delete: :cascade }
+ t.string :email, null: false
+ t.string :locale, null: false
+ t.string :confirmation_token, index: { unique: true, where: 'confirmation_token is not null' }
+ t.datetime :confirmed_at
+
+ t.timestamps
+ end
+
+ add_index :email_subscriptions, [:account_id, :email], unique: true
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 69a9ef45da..1a839c2493 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -504,6 +504,19 @@ ActiveRecord::Schema[8.1].define(version: 2026_03_23_105645) do
t.index ["domain"], name: "index_email_domain_blocks_on_domain", unique: true
end
+ create_table "email_subscriptions", force: :cascade do |t|
+ t.bigint "account_id", null: false
+ t.string "confirmation_token"
+ t.datetime "confirmed_at"
+ t.datetime "created_at", null: false
+ t.string "email", null: false
+ t.string "locale", null: false
+ t.datetime "updated_at", null: false
+ t.index ["account_id", "email"], name: "index_email_subscriptions_on_account_id_and_email", unique: true
+ t.index ["account_id"], name: "index_email_subscriptions_on_account_id"
+ t.index ["confirmation_token"], name: "index_email_subscriptions_on_confirmation_token", unique: true, where: "(confirmation_token IS NOT NULL)"
+ end
+
create_table "fasp_backfill_requests", force: :cascade do |t|
t.string "category", null: false
t.datetime "created_at", null: false
@@ -1486,6 +1499,7 @@ ActiveRecord::Schema[8.1].define(version: 2026_03_23_105645) do
add_foreign_key "custom_filter_statuses", "statuses", on_delete: :cascade
add_foreign_key "custom_filters", "accounts", on_delete: :cascade
add_foreign_key "email_domain_blocks", "email_domain_blocks", column: "parent_id", on_delete: :cascade
+ add_foreign_key "email_subscriptions", "accounts", on_delete: :cascade
add_foreign_key "fasp_backfill_requests", "fasp_providers"
add_foreign_key "fasp_debug_callbacks", "fasp_providers"
add_foreign_key "fasp_follow_recommendations", "accounts", column: "recommended_account_id"
diff --git a/spec/fabricators/email_subscription_fabricator.rb b/spec/fabricators/email_subscription_fabricator.rb
new file mode 100644
index 0000000000..8d61945564
--- /dev/null
+++ b/spec/fabricators/email_subscription_fabricator.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+Fabricator(:email_subscription) do
+ account
+ email { sequence(:email) { |i| "#{i}#{Faker::Internet.email}" } }
+ locale 'en'
+end
diff --git a/spec/mailers/email_subscription_mailer_spec.rb b/spec/mailers/email_subscription_mailer_spec.rb
new file mode 100644
index 0000000000..0d8ec6e66b
--- /dev/null
+++ b/spec/mailers/email_subscription_mailer_spec.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe EmailSubscriptionMailer do
+ describe '.confirmation' do
+ let(:email_subscription) { Fabricate(:email_subscription) }
+ let(:mail) { described_class.with(subscription: email_subscription).confirmation }
+
+ it 'renders the email' do
+ expect { mail.deliver }
+ .to send_email(
+ to: email_subscription.email,
+ from: 'notifications@localhost',
+ subject: I18n.t('email_subscription_mailer.confirmation.subject')
+ )
+ end
+ end
+
+ describe '.notification' do
+ let(:email_subscription) { Fabricate(:email_subscription, confirmed_at: Time.now.utc) }
+ let(:statuses) { Fabricate.times(num_of_statuses, :status) }
+ let(:mail) { described_class.with(subscription: email_subscription).notification(statuses) }
+
+ context 'with a single status' do
+ let(:num_of_statuses) { 1 }
+
+ it 'renders the email' do
+ expect { mail.deliver }
+ .to send_email(
+ to: email_subscription.email,
+ from: 'notifications@localhost',
+ subject: I18n.t('email_subscription_mailer.notification.subject', count: statuses.size, name: email_subscription.account.display_name, excerpt: statuses.first.text.truncate(17))
+ )
+ end
+ end
+
+ context 'with multiple statuses' do
+ let(:num_of_statuses) { 2 }
+
+ it 'renders the email' do
+ expect { mail.deliver }
+ .to send_email(
+ to: email_subscription.email,
+ from: 'notifications@localhost',
+ subject: I18n.t('email_subscription_mailer.notification.subject', count: statuses.size, name: email_subscription.account.display_name, excerpt: ActionController::Base.helpers.truncate(statuses.first.text, length: 17))
+ )
+ end
+ end
+ end
+end
diff --git a/spec/mailers/previews/email_subscription_mailer_preview.rb b/spec/mailers/previews/email_subscription_mailer_preview.rb
new file mode 100644
index 0000000000..436e24c390
--- /dev/null
+++ b/spec/mailers/previews/email_subscription_mailer_preview.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+# Preview all emails at http://localhost:3000/rails/mailers/admin_mailer
+
+class EmailSubscriptionMailerPreview < ActionMailer::Preview
+ # Preview this email at http://localhost:3000/rails/mailers/email_subscription_mailer/confirmation
+ def confirmation
+ EmailSubscriptionMailer.with(subscription: EmailSubscription.last!).confirmation
+ end
+
+ # Preview this email at http://localhost:3000/rails/mailers/email_subscription_mailer/notification
+ def notification
+ EmailSubscriptionMailer.with(subscription: EmailSubscription.last!).notification(Status.where(visibility: :public).without_replies.without_reblogs.limit(5))
+ end
+end
diff --git a/spec/models/email_subscription_spec.rb b/spec/models/email_subscription_spec.rb
new file mode 100644
index 0000000000..6e1a0483f8
--- /dev/null
+++ b/spec/models/email_subscription_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe EmailSubscription do
+ describe '#confirmed?' do
+ it 'returns true when confirmed' do
+ subject.confirmed_at = Time.now.utc
+ expect(subject.confirmed?).to be true
+ end
+
+ it 'returns false when not confirmed' do
+ subject.confirmed_at = nil
+ expect(subject.confirmed?).to be false
+ end
+ end
+
+ describe '#confirm!' do
+ subject { Fabricate(:email_subscription) }
+
+ it 'records confirmation time' do
+ subject.confirm!
+ expect(subject.confirmed_at).to_not be_nil
+ end
+ end
+
+ describe 'Callbacks' do
+ subject { Fabricate(:email_subscription) }
+
+ it 'generates token and delivers confirmation email', :inline_jobs do
+ emails = capture_emails { subject }
+
+ expect(subject.confirmed_at).to be_nil
+ expect(subject.confirmation_token).to_not be_nil
+ expect(emails.size).to eq(1)
+ expect(emails.first)
+ .to have_attributes(
+ to: contain_exactly(subject.email),
+ subject: eq(I18n.t('email_subscription_mailer.confirmation.subject', name: subject.account.username, domain: Rails.configuration.x.local_domain))
+ )
+ end
+ end
+end
diff --git a/spec/requests/api/v1/accounts/email_subscriptions_spec.rb b/spec/requests/api/v1/accounts/email_subscriptions_spec.rb
new file mode 100644
index 0000000000..ef7a31476a
--- /dev/null
+++ b/spec/requests/api/v1/accounts/email_subscriptions_spec.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Accounts Email Subscriptions API', feature: :email_subscriptions do
+ let(:account) { Fabricate(:user).account }
+
+ describe 'POST /api/v1/accounts/:id/email_subscriptions' do
+ context 'when the account has the permission' do
+ let(:role) { Fabricate(:user_role, permissions: UserRole::FLAGS[:manage_email_subscriptions]) }
+
+ before do
+ account.user.update!(role: role)
+ end
+
+ context 'when user has enabled the setting' do
+ before do
+ account.user.settings['email_subscriptions'] = true
+ account.user.save!
+ end
+
+ it 'returns http success' do
+ post "/api/v1/accounts/#{account.id}/email_subscriptions", params: { email: 'test@example.com' }
+
+ expect(response).to have_http_status(200)
+ expect(response.content_type)
+ .to start_with('application/json')
+ end
+ end
+
+ context 'when user has not enabled the setting' do
+ it 'returns http not found' do
+ post "/api/v1/accounts/#{account.id}/email_subscriptions", params: { email: 'test@example.com' }
+
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+
+ context 'when the account does not have the permission' do
+ it 'returns http not found' do
+ post "/api/v1/accounts/#{account.id}/email_subscriptions", params: { email: 'test@example.com' }
+
+ expect(response).to have_http_status(404)
+ end
+ end
+ end
+end
diff --git a/spec/requests/email_subscriptions/confirmations_spec.rb b/spec/requests/email_subscriptions/confirmations_spec.rb
new file mode 100644
index 0000000000..909aab1b77
--- /dev/null
+++ b/spec/requests/email_subscriptions/confirmations_spec.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+require 'rails_helper'
+
+RSpec.describe 'Email Subscriptions Confirmation' do
+ describe 'GET /email_subscriptions/confirmation' do
+ context 'when email subscription is unconfirmed' do
+ let!(:email_subscription) { Fabricate(:email_subscription, confirmed_at: nil) }
+
+ it 'renders success page and updates subscription as confirmed' do
+ get email_subscriptions_confirmation_path(confirmation_token: email_subscription.confirmation_token)
+
+ expect(response)
+ .to have_http_status(200)
+ expect(email_subscription.reload.confirmed?)
+ .to be true
+ end
+ end
+
+ context 'when email subscription is already confirmed' do
+ let!(:email_subscription) { Fabricate(:email_subscription, confirmed_at: Time.now.utc) }
+
+ it 'renders success page' do
+ get email_subscriptions_confirmation_path(confirmation_token: email_subscription.confirmation_token)
+
+ expect(response)
+ .to have_http_status(200)
+ expect(email_subscription.reload.confirmed?)
+ .to be true
+ end
+ end
+ end
+end
diff --git a/spec/requests/mail_subscriptions_spec.rb b/spec/requests/unsubscriptions_spec.rb
similarity index 90%
rename from spec/requests/mail_subscriptions_spec.rb
rename to spec/requests/unsubscriptions_spec.rb
index cc6557cab0..95a1499223 100644
--- a/spec/requests/mail_subscriptions_spec.rb
+++ b/spec/requests/unsubscriptions_spec.rb
@@ -2,7 +2,7 @@
require 'rails_helper'
-RSpec.describe 'MailSubscriptionsController' do
+RSpec.describe 'UnsubscriptionsController' do
let(:user) { Fabricate(:user) }
let(:token) { user.to_sgid(for: 'unsubscribe').to_s }
let(:type) { 'follow' }
@@ -39,9 +39,8 @@ RSpec.describe 'MailSubscriptionsController' do
expect(response).to have_http_status(200)
expect(response.body).to include(
- I18n.t('mail_subscriptions.unsubscribe.action')
+ I18n.t('unsubscriptions.show.action')
)
- expect(response.body).to include(user.email)
end
end
@@ -60,9 +59,8 @@ RSpec.describe 'MailSubscriptionsController' do
expect(response).to have_http_status(200)
expect(response.body).to include(
- I18n.t('mail_subscriptions.unsubscribe.complete')
+ I18n.t('unsubscriptions.create.title')
)
- expect(response.body).to include(user.email)
end
it 'updates notification settings' do
diff --git a/spec/services/bootstrap_timeline_service_spec.rb b/spec/services/bootstrap_timeline_service_spec.rb
index c99813bceb..4c2d129e9e 100644
--- a/spec/services/bootstrap_timeline_service_spec.rb
+++ b/spec/services/bootstrap_timeline_service_spec.rb
@@ -3,35 +3,31 @@
require 'rails_helper'
RSpec.describe BootstrapTimelineService do
- subject { described_class.new }
+ subject { described_class.new.call(new_user.account) }
+
+ let(:invite) { nil }
+ let(:new_user) { Fabricate(:user, invite_code: invite&.code) }
context 'when the new user has registered from an invite' do
- let(:service) { instance_double(FollowService) }
let(:autofollow) { false }
let(:inviter) { Fabricate(:user, confirmed_at: 2.days.ago) }
let(:invite) { Fabricate(:invite, user: inviter, max_uses: nil, expires_at: 1.hour.from_now, autofollow: autofollow) }
- let(:new_user) { Fabricate(:user, invite_code: invite.code) }
-
- before do
- allow(FollowService).to receive(:new).and_return(service)
- allow(service).to receive(:call)
- end
context 'when the invite has auto-follow enabled' do
let(:autofollow) { true }
- it 'calls FollowService to follow the inviter' do
- subject.call(new_user.account)
- expect(service).to have_received(:call).with(new_user.account, inviter.account)
+ it 'follows the inviter' do
+ subject
+ expect(new_user.account.following?(inviter.account)).to be true
end
end
context 'when the invite does not have auto-follow enable' do
let(:autofollow) { false }
- it 'calls FollowService to follow the inviter' do
- subject.call(new_user.account)
- expect(service).to_not have_received(:call)
+ it 'does not follow the inviter' do
+ subject
+ expect(new_user.account.following?(inviter.account)).to be false
end
end
end