diff --git a/Gemfile b/Gemfile index d6ef64cf7d..9654c8828b 100644 --- a/Gemfile +++ b/Gemfile @@ -55,6 +55,7 @@ group :development, :test do gem 'pry-rails' gem 'fuubar' gem 'fabrication' + gem 'i18n-tasks', '~> 0.9.6' end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index 9657ee212a..a31573af69 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -103,6 +103,10 @@ GEM dotenv-rails (2.1.1) dotenv (= 2.1.1) railties (>= 4.0, < 5.1) + easy_translate (0.5.0) + json + thread + thread_safe erubis (2.7.0) excon (0.53.0) execjs (2.7.0) @@ -129,6 +133,7 @@ GEM hamlit (>= 1.2.0) railties (>= 4.0.1) hashdiff (0.3.0) + highline (1.7.8) hiredis (0.6.1) htmlentities (4.3.4) http (2.0.3) @@ -143,6 +148,16 @@ GEM httplog (0.3.2) colorize i18n (0.7.0) + i18n-tasks (0.9.6) + activesupport (>= 4.0.2) + ast (>= 2.1.0) + easy_translate (>= 0.5.0) + erubis + highline (>= 1.7.3) + i18n + parser (>= 2.2.3.0) + term-ansicolor (>= 1.3.2) + terminal-table (>= 1.5.1) jbuilder (2.6.0) activesupport (>= 3.0.0, < 5.1) multi_json (~> 1.2) @@ -352,9 +367,15 @@ GEM activesupport (>= 4.0) sprockets (>= 3.0.0) temple (0.7.7) + term-ansicolor (1.4.0) + tins (~> 1.0) + terminal-table (1.7.0) + unicode-display_width (~> 1.1) thor (0.19.1) + thread (0.2.2) thread_safe (0.3.5) tilt (2.0.5) + tins (1.12.0) tzinfo (1.2.2) thread_safe (~> 0.1) uglifier (3.0.1) @@ -401,6 +422,7 @@ DEPENDENCIES htmlentities http httplog + i18n-tasks (~> 0.9.6) jbuilder (~> 2.0) jquery-rails ledermann-rails-settings diff --git a/app/mailers/notification_mailer.rb b/app/mailers/notification_mailer.rb index 2ed5629792..33bea4c799 100644 --- a/app/mailers/notification_mailer.rb +++ b/app/mailers/notification_mailer.rb @@ -8,7 +8,7 @@ class NotificationMailer < ApplicationMailer @status = status return unless @me.user.settings(:notification_emails).mention - mail to: @me.user.email, subject: "You were mentioned by #{@status.account.acct}" + mail to: @me.user.email, subject: I18n.t('notification_mailer.mention.subject', name: @status.account.acct) end def follow(followed_account, follower) @@ -16,7 +16,7 @@ class NotificationMailer < ApplicationMailer @account = follower return unless @me.user.settings(:notification_emails).follow - mail to: @me.user.email, subject: "#{@account.acct} is now following you" + mail to: @me.user.email, subject: I18n.t('notification_mailer.follow.subject', name: @account.acct) end def favourite(target_status, from_account) @@ -25,7 +25,7 @@ class NotificationMailer < ApplicationMailer @status = target_status return unless @me.user.settings(:notification_emails).favourite - mail to: @me.user.email, subject: "#{@account.acct} favourited your status" + mail to: @me.user.email, subject: I18n.t('notification_mailer.favourite.subject', name: @account.acct) end def reblog(target_status, from_account) @@ -34,6 +34,6 @@ class NotificationMailer < ApplicationMailer @status = target_status return unless @me.user.settings(:notification_emails).reblog - mail to: @me.user.email, subject: "#{@account.acct} reblogged your status" + mail to: @me.user.email, subject: I18n.t('notification_mailer.reblog.subject', name: @account.acct) end end diff --git a/app/views/about/index.html.haml b/app/views/about/index.html.haml index e9e2f9d93c..307d75c815 100644 --- a/app/views/about/index.html.haml +++ b/app/views/about/index.html.haml @@ -6,24 +6,15 @@ = image_tag 'logo.png' Mastodon - %p - Mastodon is a - %em free, open-source - social network server. A - %em decentralized - alternative to commercial platforms, it avoids the risks of a single company monopolizing your communication. Anyone can run Mastodon and participate in the - %em social network - seamlessly. - %p - %em= Rails.configuration.x.local_domain - is a Mastodon instance. + %p= t('about.about_mastodon').html_safe + %p= t('about.about_instance', instance: Rails.configuration.x.local_domain).html_safe .screenshot= image_tag 'screenshot.png' .actions .info - = link_to 'Terms', terms_path - = link_to 'Source code', 'https://github.com/Gargron/mastodon' + = link_to t('about.terms'), terms_path + = link_to t('about.source_code'), 'https://github.com/Gargron/mastodon' - = link_to 'Get started', new_user_registration_path, class: 'button' - = link_to 'Log in', new_user_session_path, class: 'button' + = link_to t('about.get_started'), new_user_registration_path, class: 'button' + = link_to t('auth.login'), new_user_session_path, class: 'button' diff --git a/app/views/about/terms.html.haml b/app/views/about/terms.en.html.haml similarity index 100% rename from app/views/about/terms.html.haml rename to app/views/about/terms.en.html.haml diff --git a/app/views/accounts/_header.html.haml b/app/views/accounts/_header.html.haml index ec2233b773..0063d9f160 100644 --- a/app/views/accounts/_header.html.haml +++ b/app/views/accounts/_header.html.haml @@ -2,9 +2,9 @@ - if user_signed_in? && current_account.id != @account.id .controls - if current_account.following?(@account) - = link_to 'Unfollow', unfollow_account_path(@account), data: { method: :post }, class: 'button' + = link_to t('accounts.unfollow'), unfollow_account_path(@account), data: { method: :post }, class: 'button' - else - = link_to 'Follow', follow_account_path(@account), data: { method: :post }, class: 'button' + = link_to t('accounts.follow'), follow_account_path(@account), data: { method: :post }, class: 'button' .avatar= image_tag @account.avatar.url(:large) %h1.name @@ -17,13 +17,13 @@ .details-counters .counter{ class: active_nav_class(account_url(@account)) } = link_to account_url(@account) do - %span.counter-label Posts + %span.counter-label= t('accounts.posts') %span.counter-number= @account.statuses.count .counter{ class: active_nav_class(following_account_url(@account)) } = link_to following_account_url(@account) do - %span.counter-label Following + %span.counter-label= t('accounts.following') %span.counter-number= @account.following.count .counter{ class: active_nav_class(followers_account_url(@account)) } = link_to followers_account_url(@account) do - %span.counter-label Followers + %span.counter-label= t('accounts.followers') %span.counter-number= @account.followers.count diff --git a/app/views/accounts/_nothing_here.html.haml b/app/views/accounts/_nothing_here.html.haml index faa1feb20b..0c6dc11684 100644 --- a/app/views/accounts/_nothing_here.html.haml +++ b/app/views/accounts/_nothing_here.html.haml @@ -1 +1 @@ -%p.nothing-here There is nothing here! +%p.nothing-here= t('accounts.nothing_here') diff --git a/app/views/accounts/followers.html.haml b/app/views/accounts/followers.html.haml index 7a6e270ac6..4934910201 100644 --- a/app/views/accounts/followers.html.haml +++ b/app/views/accounts/followers.html.haml @@ -1,6 +1,5 @@ - content_for :page_title do - People who follow - = display_name(@account) + = t('accounts.people_who_follow', name: display_name(@account)) = render partial: 'header' diff --git a/app/views/accounts/following.html.haml b/app/views/accounts/following.html.haml index 95843f64d0..370cd6c483 100644 --- a/app/views/accounts/following.html.haml +++ b/app/views/accounts/following.html.haml @@ -1,7 +1,5 @@ - content_for :page_title do - People whom - = display_name(@account) - follows + = t('accounts.people_followed_by', name: display_name(@account)) = render partial: 'header' diff --git a/app/views/auth/mailer/confirmation_instructions.html.erb b/app/views/auth/mailer/confirmation_instructions.en.html.erb similarity index 100% rename from app/views/auth/mailer/confirmation_instructions.html.erb rename to app/views/auth/mailer/confirmation_instructions.en.html.erb diff --git a/app/views/auth/mailer/confirmation_instructions.text.erb b/app/views/auth/mailer/confirmation_instructions.en.text.erb similarity index 100% rename from app/views/auth/mailer/confirmation_instructions.text.erb rename to app/views/auth/mailer/confirmation_instructions.en.text.erb diff --git a/app/views/auth/mailer/password_change.html.erb b/app/views/auth/mailer/password_change.en.html.erb similarity index 100% rename from app/views/auth/mailer/password_change.html.erb rename to app/views/auth/mailer/password_change.en.html.erb diff --git a/app/views/auth/mailer/password_change.text.erb b/app/views/auth/mailer/password_change.en.text.erb similarity index 100% rename from app/views/auth/mailer/password_change.text.erb rename to app/views/auth/mailer/password_change.en.text.erb diff --git a/app/views/auth/mailer/reset_password_instructions.html.erb b/app/views/auth/mailer/reset_password_instructions.en.html.erb similarity index 100% rename from app/views/auth/mailer/reset_password_instructions.html.erb rename to app/views/auth/mailer/reset_password_instructions.en.html.erb diff --git a/app/views/auth/mailer/reset_password_instructions.text.erb b/app/views/auth/mailer/reset_password_instructions.en.text.erb similarity index 100% rename from app/views/auth/mailer/reset_password_instructions.text.erb rename to app/views/auth/mailer/reset_password_instructions.en.text.erb diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb index 6327024397..ae52173b54 100644 --- a/app/views/layouts/mailer.text.erb +++ b/app/views/layouts/mailer.text.erb @@ -2,4 +2,4 @@ --- -Mastodon notifications from <%= Rails.configuration.x.local_domain %> +<%= t('application_mailer.signature', instance: Rails.configuration.x.local_domain) %> diff --git a/app/views/notification_mailer/favourite.text.erb b/app/views/notification_mailer/favourite.text.erb index 1b6fa274cc..b2e1e3e9e8 100644 --- a/app/views/notification_mailer/favourite.text.erb +++ b/app/views/notification_mailer/favourite.text.erb @@ -1,5 +1,5 @@ <%= display_name(@me) %>, -Your status was favourited by <%= @account.acct %>: +<%= t('notification_mailer.favourite.body', name: @account.acct) %> <%= render partial: 'status' %> diff --git a/app/views/notification_mailer/follow.text.erb b/app/views/notification_mailer/follow.text.erb index 4098e4846c..4b2ec142c2 100644 --- a/app/views/notification_mailer/follow.text.erb +++ b/app/views/notification_mailer/follow.text.erb @@ -1,5 +1,5 @@ <%= display_name(@me) %>, -<%= @account.acct %> is now following you! +<%= t('notification_mailer.follow.body', name: @account.acct) %> <%= web_url("accounts/#{@account.id}") %> diff --git a/app/views/notification_mailer/mention.text.erb b/app/views/notification_mailer/mention.text.erb index 72dc1b0094..31a294bb94 100644 --- a/app/views/notification_mailer/mention.text.erb +++ b/app/views/notification_mailer/mention.text.erb @@ -1,5 +1,5 @@ <%= display_name(@me) %>, -You were mentioned by <%= @status.account.acct %> in: +<%= t('notification_mailer.mention.body', name: @status.account.acct) %> <%= render partial: 'status' %> diff --git a/app/views/notification_mailer/reblog.text.erb b/app/views/notification_mailer/reblog.text.erb index 2077e949ec..7af8052ca4 100644 --- a/app/views/notification_mailer/reblog.text.erb +++ b/app/views/notification_mailer/reblog.text.erb @@ -1,5 +1,5 @@ <%= display_name(@me) %>, -Your status was reblogged by <%= @account.acct %>: +<%= t('notification_mailer.reblog.body', name: @account.acct) %> <%= render partial: 'status' %> diff --git a/app/views/oauth/authorizations/new.html.haml b/app/views/oauth/authorizations/new.html.haml index ba5d426f5c..cd6e93e08a 100644 --- a/app/views/oauth/authorizations/new.html.haml +++ b/app/views/oauth/authorizations/new.html.haml @@ -1,11 +1,11 @@ +- content_for :page_title do + = t('doorkeeper.authorizations.new.title') + .oauth-prompt - %h2 - Application - %strong=@pre_auth.client.name - requests access to your account + %h2= t('doorkeeper.authorizations.new.prompt', name: @pre_auth.client.name) %p - It will be able to + = t('doorkeeper.authorizations.new.able_to') = @pre_auth.scopes.map { |scope| t(scope, scope: [:doorkeeper, :scopes]) }.map { |s| "#{s}"}.to_sentence.html_safe = form_tag oauth_authorization_path, method: :post, class: 'simple_form' do diff --git a/app/views/stream_entries/_favourite.html.haml b/app/views/stream_entries/_favourite.html.haml index 85e3a08249..aac90dcdf8 100644 --- a/app/views/stream_entries/_favourite.html.haml +++ b/app/views/stream_entries/_favourite.html.haml @@ -1,5 +1,5 @@ .entry.entry-favourite .content %strong= favourite.account.acct - favourited a post by + = t('stream_entries.favourited') %strong= favourite.status.account.acct diff --git a/app/views/stream_entries/_follow.html.haml b/app/views/stream_entries/_follow.html.haml index f6ec8c4f5b..1a2e2c5541 100644 --- a/app/views/stream_entries/_follow.html.haml +++ b/app/views/stream_entries/_follow.html.haml @@ -1,5 +1,5 @@ .entry.entry-follow .content %strong= link_to follow.account.acct, account_path(follow.account) - is now following + = t('stream_entries.is_now_following') %strong= link_to follow.target_account.acct, TagManager.instance.url_for(follow.target_account) diff --git a/config/application.rb b/config/application.rb index 5b5e66ca75..6525571cc7 100644 --- a/config/application.rb +++ b/config/application.rb @@ -31,16 +31,16 @@ module Mastodon allow do origins '*' - resource '/api/*', :headers => :any, :methods => [:post, :put, :delete, :get, :options], credentials: false - resource '/oauth/token', :headers => :any, :methods => [:post], credentials: false + resource '/api/*', headers: :any, methods: [:post, :put, :delete, :get, :options], credentials: false + resource '/oauth/token', headers: :any, methods: [:post], credentials: false end end config.middleware.use Rack::Attack config.middleware.use Rack::Deflater - config.browserify_rails.source_map_environments += %w[development production] - config.browserify_rails.commandline_options = "--transform [ babelify --presets [ es2015 react ] ] --extension=\".jsx\"" + config.browserify_rails.source_map_environments += %w(development production) + config.browserify_rails.commandline_options = '--transform [ babelify --presets [ es2015 react ] ] --extension=".jsx"' config.to_prepare do Doorkeeper::AuthorizationsController.layout 'auth' @@ -50,7 +50,7 @@ module Mastodon 'Server' => 'Mastodon', 'X-Frame-Options' => 'DENY', 'X-Content-Type-Options' => 'nosniff', - 'X-XSS-Protection' => '1; mode=block' + 'X-XSS-Protection' => '1; mode=block', } end end diff --git a/config/i18n-tasks.yml b/config/i18n-tasks.yml new file mode 100644 index 0000000000..d345ce6c06 --- /dev/null +++ b/config/i18n-tasks.yml @@ -0,0 +1,43 @@ +# i18n-tasks finds and manages missing and unused translations: https://github.com/glebm/i18n-tasks + +# The "main" locale. +base_locale: en +data: + read: + - config/locales/%{locale}.yml + - config/locales/**/*.%{locale}.yml + + write: + - ['{devise, simple_form, doorkeeper}.*', 'config/locales/\1.%{locale}.yml'] + - config/locales/%{locale}.yml + + yaml: + write: + line_width: -1 + +search: + paths: + - app/ + + relative_roots: + - app/controllers + - app/helpers + - app/mailers + - app/views + + exclude: + - app/assets/images + - app/assets/fonts + - app/assets/videos + +ignore_missing: + - '{devise,simple_form}.*' + +ignore_unused: + - 'activerecord.attributes.*' + - '{devise,will_paginate,doorkeeper}.*' + - 'simple_form.{yes,no}' + - 'simple_form.{placeholders,hints,labels}.*' + - 'simple_form.{error_notification,required}.:' + - 'errors.messages.*' + - 'activerecord.errors.models.doorkeeper/*' diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index acf79149d6..43f7860cb0 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -8,4 +8,5 @@ Rails.application.config.assets.version = '1.0' # Precompile additional assets. # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. -Rails.application.config.assets.precompile += %w( application_public.js ) +Rails.application.config.assets.precompile += %w(application_public.js) +Rails.application.config.assets.initialize_on_precompile = true diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml index d06eee4fdc..32ac92cf9b 100644 --- a/config/locales/devise.en.yml +++ b/config/locales/devise.en.yml @@ -1,62 +1,61 @@ -# Additional translations at https://github.com/plataformatec/devise/wiki/I18n - +--- en: devise: confirmations: - confirmed: "Your email address has been successfully confirmed." - send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes." - send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes." + confirmed: Your email address has been successfully confirmed. + send_instructions: You will receive an email with instructions for how to confirm your email address in a few minutes. + send_paranoid_instructions: If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes. failure: - already_authenticated: "You are already signed in." - inactive: "Your account is not activated yet." - invalid: "Invalid %{authentication_keys} or password." - locked: "Your account is locked." - last_attempt: "You have one more attempt before your account is locked." - not_found_in_database: "Invalid %{authentication_keys} or password." - timeout: "Your session expired. Please sign in again to continue." - unauthenticated: "You need to sign in or sign up before continuing." - unconfirmed: "You have to confirm your email address before continuing." + already_authenticated: You are already signed in. + inactive: Your account is not activated yet. + invalid: Invalid %{authentication_keys} or password. + last_attempt: You have one more attempt before your account is locked. + locked: Your account is locked. + not_found_in_database: Invalid %{authentication_keys} or password. + timeout: Your session expired. Please sign in again to continue. + unauthenticated: You need to sign in or sign up before continuing. + unconfirmed: You have to confirm your email address before continuing. mailer: confirmation_instructions: - subject: "Mastodon: Confirmation instructions" - reset_password_instructions: - subject: "Mastodon: Reset password instructions" - unlock_instructions: - subject: "Mastodon: Unlock instructions" + subject: 'Mastodon: Confirmation instructions' password_change: - subject: "Mastodon: Password changed" + subject: 'Mastodon: Password changed' + reset_password_instructions: + subject: 'Mastodon: Reset password instructions' + unlock_instructions: + subject: 'Mastodon: Unlock instructions' omniauth_callbacks: - failure: "Could not authenticate you from %{kind} because \"%{reason}\"." - success: "Successfully authenticated from %{kind} account." + failure: Could not authenticate you from %{kind} because "%{reason}". + success: Successfully authenticated from %{kind} account. passwords: - no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided." - send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes." - send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." - updated: "Your password has been changed successfully. You are now signed in." - updated_not_active: "Your password has been changed successfully." + no_token: You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided. + send_instructions: You will receive an email with instructions on how to reset your password in a few minutes. + send_paranoid_instructions: If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes. + updated: Your password has been changed successfully. You are now signed in. + updated_not_active: Your password has been changed successfully. registrations: - destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon." - signed_up: "Welcome! You have signed up successfully." - signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." - signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." - signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account." - update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address." - updated: "Your account has been updated successfully." + destroyed: Bye! Your account has been successfully cancelled. We hope to see you again soon. + signed_up: Welcome! You have signed up successfully. + signed_up_but_inactive: You have signed up successfully. However, we could not sign you in because your account is not yet activated. + signed_up_but_locked: You have signed up successfully. However, we could not sign you in because your account is locked. + signed_up_but_unconfirmed: A message with a confirmation link has been sent to your email address. Please follow the link to activate your account. + update_needs_confirmation: You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address. + updated: Your account has been updated successfully. sessions: - signed_in: "Signed in successfully." - signed_out: "Signed out successfully." - already_signed_out: "Signed out successfully." + already_signed_out: Signed out successfully. + signed_in: Signed in successfully. + signed_out: Signed out successfully. unlocks: - send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes." - send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes." - unlocked: "Your account has been unlocked successfully. Please sign in to continue." + send_instructions: You will receive an email with instructions for how to unlock your account in a few minutes. + send_paranoid_instructions: If your account exists, you will receive an email with instructions for how to unlock it in a few minutes. + unlocked: Your account has been unlocked successfully. Please sign in to continue. errors: messages: - already_confirmed: "was already confirmed, please try signing in" - confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" - expired: "has expired, please request a new one" - not_found: "not found" - not_locked: "was not locked" + already_confirmed: was already confirmed, please try signing in + confirmation_period_expired: needs to be confirmed within %{period}, please request a new one + expired: has expired, please request a new one + not_found: not found + not_locked: was not locked not_saved: - one: "1 error prohibited this %{resource} from being saved:" + one: '1 error prohibited this %{resource} from being saved:' other: "%{count} errors prohibited this %{resource} from being saved:" diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml index e4444c9722..aaf5df6fcf 100644 --- a/config/locales/doorkeeper.en.yml +++ b/config/locales/doorkeeper.en.yml @@ -1,127 +1,112 @@ +--- en: activerecord: attributes: doorkeeper/application: - name: 'Name' - redirect_uri: 'Redirect URI' + name: Name + redirect_uri: Redirect URI errors: models: doorkeeper/application: attributes: redirect_uri: - fragment_present: 'cannot contain a fragment.' - invalid_uri: 'must be a valid URI.' - relative_uri: 'must be an absolute URI.' - secured_uri: 'must be an HTTPS/SSL URI.' - + fragment_present: cannot contain a fragment. + invalid_uri: must be a valid URI. + relative_uri: must be an absolute URI. + secured_uri: must be an HTTPS/SSL URI. doorkeeper: - scopes: - read: read your account's data - write: post on your behalf - follow: follow, block, unblock and unfollow accounts applications: - confirmations: - destroy: 'Are you sure?' buttons: - edit: 'Edit' - destroy: 'Destroy' - submit: 'Submit' - cancel: 'Cancel' - authorize: 'Authorize' - form: - error: 'Whoops! Check your form for possible errors' - help: - redirect_uri: 'Use one line per URI' - native_redirect_uri: 'Use %{native_redirect_uri} for local tests' - scopes: 'Separate scopes with spaces. Leave blank to use the default scopes.' + authorize: Authorize + cancel: Cancel + destroy: Destroy + edit: Edit + submit: Submit + confirmations: + destroy: Are you sure? edit: - title: 'Edit application' + title: Edit application + form: + error: Whoops! Check your form for possible errors + help: + native_redirect_uri: Use %{native_redirect_uri} for local tests + redirect_uri: Use one line per URI + scopes: Separate scopes with spaces. Leave blank to use the default scopes. index: - title: 'Your applications' - new: 'New Application' - name: 'Name' - callback_url: 'Callback URL' + callback_url: Callback URL + name: Name + new: New Application + title: Your applications new: - title: 'New Application' + title: New Application show: + actions: Actions + application_id: Application Id + callback_urls: Callback urls + scopes: Scopes + secret: Secret title: 'Application: %{name}' - application_id: 'Application Id' - secret: 'Secret' - scopes: 'Scopes' - callback_urls: 'Callback urls' - actions: 'Actions' - authorizations: buttons: - authorize: 'Authorize' - deny: 'Deny' + authorize: Authorize + deny: Deny error: - title: 'An error has occurred' + title: An error has occurred new: - title: 'Authorization required' - prompt: 'Authorize %{client_name} to use your account?' - able_to: 'This application will be able to' + able_to: It will be able to + prompt: Application %{client_name} requests access to your account + title: Authorization required show: - title: 'Authorization code' - + title: Authorization code authorized_applications: - confirmations: - revoke: 'Are you sure?' buttons: - revoke: 'Revoke' + revoke: Revoke + confirmations: + revoke: Are you sure? index: - title: 'Your authorized applications' - application: 'Application' - created_at: 'Created At' - date_format: '%Y-%m-%d %H:%M:%S' - + application: Application + created_at: Created At + date_format: "%Y-%m-%d %H:%M:%S" + title: Your authorized applications errors: messages: - # Common error messages - invalid_request: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.' - invalid_redirect_uri: 'The redirect uri included is not valid.' - unauthorized_client: 'The client is not authorized to perform this request using this method.' - access_denied: 'The resource owner or authorization server denied the request.' - invalid_scope: 'The requested scope is invalid, unknown, or malformed.' - server_error: 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.' - temporarily_unavailable: 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.' - - #configuration error messages - credential_flow_not_configured: 'Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.' - resource_owner_authenticator_not_configured: 'Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged.' - - # Access grant errors - unsupported_response_type: 'The authorization server does not support this response type.' - - # Access token errors - invalid_client: 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.' - invalid_grant: 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.' - unsupported_grant_type: 'The authorization grant type is not supported by the authorization server.' - - # Password Access token errors - invalid_resource_owner: 'The provided resource owner credentials are not valid, or resource owner cannot be found' - + access_denied: The resource owner or authorization server denied the request. + credential_flow_not_configured: Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured. + invalid_client: Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method. + invalid_grant: The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client. + invalid_redirect_uri: The redirect uri included is not valid. + invalid_request: The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed. + invalid_resource_owner: The provided resource owner credentials are not valid, or resource owner cannot be found + invalid_scope: The requested scope is invalid, unknown, or malformed. invalid_token: - revoked: "The access token was revoked" - expired: "The access token expired" - unknown: "The access token is invalid" - + expired: The access token expired + revoked: The access token was revoked + unknown: The access token is invalid + resource_owner_authenticator_not_configured: Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfiged. + server_error: The authorization server encountered an unexpected condition which prevented it from fulfilling the request. + temporarily_unavailable: The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server. + unauthorized_client: The client is not authorized to perform this request using this method. + unsupported_grant_type: The authorization grant type is not supported by the authorization server. + unsupported_response_type: The authorization server does not support this response type. flash: applications: create: - notice: 'Application created.' + notice: Application created. destroy: - notice: 'Application deleted.' + notice: Application deleted. update: - notice: 'Application updated.' + notice: Application updated. authorized_applications: destroy: - notice: 'Application revoked.' - + notice: Application revoked. layouts: admin: nav: - oauth2_provider: 'OAuth2 Provider' - applications: 'Applications' + applications: Applications + oauth2_provider: OAuth2 Provider application: - title: 'OAuth authorization required' + title: OAuth authorization required + scopes: + follow: follow, block, unblock and unfollow accounts + read: read your account's data + write: post on your behalf diff --git a/config/locales/en.yml b/config/locales/en.yml index 55b062c0de..ab16ed0821 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1,23 +1,57 @@ +--- en: + about: + about_instance: "%{instance} is a Mastodon instance." + about_mastodon: Mastodon is a free, open-source social network server. A decentralized alternative to commercial platforms, it avoids the risks of a single company monopolizing your communication. Anyone can run Mastodon and participate in the social network seamlessly. + get_started: Get started + source_code: Source code + terms: Terms + accounts: + follow: Follow + followers: Followers + following: Following + nothing_here: There is nothing here! + people_followed_by: People whom %{name} follows + people_who_follow: People who follow %{name} + posts: Posts + unfollow: Unfollow + application_mailer: + signature: Mastodon notifications from %{instance} auth: + change_password: Change password + didnt_get_confirmation: Didn't receive confirmation instructions? + forgot_password: Forgot your password? login: Log in register: Sign up - forgot_password: Forgot your password? - didnt_get_confirmation: Didn't receive confirmation instructions? resend_confirmation: Resend confirmation instructions reset_password: Reset password set_new_password: Set new password - change_password: Change password generic: + changes_saved_msg: Changes successfully saved! + powered_by: powered by %{link} save_changes: Save changes validation_errors: one: Something isn't quite right yet! Please review the error below other: Something isn't quite right yet! Please review %{count} errors below - powered_by: powered by %{link} - changes_saved_msg: Changes successfully saved! + notification_mailer: + favourite: + body: 'Your status was favourited by %{name}:' + subject: "%{name} favourited your status" + follow: + body: "%{name} is now following you!" + subject: "%{name} is now following you" + mention: + body: 'You were mentioned by %{name} in:' + subject: You were mentioned by %{name} + reblog: + body: 'Your status was reblogged by %{name}:' + subject: "%{name} reblogged your status" pagination: next: Next prev: Prev settings: edit_profile: Edit profile preferences: Preferences + stream_entries: + favourited: favourited a post by + is_now_following: is now following diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml index 34bc94963e..ef69f75696 100644 --- a/config/locales/simple_form.en.yml +++ b/config/locales/simple_form.en.yml @@ -1,43 +1,28 @@ +--- en: simple_form: - "yes": 'Yes' - "no": 'No' - required: - text: 'required' - mark: '*' error_notification: - default_message: "Please review the problems below:" - + default_message: 'Please review the problems below:' labels: defaults: - email: E-mail address - password: Password - username: Username - confirm_password: Confirm password - new_password: New password + avatar: Avatar confirm_new_password: Confirm new password + confirm_password: Confirm password current_password: Current password display_name: Display name - note: Bio - avatar: Avatar + email: E-mail address header: Header + new_password: New password + note: Bio + password: Password + username: Username notification_emails: - follow: Send e-mail when someone follows you - reblog: Send e-mail when someone reblogs your status favourite: Send e-mail when someone favourites your status + follow: Send e-mail when someone follows you mention: Send e-mail when someone mentions you - # user: - # new: - # email: 'E-mail to sign in.' - # edit: - # email: 'E-mail.' - # hints: - # defaults: - # username: 'User name to sign in.' - # password: 'No special characters, please.' - # include_blanks: - # defaults: - # age: 'Rather not say' - # prompts: - # defaults: - # age: 'Select your age' + reblog: Send e-mail when someone reblogs your status + 'no': 'No' + required: + mark: "*" + text: required + 'yes': 'Yes' diff --git a/spec/i18n_spec.rb b/spec/i18n_spec.rb new file mode 100644 index 0000000000..e7126127e0 --- /dev/null +++ b/spec/i18n_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true +require 'i18n/tasks' + +RSpec.describe 'I18n' do + let(:i18n) { I18n::Tasks::BaseTask.new } + let(:missing_keys) { i18n.missing_keys } + let(:unused_keys) { i18n.unused_keys } + + it 'does not have missing keys' do + expect(missing_keys).to be_empty, + "Missing #{missing_keys.leaves.count} i18n keys, run `i18n-tasks missing' to show them" + end + + it 'does not have unused keys' do + expect(unused_keys).to be_empty, + "#{unused_keys.leaves.count} unused i18n keys, run `i18n-tasks unused' to show them" + end +end diff --git a/spec/models/domain_block_spec.rb b/spec/models/domain_block_spec.rb index 57c519014a..ad54031108 100644 --- a/spec/models/domain_block_spec.rb +++ b/spec/models/domain_block_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' RSpec.describe DomainBlock, type: :model do - pending "add some examples to (or delete) #{__FILE__}" + end diff --git a/spec/models/tag_spec.rb b/spec/models/tag_spec.rb index 0d0fcb0573..9a7f481e48 100644 --- a/spec/models/tag_spec.rb +++ b/spec/models/tag_spec.rb @@ -1,5 +1,5 @@ require 'rails_helper' RSpec.describe Tag, type: :model do - pending "add some examples to (or delete) #{__FILE__}" + end