diff --git a/app/helpers/users_helper.rb b/app/helpers/users_helper.rb
index dd3ff761154..6f5247d0f4e 100644
--- a/app/helpers/users_helper.rb
+++ b/app/helpers/users_helper.rb
@@ -6,4 +6,12 @@ def twitter_username(user)
def twitter_url(user)
"https://twitter.com/#{user.twitter_username}"
end
+
+ def mastodon_handle(user)
+ "@#{user.mastodon_handle}" if user.mastodon_handle.present?
+ end
+
+ def mastodon_url(user)
+ "@#{user.mastodon_handle}"
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 7f9e006cd28..bef2c9d4d62 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -14,6 +14,7 @@ class User < ApplicationRecord
password
website
twitter_username
+ mastodon_handle
].freeze
before_save :_generate_confirmation_token_no_reset_unconfirmed_email, if: :will_save_change_to_unconfirmed_email?
@@ -51,7 +52,13 @@ class User < ApplicationRecord
message: "can only contain letters, numbers, and underscores"
}, allow_nil: true
+ # https://rubular.com/r/Zjjh8UbLfAFBCm
+ validates :mastodon_handle, format: {
+ with: /\A[a-zA-Z0-9_]+@[a-zA-Z0-9_\.]+\z/
+ }, allow_nil: true
+
validates :twitter_username, length: { within: 0..20 }, allow_nil: true
+ validates :mastodon_handle, length: { within: 0..20 }, allow_nil: true
validates :password,
length: { within: 10..200 },
unpwn: true,
diff --git a/app/views/profiles/edit.html.erb b/app/views/profiles/edit.html.erb
index 2fe3e74716c..89ecbb7be0d 100644
--- a/app/views/profiles/edit.html.erb
+++ b/app/views/profiles/edit.html.erb
@@ -16,6 +16,25 @@
<%= form.text_field :handle, :class => 'form__input' %>
+
+ <%= form.label :mastodon_handle, class: 'form__label form__label__icon-container' do %>
+ <%=
+ image_tag("/images/mastodon_icon.png", alt: 'Mastodon icon', class: 'form__label__icon')
+ %>
+
+
Mastodon handle
+ <% end %>
+
+
+ <%= t('.optional_mastodon_handle') %>
+
+
+
+ @
+ <%= form.text_field(:mastodon_handle, class: 'form__input') %>
+
+
+
<%= form.label :twitter_username, class: 'form__label form__label__icon-container' do %>
<%=
diff --git a/app/views/profiles/show.html.erb b/app/views/profiles/show.html.erb
index 4b059afe4ad..ed2fed92fed 100644
--- a/app/views/profiles/show.html.erb
+++ b/app/views/profiles/show.html.erb
@@ -73,6 +73,18 @@
<% end %>
+ <% if @user.mastodon_handle.present? %>
+ <%=
+ image_tag(
+ "/images/mastodon_icon.png",
+ alt: "Mastodon icon",
+ class: "profile__header__icon"
+ )
+ %>
+
+ <%= mastodon_handle(user) %>
+ <% end %>
+
<% if @user.twitter_username.present? %>
<%=
image_tag(
diff --git a/config/locales/de.yml b/config/locales/de.yml
index cc525913b7a..83f9bf00e92 100644
--- a/config/locales/de.yml
+++ b/config/locales/de.yml
@@ -418,6 +418,7 @@ de:
email_awaiting_confirmation:
enter_password:
hide_email: Verberge E-Mails in öffentlichem Profil
+ optional_mastodon_handle:
optional_twitter_username:
title: Bearbeite Profil
delete:
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 20a77dabcbb..27f95127af4 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -406,6 +406,7 @@ en:
email_awaiting_confirmation: Please confirm your new email address %{unconfirmed_email}
enter_password: Please enter your account's password
hide_email: Hide email in public profile
+ optional_mastodon_handle: Optional Mastodon handle. Will be displayed publicly
optional_twitter_username: Optional Twitter username. Will be displayed publicly
title: Edit profile
delete:
diff --git a/config/locales/es.yml b/config/locales/es.yml
index 401950dc61d..0d8b5c35bc3 100644
--- a/config/locales/es.yml
+++ b/config/locales/es.yml
@@ -441,6 +441,7 @@ es:
%{unconfirmed_email}
enter_password: Por favor introduce tu contraseña
hide_email: Ocultar correo electrónico en perfil público
+ optional_mastodon_handle:
optional_twitter_username: Usuario de Twitter opcional. Será mostrado en tu
perfil público
title: Editar perfil
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index 8c8dfa284e9..0c7a1c18c80 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -444,6 +444,7 @@ fr:
%{unconfirmed_email}
enter_password: Veuillez entrer le mot de passe de votre compte
hide_email: Ne pas afficher l'email dans le profil public
+ optional_mastodon_handle:
optional_twitter_username: Nom d'utilisateur Twitter optionnel. Sera affiché
publiquement
title: Modification de profil
diff --git a/config/locales/ja.yml b/config/locales/ja.yml
index 4e6db7db468..c1a0d413574 100644
--- a/config/locales/ja.yml
+++ b/config/locales/ja.yml
@@ -403,6 +403,7 @@ ja:
email_awaiting_confirmation: あなたの新しいメールアドレス%{unconfirmed_email}を確認してください。
enter_password: パスワードを入力してください。
hide_email: メールアドレスを公開しない
+ optional_mastodon_handle: Mastodonのユーザー名(任意,公開)
optional_twitter_username: Twitterのユーザー名(任意,公開)
title: プロフィールを編集する
delete:
diff --git a/config/locales/nl.yml b/config/locales/nl.yml
index 619eeeff352..c365f8bf013 100644
--- a/config/locales/nl.yml
+++ b/config/locales/nl.yml
@@ -422,6 +422,7 @@ nl:
email_awaiting_confirmation:
enter_password:
hide_email:
+ optional_mastodon_handle:
optional_twitter_username:
title: Wijzig profiel
delete:
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index a1340ffd706..15f522fbe8c 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -433,6 +433,7 @@ pt-BR:
email_awaiting_confirmation:
enter_password:
hide_email: Não mostrar meu email
+ optional_mastodon_handle:
optional_twitter_username:
title: Editar Perfil
delete:
diff --git a/config/locales/zh-CN.yml b/config/locales/zh-CN.yml
index c8603fd4699..5da99b0d31c 100644
--- a/config/locales/zh-CN.yml
+++ b/config/locales/zh-CN.yml
@@ -404,6 +404,7 @@ zh-CN:
email_awaiting_confirmation: 请验证你的新邮箱地址 %{unconfirmed_email}
enter_password: 输入密码
hide_email: 在公开的个人资料里面隐藏我的 Email
+ optional_mastodon_handle:
optional_twitter_username: Twitter 账号(可选)
title: 修改个人资料
delete:
diff --git a/config/locales/zh-TW.yml b/config/locales/zh-TW.yml
index 43b261a2d30..28cc266341a 100644
--- a/config/locales/zh-TW.yml
+++ b/config/locales/zh-TW.yml
@@ -405,6 +405,7 @@ zh-TW:
email_awaiting_confirmation: 請驗證你的新 Email %{unconfirmed_email}
enter_password: 輸入密碼
hide_email: 在公開的個人頁面中隱藏 email
+ optional_mastodon_handle:
optional_twitter_username: Twitter 帳號(可選)
title: 編輯個人檔案
delete:
diff --git a/db/migrate/20230103103445_add_mastodon_handle_to_users.rb b/db/migrate/20230103103445_add_mastodon_handle_to_users.rb
new file mode 100644
index 00000000000..747bc0973c2
--- /dev/null
+++ b/db/migrate/20230103103445_add_mastodon_handle_to_users.rb
@@ -0,0 +1,5 @@
+class AddMastodonHandleToUsers < ActiveRecord::Migration[7.0]
+ def change
+ add_column :users, :mastodon_handle, :string
+ end
+end
diff --git a/public/images/mastodon_icon.png b/public/images/mastodon_icon.png
new file mode 100644
index 00000000000..f686138c933
Binary files /dev/null and b/public/images/mastodon_icon.png differ
diff --git a/test/integration/profile_test.rb b/test/integration/profile_test.rb
index 673e55e45f1..00074a92b25 100644
--- a/test/integration/profile_test.rb
+++ b/test/integration/profile_test.rb
@@ -93,6 +93,21 @@ def sign_in
refute page.has_content?("Email Me")
end
+ test "adding Mastodon username" do
+ sign_in
+ visit profile_path("nick1")
+
+ click_link "Edit Profile"
+ fill_in "Mastodon handle", with: "nick1@ruby.social"
+ fill_in "Password", with: PasswordHelpers::SECURE_TEST_PASSWORD
+ click_button "Update"
+
+ click_link "Sign out"
+ visit profile_path("nick1")
+
+ assert page.has_content?("@nick1@ruby.social")
+ end
+
test "adding Twitter username" do
sign_in
visit profile_path("nick1")
diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb
index 9b3041e7fcf..f562745f8d2 100644
--- a/test/unit/user_test.rb
+++ b/test/unit/user_test.rb
@@ -128,6 +128,16 @@ class UserTest < ActiveSupport::TestCase
end
end
+ context "mastodon_handle" do
+ should validate_length_of(:mastodon_handle)
+ should allow_value("user123_32@mastodon").for(:mastodon_handle)
+ should_not allow_value("@user").for(:mastodon_handle)
+ should_not allow_value("user 1").for(:mastodon_handle)
+ should_not allow_value("user-1").for(:mastodon_handle)
+ should allow_value("01234567890123456789@01234567890123456789").for(:mastodon_handle)
+ should_not allow_value("012345678901234567890").for(:mastodon_handle)
+ end
+
context "twitter_username" do
should validate_length_of(:twitter_username)
should allow_value("user123_32").for(:twitter_username)