Merge pull request #438 from mastodon/feature-familiar-followers

Display familiar followers for profile card
This commit is contained in:
CMK 2022-05-19 10:52:04 +08:00 committed by GitHub
commit b368ca67e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
177 changed files with 4397 additions and 506 deletions

View File

@ -17,6 +17,6 @@
<key>CFBundleShortVersionString</key>
<string>1.4.2</string>
<key>CFBundleVersion</key>
<string>127</string>
<string>130</string>
</dict>
</plist>

View File

@ -74,6 +74,49 @@
<string>%ld حَرف</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>zero</key>
<string></string>
<key>one</key>
<string></string>
<key>two</key>
<string></string>
<key>few</key>
<string></string>
<key>many</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>Followed by %1$@, and %ld mutuals</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>two</key>
<string>Followed by %1$@, and %ld mutuals</string>
<key>few</key>
<string>Followed by %1$@, and %ld mutuals</string>
<key>many</key>
<string>Followed by %1$@, and %ld mutuals</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "لا يُمكِن عَرض المُتابِعين مِنَ الخوادم الأُخرى."
},
"following": {
"title": "following",
"footer": "لا يُمكِن عَرض المُتابَعات مِنَ الخوادم الأُخرى."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "البَحث",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld caràcters</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Seguit per %1$@, i un altre mutu</string>
<key>other</key>
<string>Seguit per %1$@, i %ld mutus</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Els seguidors d'altres servidors no son mostrats."
},
"following": {
"title": "following",
"footer": "Els seguits d'altres servidors no son mostrats."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Cerca",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld نووسە</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "شوێنکەوتووەکانی لە ڕاژەکارەکانی ترەوە نیشان نادرێت."
},
"following": {
"title": "following",
"footer": "شوێنکەوتنەکانی بۆ هەژماری ڕاژەکارەکانی تر نیشان نادرێت."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "بگەڕێ",
"search_bar": {

View File

@ -74,6 +74,49 @@
<string>%ld characters</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>zero</key>
<string></string>
<key>one</key>
<string></string>
<key>two</key>
<string></string>
<key>few</key>
<string></string>
<key>many</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>Followed by %1$@, and %ld mutuals</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>two</key>
<string>Followed by %1$@, and %ld mutuals</string>
<key>few</key>
<string>Followed by %1$@, and %ld mutuals</string>
<key>many</key>
<string>Followed by %1$@, and %ld mutuals</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Search",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld characters</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Search",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld Zeichen</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Follower von anderen Servern werden nicht angezeigt."
},
"following": {
"title": "following",
"footer": "Wem das Konto folgt wird von anderen Servern werden nicht angezeigt."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Suche",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld characters</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Search",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld characters</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Search",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld caracteres</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@: "%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Seguido por %1$@ y otra cuenta mutua</string>
<key>other</key>
<string>Seguido por %1$@ y otras %ld cuentas mutuas</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
@ -77,9 +104,9 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 media</string>
<string>1 medio</string>
<key>other</key>
<string>%ld media</string>
<string>%ld medios</string>
</dict>
</dict>
<key>plural.count.post</key>

View File

@ -180,7 +180,7 @@
"unmute": "Dejar de silenciar",
"unmute_user": "Dejar de silenciar a %s",
"muted": "Silenciado",
"edit_info": "Editar información"
"edit_info": "Editar"
},
"timeline": {
"filtered": "Filtrado",
@ -194,11 +194,11 @@
},
"header": {
"no_status_found": "Mensaje no encontrado",
"blocking_warning": "No podés ver el perfil de este usuario\n hasta que lo desbloquees.\nTu perfil le aparece así a este usuario.",
"user_blocking_warning": "No podés ver el perfil de %s\n hasta que lo desbloquees.\nTu perfil le aparece así a este usuario.",
"blocked_warning": "No podés ver el perfil de este usuario\n hasta que dicho usuario te desbloquee.",
"user_blocked_warning": "No podés ver el perfil de %s\n hasta que dicho usuario te desbloquee.",
"suspended_warning": "Este usuario está suspendido.",
"blocking_warning": "No podés ver el perfil de este usuario\nhasta que lo desbloquees.\nTu perfil le aparece así a este usuario.",
"user_blocking_warning": "No podés ver el perfil de %s\nhasta que lo desbloquees.\nTu perfil le aparece así a este usuario.",
"blocked_warning": "No podés ver el perfil de este usuario\nhasta que dicho usuario te desbloquee.",
"user_blocked_warning": "No podés ver el perfil de %s\nhasta que dicho usuario te desbloquee.",
"suspended_warning": "Esta cuenta está suspendida.",
"user_suspended_warning": "La cuenta de %s está suspendida."
}
}
@ -211,16 +211,16 @@
"log_in": "Iniciar sesión"
},
"server_picker": {
"title": "Elegí un servidor,\nel que quieras.",
"subtitle": "Elegí una comunidad basada en tus intereses, región o una de propósitos generales.",
"subtitle_extend": "Elegí una comunidad basada en tus intereses, región o una de propósitos generales. Cada comunidad es operada por una organización o individuo totalmente independiente.",
"title": "Mastodon está compuesto de cuentas en diferentes servidores.",
"subtitle": "Elegí un servidor basado en tus intereses, región, o de propósitos generales.",
"subtitle_extend": "Elegí un servidor basado en tus intereses, región, o de propósitos generales. Cada servidor es operado por una organización o individuo totalmente independientes.",
"button": {
"category": {
"all": "Todas",
"all_accessiblity_description": "Categoría: Todas",
"academia": "académico",
"activism": "activismo",
"food": "comida",
"food": "alimentación",
"furry": "furry",
"games": "juegos",
"general": "general",
@ -241,7 +241,7 @@
},
"input": {
"placeholder": "Encontrá un servidor o unite al tuyo…",
"search_servers_or_enter_url": "Search communities or enter URL"
"search_servers_or_enter_url": "Buscar comunidades o introducir dirección web"
},
"empty_state": {
"finding_servers": "Buscando servidores disponibles…",
@ -251,7 +251,7 @@
},
"register": {
"title": "Contanos sobre vos.",
"lets_get_you_set_up_on_domain": "Lets get you set up on %s",
"lets_get_you_set_up_on_domain": "Vamos a prepararte en %s",
"input": {
"avatar": {
"delete": "Eliminar"
@ -322,7 +322,7 @@
"confirm_email": {
"title": "Una última cosa.",
"subtitle": "Acabamos de enviar un correo electrónico a %s,\npulsá en el enlace para confirmar tu cuenta.",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Tocá el enlace que te enviamos por correo electrónico para verificar tu cuenta",
"button": {
"open_email_app": "Abrir aplicación de correo electrónico",
"resend": "Reenviar"
@ -347,8 +347,8 @@
"published": "¡Enviado!",
"Publishing": "Enviando mensaje…",
"accessibility": {
"logo_label": "Logo Button",
"logo_hint": "Tap to scroll to top and tap again to previous location"
"logo_label": "Botón de logo",
"logo_hint": "Tocá para desplazarte hacia arriba y tocá de nuevo para ir a la ubicación anterior"
}
}
},
@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "No se muestran los seguidores de otros servidores."
},
"following": {
"title": "following",
"footer": "No se muestran las cuentas de otros servidores que seguís."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Buscar",
"search_bar": {
@ -605,46 +617,46 @@
"text_placeholder": "Escribí o pegá comentarios adicionales",
"reported": "DENUNCIADA",
"step_one": {
"step_1_of_4": "Step 1 of 4",
"whats_wrong_with_this_post": "What's wrong with this post?",
"whats_wrong_with_this_account": "What's wrong with this account?",
"whats_wrong_with_this_username": "What's wrong with %s?",
"select_the_best_match": "Select the best match",
"i_dont_like_it": "I dont like it",
"it_is_not_something_you_want_to_see": "It is not something you want to see",
"its_spam": "Its spam",
"malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies",
"it_violates_server_rules": "It violates server rules",
"you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules",
"its_something_else": "Its something else",
"the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories"
"step_1_of_4": "Paso 1 de 4",
"whats_wrong_with_this_post": "¿Cuál es el problema con este mensaje?",
"whats_wrong_with_this_account": "¿Cuál es el problema con esta cuenta?",
"whats_wrong_with_this_username": "¿Cuál es el problema con %s?",
"select_the_best_match": "Seleccioná la mejor coincidencia",
"i_dont_like_it": "No te gusta",
"it_is_not_something_you_want_to_see": "Es algo que no querés ver",
"its_spam": "Es spam",
"malicious_links_fake_engagement_or_repetetive_replies": "Enlaces maliciosos, interacciones falsas o respuestas repetitivas",
"it_violates_server_rules": "Viola las reglas del servidor",
"you_are_aware_that_it_breaks_specific_rules": "Sos consciente de que infringe normas específicas",
"its_something_else": "Es otra cosa",
"the_issue_does_not_fit_into_other_categories": "El problema no aplica en otras categorías"
},
"step_two": {
"step_2_of_4": "Step 2 of 4",
"which_rules_are_being_violated": "Which rules are being violated?",
"select_all_that_apply": "Select all that apply",
"i_just_dont_like_it": "I just dont like it"
"step_2_of_4": "Paso 2 de 4",
"which_rules_are_being_violated": "¿Qué reglas se están violando?",
"select_all_that_apply": "Seleccioná todo lo que corresponda",
"i_just_dont_like_it": "Simplemente no te gusta"
},
"step_three": {
"step_3_of_4": "Step 3 of 4",
"are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?",
"select_all_that_apply": "Select all that apply"
"step_3_of_4": "Paso 3 de 4",
"are_there_any_posts_that_back_up_this_report": "¿Hay algún mensaje que respalde esta denuncia?",
"select_all_that_apply": "Seleccioná todo lo que corresponda"
},
"step_four": {
"step_4_of_4": "Step 4 of 4",
"is_there_anything_else_we_should_know": "Is there anything else we should know?"
"step_4_of_4": "Paso 4 de 4",
"is_there_anything_else_we_should_know": "¿Hay algo más que deberíamos saber?"
},
"step_final": {
"dont_want_to_see_this": "Dont want to see this?",
"when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you dont like on Mastodon, you can remove the person from your experience.",
"unfollow": "Unfollow",
"unfollowed": "Unfollowed",
"unfollow_user": "Unfollow %s",
"mute_user": "Mute %s",
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You wont see their posts or reblogs in your home feed. They wont know theyve been muted.",
"block_user": "Block %s",
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if theyve been blocked.",
"while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s"
"dont_want_to_see_this": "¿No querés ver esto?",
"when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Cuando veas algo que no te gusta en Mastodon, podés quitar a esa cuenta de tu experiencia.",
"unfollow": "Dejar de seguir",
"unfollowed": "Dejaste de seguir a esta cuenta",
"unfollow_user": "Dejar de seguir a %s",
"mute_user": "Silenciar a %s",
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "No verás sus publicaciones ni sus adhesiones en tu línea temporal. El usuario de esta cuenta no sabrá que fue silenciado.",
"block_user": "Bloquear a %s",
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "El usuario de esta cuenta ya no podrá seguirte o leer tus mensajes, pero podrá fijarse si fue bloqueado.",
"while_we_review_this_you_can_take_action_against_user": "Mientras revisamos esto, podés tomar medidas contra %s"
}
},
"preview": {

View File

@ -50,6 +50,33 @@
<string>%ld caracteres</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "No se muestran los seguidores de otros servidores."
},
"following": {
"title": "following",
"footer": "No se muestran los seguidos de otros servidores."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Buscar",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld karaktere</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Beste zerbitzarietako jarraitzaileak ez dira bistaratzen."
},
"following": {
"title": "following",
"footer": "Beste zerbitzarietan jarraitutakoak ez dira bistaratzen."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Bilatu",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld merkkiä</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Seuraajia muilta palvelimilta ei näytetä."
},
"following": {
"title": "following",
"footer": "Seurauksia muilta palvelimilta ei näytetä."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Haku",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld caractères</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Les abonné·e·s issus des autres serveurs ne sont pas affiché·e·s."
},
"following": {
"title": "following",
"footer": "Les abonnés issus des autres serveurs ne sont pas affichés."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Rechercher",
"search_bar": {

View File

@ -62,6 +62,41 @@
<string>%ld caractar</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>two</key>
<string></string>
<key>few</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>two</key>
<string>Followed by %1$@, and %ld mutuals</string>
<key>few</key>
<string>Followed by %1$@, and %ld mutuals</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Cha dèid luchd-leantainn o fhrithealaichean eile a shealltainn."
},
"following": {
"title": "following",
"footer": "Cha dèid cò air a leanas tu air frithealaichean eile a shealltainn."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Lorg",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld caracteres</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Seguida por %1$@, e outro común</string>
<key>other</key>
<string>Seguida por %1$@, e %ld comúns</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -207,7 +207,7 @@
"scene": {
"welcome": {
"slogan": "Comunicación social\nde volta ás túas mans.",
"get_started": "Comezar",
"get_started": "Crear conta",
"log_in": "Acceder"
},
"server_picker": {
@ -251,7 +251,7 @@
},
"register": {
"title": "Imos crear a túa conta en %s",
"lets_get_you_set_up_on_domain": "Lets get you set up on %s",
"lets_get_you_set_up_on_domain": "Imos crear a túa conta en %s",
"input": {
"avatar": {
"delete": "Eliminar"
@ -322,7 +322,7 @@
"confirm_email": {
"title": "O último detalle.",
"subtitle": "Preme na ligazón que che enviamos ao email para verificar a conta.",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Preme na ligazón que che enviamos ao email para verificar a conta",
"button": {
"open_email_app": "Abrir app de email",
"resend": "Reenviar"
@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Non se mostran seguidoras desde outros servidores."
},
"following": {
"title": "following",
"footer": "Non se mostran os seguimentos desde outros servidores."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Procurar",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld characters</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Search",
"search_bar": {

View File

@ -44,6 +44,29 @@
<string>%ld karakter</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Cari",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld caratteri</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Seguito da %1$@ e un altro amico in comune</string>
<key>other</key>
<string>Seguito da %1$@ e %ld amici in comune</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "I seguaci da altri server non vengono visualizzati."
},
"following": {
"title": "following",
"footer": "I follow da altri server non vengono visualizzati."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Cerca",
"search_bar": {

View File

@ -44,6 +44,29 @@
<string>%ld 文字</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "他のサーバーからのフォロワーは表示されません。"
},
"following": {
"title": "following",
"footer": "他のサーバーにいるフォローは表示されません。"
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "検索",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld yisekkilen</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Ineḍfaren seg yiqeddacen-nniḍen ur d-ttwaskanen ara."
},
"following": {
"title": "following",
"footer": "Ineḍfaren seg yiqeddacen-nniḍen ur d-ttwaskanen ara."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Nadi",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld tîp</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Ji aliyê %1$@, û hevaleke hevpar tê şopandin</string>
<key>other</key>
<string>Ji aliyê %1$@, û %ld hevalên hevpar tê şopandin</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -241,7 +241,7 @@
},
"input": {
"placeholder": "Li rajekaran bigere",
"search_servers_or_enter_url": "Search communities or enter URL"
"search_servers_or_enter_url": "Li civakan bigere an jî girêdanê binivîse"
},
"empty_state": {
"finding_servers": "Peydakirina rajekarên berdest...",
@ -251,7 +251,7 @@
},
"register": {
"title": "Ji me re hinekî qala xwe bike %s",
"lets_get_you_set_up_on_domain": "Lets get you set up on %s",
"lets_get_you_set_up_on_domain": "Ka em te bi rê bixin li ser %s",
"input": {
"avatar": {
"delete": "Jê bibe"
@ -322,7 +322,7 @@
"confirm_email": {
"title": "Tiştekî dawî.",
"subtitle": "Me tenê e-nameyek ji %s re şand,\ngirêdanê bitikne da ku ajimêra xwe bidî piştrastkirin.",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Girêdana e-nameyê ku me ji te re şand bitikîne da ku ajimêra xwe bidî piştrastkirin",
"button": {
"open_email_app": "Sepana e-nameyê veke",
"resend": "Ji nû ve bişîne"
@ -347,8 +347,8 @@
"published": "Hate weşandin!",
"Publishing": "Şandî tê weşandin...",
"accessibility": {
"logo_label": "Logo Button",
"logo_hint": "Tap to scroll to top and tap again to previous location"
"logo_label": "Bişkoka Logo",
"logo_hint": "Ji bo şemitandina jor û dîsa li cihê berê vegerî bitikîne"
}
}
},
@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Şopîner ji rajekerên din nayê dîtin."
},
"following": {
"title": "following",
"footer": "Şopandin ji rajekerên din nayê dîtin."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Bigere",
"search_bar": {
@ -606,45 +618,45 @@
"reported": "HATE RAGIHANDIN",
"step_one": {
"step_1_of_4": "Gav 1 ji 4",
"whats_wrong_with_this_post": "What's wrong with this post?",
"whats_wrong_with_this_account": "What's wrong with this account?",
"whats_wrong_with_this_username": "What's wrong with %s?",
"select_the_best_match": "Select the best match",
"whats_wrong_with_this_post": "Çi çewt e di vê şandiyê de?",
"whats_wrong_with_this_account": "Çi çewt e di vê ajimêrê de?",
"whats_wrong_with_this_username": "Çi çewt e bi %s re?",
"select_the_best_match": "Baştirîn lihevhatina hilbijêre",
"i_dont_like_it": "Ez jê hez nakim",
"it_is_not_something_you_want_to_see": "It is not something you want to see",
"it_is_not_something_you_want_to_see": "Ew ne tiştek e ku tu dixwazî bibînî",
"its_spam": "Ew spam e",
"malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies",
"it_violates_server_rules": "It violates server rules",
"you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules",
"its_something_else": "Its something else",
"the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories"
"malicious_links_fake_engagement_or_repetetive_replies": "Girêdanên xerab, tevlêbûna sexte, an jî bersivên dubarekirî",
"it_violates_server_rules": "Ew rêzikên rajekar binpê dike",
"you_are_aware_that_it_breaks_specific_rules": "Tu dizanî ku ew rêzikên taybetiyê binpê dike",
"its_something_else": "Tiştekî din e",
"the_issue_does_not_fit_into_other_categories": "Pirsgirêk di kategoriyên din de cih nagire"
},
"step_two": {
"step_2_of_4": "Gav 2 ji 4",
"which_rules_are_being_violated": "Which rules are being violated?",
"select_all_that_apply": "Select all that apply",
"which_rules_are_being_violated": "Kîjan rêzik têne binpêkirin?",
"select_all_that_apply": "Hemûyên ku têne sepandin hilbijêre",
"i_just_dont_like_it": "Tenê ez jê hez nakim"
},
"step_three": {
"step_3_of_4": "Gav 3 ji 4",
"are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?",
"select_all_that_apply": "Select all that apply"
"are_there_any_posts_that_back_up_this_report": "Tu şandiyên ku vê ragihandinê piştgirî dikin hene?",
"select_all_that_apply": "Hemûyên ku têne sepandin hilbijêre"
},
"step_four": {
"step_4_of_4": "Gav 4 ji 4",
"is_there_anything_else_we_should_know": "Is there anything else we should know?"
"is_there_anything_else_we_should_know": "Tiştek din heye ku tu difikirî ku divê em zanibin?"
},
"step_final": {
"dont_want_to_see_this": "Tu naxwazî vê bibînî?",
"when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you dont like on Mastodon, you can remove the person from your experience.",
"when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Dema li ser Mastodonê tiştekî ku tu jê hez nakî bibînî, tu dikarî ew kes ji navrûya xwe derxî.",
"unfollow": "Neşopîne",
"unfollowed": "Ji şopê hate derketin",
"unfollow_user": "%s neşopîne",
"mute_user": "%s bêdeng bike",
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You wont see their posts or reblogs in your home feed. They wont know theyve been muted.",
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Tu yê şandî an jî bilindkirinên wan di rojeva xwe de nebînî. Ew ê nizanibin ku hatine bêdengkirin.",
"block_user": "%s asteng bike",
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if theyve been blocked.",
"while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s"
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Êdî nikarin şandiyên te bişopînin an jî bibînin, lê ew dikarin bibînin ka hatine astengkirin an na.",
"while_we_review_this_you_can_take_action_against_user": "Dema ku em vê yekê dinirxînin, tu dikarî li dijî %s tedbîran bigirî"
}
},
"preview": {

View File

@ -44,6 +44,29 @@
<string>%ld characters</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -67,7 +67,7 @@
"done": "완료",
"confirm": "확인",
"continue": "계속",
"compose": "Compose",
"compose": "작성",
"cancel": "취소",
"discard": "버리기",
"try_again": "다시 시도",
@ -82,7 +82,7 @@
"share_user": "%s를 공유",
"share_post": "게시물 공유",
"open_in_safari": "사파리에서 열기",
"open_in_browser": "Open in Browser",
"open_in_browser": "브라우저에서 열기",
"find_people": "팔로우 할 사람들 찾기",
"manually_search": "대신 수동으로 검색하기",
"skip": "건너뛰기",
@ -131,7 +131,7 @@
"content_warning": "열람 주의",
"sensitive_content": "Sensitive Content",
"media_content_warning": "Tap anywhere to reveal",
"tap_to_reveal": "Tap to reveal",
"tap_to_reveal": "눌러서 확인",
"poll": {
"vote": "투표",
"closed": "마감"
@ -143,8 +143,8 @@
"favorite": "즐겨찾기",
"unfavorite": "즐겨찾기 해제",
"menu": "메뉴",
"hide": "Hide",
"show_image": "Show image",
"hide": "숨기기",
"show_image": "이미지 표시",
"show_gif": "Show GIF",
"show_video_player": "Show video player",
"tap_then_hold_to_show_menu": "Tap then hold to show menu"
@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "검색",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld tekens</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Volgers van andere servers worden niet weergegeven."
},
"following": {
"title": "following",
"footer": "Volgers van andere servers worden niet weergegeven."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Zoeken",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld caracteres</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Search",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld characters</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Search",
"search_bar": {

View File

@ -56,6 +56,37 @@
<string>%ld characters</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>few</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>few</key>
<string>Followed by %1$@, and %ld mutuals</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Search",
"search_bar": {

View File

@ -62,6 +62,41 @@
<string>%ld символа осталось</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>few</key>
<string></string>
<key>many</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>%1$@ и ещё %ld человек подписаны</string>
<key>few</key>
<string>%1$@ и ещё %ld человека подписаны</string>
<key>many</key>
<string>%1$@ и ещё %ld человек подписаны</string>
<key>other</key>
<string>%1$@ и ещё %ld человека подписаны</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Поиск",
"search_bar": {

View File

@ -50,6 +50,33 @@
<string>%ld tecken</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
@ -77,7 +104,7 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 media</string>
<string>%ld media</string>
<key>other</key>
<string>%ld media</string>
</dict>

View File

@ -251,7 +251,7 @@
},
"register": {
"title": "Låt oss få igång dig på %s",
"lets_get_you_set_up_on_domain": "Lets get you set up on %s",
"lets_get_you_set_up_on_domain": "Låt oss få igång dig på %s",
"input": {
"avatar": {
"delete": "Radera"
@ -322,7 +322,7 @@
"confirm_email": {
"title": "En sista sak.",
"subtitle": "Tryck på länken vi e-postade till dig för att verifiera ditt konto.",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Tryck på länken vi e-postade till dig för att verifiera ditt konto",
"button": {
"open_email_app": "Öppna e-postappen",
"resend": "Skicka igen"
@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Följare från andra servrar visas inte."
},
"following": {
"title": "following",
"footer": "Följda på andra servrar visas inte."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Sök",
"search_bar": {
@ -644,7 +656,7 @@
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Du kommer inte att se deras inlägg eller ompostningar i ditt hemflöde. De kommer inte att veta att de har blivit tystade.",
"block_user": "Blockera %s",
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "De kommer inte längre att kunna följa eller se dina inlägg, men de kan se om de har blockerats.",
"while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s"
"while_we_review_this_you_can_take_action_against_user": "Medan vi granskar detta kan du vidta åtgärder mot %s"
}
},
"preview": {

View File

@ -44,6 +44,29 @@
<string>%ld ตัวอักษร</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
@ -69,7 +92,7 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string>%ld media</string>
<string>%ld สื่อ</string>
</dict>
</dict>
<key>plural.count.post</key>

View File

@ -241,7 +241,7 @@
},
"input": {
"placeholder": "ค้นหาเซิร์ฟเวอร์",
"search_servers_or_enter_url": "Search communities or enter URL"
"search_servers_or_enter_url": "ค้นหาชุมชนหรือป้อน URL"
},
"empty_state": {
"finding_servers": "กำลังค้นหาเซิร์ฟเวอร์ที่พร้อมใช้งาน...",
@ -251,7 +251,7 @@
},
"register": {
"title": "มาตั้งค่าของคุณใน %s กันเลย",
"lets_get_you_set_up_on_domain": "Lets get you set up on %s",
"lets_get_you_set_up_on_domain": "มาตั้งค่าของคุณใน %s กันเลย",
"input": {
"avatar": {
"delete": "ลบ"
@ -322,7 +322,7 @@
"confirm_email": {
"title": "หนึ่งสิ่งสุดท้าย",
"subtitle": "แตะลิงก์ที่เราส่งอีเมลถึงคุณเพื่อยืนยันบัญชีของคุณ",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "แตะลิงก์ที่เราส่งอีเมลถึงคุณเพื่อยืนยันบัญชีของคุณ",
"button": {
"open_email_app": "เปิดแอปอีเมล",
"resend": "ส่งใหม่"
@ -347,8 +347,8 @@
"published": "เผยแพร่แล้ว!",
"Publishing": "กำลังเผยแพร่โพสต์...",
"accessibility": {
"logo_label": "Logo Button",
"logo_hint": "Tap to scroll to top and tap again to previous location"
"logo_label": "ปุ่มโลโก้",
"logo_hint": "แตะเพื่อเลื่อนไปยังด้านบนสุดและแตะอีกครั้งไปยังตำแหน่งที่ตั้งก่อนหน้า"
}
}
},
@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "ไม่ได้แสดงผู้ติดตามจากเซิร์ฟเวอร์อื่น ๆ"
},
"following": {
"title": "following",
"footer": "ไม่ได้แสดงการติดตามจากเซิร์ฟเวอร์อื่น ๆ"
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "ค้นหา",
"search_bar": {
@ -605,46 +617,46 @@
"text_placeholder": "พิมพ์หรือวางความคิดเห็นเพิ่มเติม",
"reported": "รายงานแล้ว",
"step_one": {
"step_1_of_4": "Step 1 of 4",
"whats_wrong_with_this_post": "What's wrong with this post?",
"whats_wrong_with_this_account": "What's wrong with this account?",
"whats_wrong_with_this_username": "What's wrong with %s?",
"select_the_best_match": "Select the best match",
"i_dont_like_it": "I dont like it",
"it_is_not_something_you_want_to_see": "It is not something you want to see",
"its_spam": "Its spam",
"malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies",
"it_violates_server_rules": "It violates server rules",
"you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules",
"its_something_else": "Its something else",
"the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories"
"step_1_of_4": "ขั้นตอนที่ 1 จาก 4",
"whats_wrong_with_this_post": "โพสต์นี้มีอะไรผิดปกติ?",
"whats_wrong_with_this_account": "บัญชีนี้มีอะไรผิดปกติ?",
"whats_wrong_with_this_username": "%s มีอะไรผิดปกติ?",
"select_the_best_match": "เลือกที่ตรงกันที่สุด",
"i_dont_like_it": "ฉันไม่ชอบโพสต์",
"it_is_not_something_you_want_to_see": "โพสต์ไม่ใช่บางอย่างที่คุณต้องการเห็น",
"its_spam": "โพสต์เป็นสแปม",
"malicious_links_fake_engagement_or_repetetive_replies": "ลิงก์ที่เป็นอันตราย, การมีส่วนร่วมปลอม หรือการตอบกลับซ้ำ ๆ",
"it_violates_server_rules": "โพสต์ละเมิดกฎของเซิร์ฟเวอร์",
"you_are_aware_that_it_breaks_specific_rules": "คุณทราบว่าโพสต์แหกกฎเฉพาะ",
"its_something_else": "โพสต์เป็นอย่างอื่น",
"the_issue_does_not_fit_into_other_categories": "ปัญหาไม่เข้าหมวดหมู่อื่น ๆ"
},
"step_two": {
"step_2_of_4": "Step 2 of 4",
"which_rules_are_being_violated": "Which rules are being violated?",
"select_all_that_apply": "Select all that apply",
"i_just_dont_like_it": "I just dont like it"
"step_2_of_4": "ขั้นตอนที่ 2 จาก 4",
"which_rules_are_being_violated": "กำลังละเมิดกฎใด?",
"select_all_that_apply": "เลือกทั้งหมดที่นำไปใช้",
"i_just_dont_like_it": "ฉันแค่ไม่ชอบโพสต์"
},
"step_three": {
"step_3_of_4": "Step 3 of 4",
"are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?",
"select_all_that_apply": "Select all that apply"
"step_3_of_4": "ขั้นตอนที่ 3 จาก 4",
"are_there_any_posts_that_back_up_this_report": "มีโพสต์ใด ๆ ที่สนับสนุนรายงานนี้หรือไม่?",
"select_all_that_apply": "เลือกทั้งหมดที่นำไปใช้"
},
"step_four": {
"step_4_of_4": "Step 4 of 4",
"is_there_anything_else_we_should_know": "Is there anything else we should know?"
"step_4_of_4": "ขั้นตอนที่ 4 จาก 4",
"is_there_anything_else_we_should_know": "มีสิ่งอื่นใดที่เราควรทราบหรือไม่?"
},
"step_final": {
"dont_want_to_see_this": "Dont want to see this?",
"when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you dont like on Mastodon, you can remove the person from your experience.",
"unfollow": "Unfollow",
"unfollowed": "Unfollowed",
"unfollow_user": "Unfollow %s",
"mute_user": "Mute %s",
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You wont see their posts or reblogs in your home feed. They wont know theyve been muted.",
"block_user": "Block %s",
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if theyve been blocked.",
"while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s"
"dont_want_to_see_this": "ไม่ต้องการเห็นสิ่งนี้?",
"when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "เมื่อคุณเห็นบางอย่างที่คุณไม่ชอบใน Mastodon คุณสามารถเอาบุคคลออกจากประสบการณ์ของคุณ",
"unfollow": "เลิกติดตาม",
"unfollowed": "เลิกติดตามแล้ว",
"unfollow_user": "เลิกติดตาม %s",
"mute_user": "ซ่อน %s",
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "คุณจะไม่เห็นโพสต์หรือการดันของเขาในฟีดหน้าแรกของคุณ เขาจะไม่ทราบว่ามีการซ่อนเขา",
"block_user": "ปิดกั้น %s",
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "เขาจะไม่สามารถติดตามหรือเห็นโพสต์ของคุณได้อีกต่อไป แต่เขาสามารถเห็นว่ามีการปิดกั้นเขาหรือไม่",
"while_we_review_this_you_can_take_action_against_user": "ขณะที่เราตรวจทานสิ่งนี้ คุณสามารถดำเนินการกับ %s"
}
},
"preview": {

View File

@ -50,6 +50,33 @@
<string>%ld karakter</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>one</key>
<string></string>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Diğer sunucudaki takipçiler gösterilemiyor."
},
"following": {
"title": "following",
"footer": "Diğer sunucudaki takip edilenler gösterilemiyor."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Arama",
"search_bar": {

View File

@ -44,6 +44,29 @@
<string>%ld ký tự</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string>Theo dõi bởi %1$@, và %ld người quen</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -241,7 +241,7 @@
},
"input": {
"placeholder": "Tìm máy chủ",
"search_servers_or_enter_url": "Search communities or enter URL"
"search_servers_or_enter_url": "Tìm một máy chủ hoặc nhập URL"
},
"empty_state": {
"finding_servers": "Đang tìm máy chủ hoạt động...",
@ -251,7 +251,7 @@
},
"register": {
"title": "Hãy để tôi đăng ký trên %s",
"lets_get_you_set_up_on_domain": "Lets get you set up on %s",
"lets_get_you_set_up_on_domain": "Hãy để tôi đăng ký trên %s",
"input": {
"avatar": {
"delete": "Xóa"
@ -322,7 +322,7 @@
"confirm_email": {
"title": "Còn điều này nữa.",
"subtitle": "Nhấn vào liên kết chúng tôi gửi qua email để xác thực tài khoản.",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Nhấn vào liên kết chúng tôi gửi qua email để xác thực tài khoản",
"button": {
"open_email_app": "Mở ứng dụng email",
"resend": "Gửi lại"
@ -347,8 +347,8 @@
"published": "Đã đăng!",
"Publishing": "Đang đăng tút...",
"accessibility": {
"logo_label": "Logo Button",
"logo_hint": "Tap to scroll to top and tap again to previous location"
"logo_label": "Nút biểu tượng",
"logo_hint": "Nhấn để cuộn lên trên và nhấn lại lần nữa để trở về vị trí cũ"
}
}
},
@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "Không hiển thị người theo dõi từ máy chủ khác."
},
"following": {
"title": "following",
"footer": "Không hiển thị người bạn theo dõi từ máy chủ khác."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Tìm kiếm",
"search_bar": {
@ -605,46 +617,46 @@
"text_placeholder": "Nhập hoặc bổ sung chú thích",
"reported": "ĐÃ BÁO CÁO",
"step_one": {
"step_1_of_4": "Step 1 of 4",
"whats_wrong_with_this_post": "What's wrong with this post?",
"whats_wrong_with_this_account": "What's wrong with this account?",
"whats_wrong_with_this_username": "What's wrong with %s?",
"select_the_best_match": "Select the best match",
"i_dont_like_it": "I dont like it",
"it_is_not_something_you_want_to_see": "It is not something you want to see",
"its_spam": "Its spam",
"malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies",
"it_violates_server_rules": "It violates server rules",
"you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules",
"its_something_else": "Its something else",
"the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories"
"step_1_of_4": "Bước 1 trong 4",
"whats_wrong_with_this_post": "Có vấn đề gì với tút này?",
"whats_wrong_with_this_account": "Có vấn đề gì với người này?",
"whats_wrong_with_this_username": "Có vấn đề gì với %s?",
"select_the_best_match": "Chọn lý do khớp nhất",
"i_dont_like_it": "Tôi không thích nó",
"it_is_not_something_you_want_to_see": "Đó không phải là thứ gì mà bạn muốn thấy",
"its_spam": "Đây là spam",
"malicious_links_fake_engagement_or_repetetive_replies": "Liên kết độc hại, tạo tương tác giả hoặc trả lời lặp đi lặp lại",
"it_violates_server_rules": "Vi phạm quy tắc máy chủ",
"you_are_aware_that_it_breaks_specific_rules": "Bạn nhận thấy nó vi phạm quy tắc máy chủ",
"its_something_else": "Một lý do khác",
"the_issue_does_not_fit_into_other_categories": "Vấn đề không nằm trong những mục trên"
},
"step_two": {
"step_2_of_4": "Step 2 of 4",
"which_rules_are_being_violated": "Which rules are being violated?",
"select_all_that_apply": "Select all that apply",
"i_just_dont_like_it": "I just dont like it"
"step_2_of_4": "Bước 2 trong 4",
"which_rules_are_being_violated": "Vi phạm quy tắc nào?",
"select_all_that_apply": "Chọn tất cả những gì phù hợp",
"i_just_dont_like_it": "Tôi không thích nó"
},
"step_three": {
"step_3_of_4": "Step 3 of 4",
"are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?",
"select_all_that_apply": "Select all that apply"
"step_3_of_4": "Bước 3 trong 4",
"are_there_any_posts_that_back_up_this_report": "Bạn muốn gửi tút nào kèm báo cáo này?",
"select_all_that_apply": "Chọn tất cả những gì phù hợp"
},
"step_four": {
"step_4_of_4": "Step 4 of 4",
"is_there_anything_else_we_should_know": "Is there anything else we should know?"
"step_4_of_4": "Bước 4 trong 4",
"is_there_anything_else_we_should_know": "Bạn nghĩ chúng tôi nên biết thêm điều gì?"
},
"step_final": {
"dont_want_to_see_this": "Dont want to see this?",
"when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you dont like on Mastodon, you can remove the person from your experience.",
"unfollow": "Unfollow",
"unfollowed": "Unfollowed",
"unfollow_user": "Unfollow %s",
"mute_user": "Mute %s",
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You wont see their posts or reblogs in your home feed. They wont know theyve been muted.",
"block_user": "Block %s",
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if theyve been blocked.",
"while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s"
"dont_want_to_see_this": "Không muốn xem thứ này?",
"when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Khi bạn thấy có gì đó mà bạn không thích trên Mastodon, bạn có thể tự loại bỏ chúng.",
"unfollow": "Ngưng theo dõi",
"unfollowed": "Ngưng theo dõi",
"unfollow_user": "Ngưng theo dõi %s",
"mute_user": "Ẩn %s",
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Bạn sẽ không thấy tút hoặc lượt đăng lại của họ trên bảng tin. Họ không biết rằng bạn ẩn họ.",
"block_user": "Chặn %s",
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Họ sẽ không thể theo dõi hoặc đọc tút của bạn, nhưng họ có thể hiểu bạn đã chặn họ.",
"while_we_review_this_you_can_take_action_against_user": "Trong lúc chờ chúng tôi xem xét, bạn có thể áp dụng hành động với @%s"
}
},
"preview": {

View File

@ -44,6 +44,29 @@
<string>%ld 个字符</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string>%1$@ 和你关注的另外 %ld 人也关注了这个账号</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
@ -69,7 +92,7 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string>%ld media</string>
<string>%ld 个媒体</string>
</dict>
</dict>
<key>plural.count.post</key>

View File

@ -241,7 +241,7 @@
},
"input": {
"placeholder": "查找或加入你自己的服务器...",
"search_servers_or_enter_url": "Search communities or enter URL"
"search_servers_or_enter_url": "搜索服务器或输入 URL"
},
"empty_state": {
"finding_servers": "正在查找可用的服务器...",
@ -251,7 +251,7 @@
},
"register": {
"title": "让我们在 %s 上开始",
"lets_get_you_set_up_on_domain": "Lets get you set up on %s",
"lets_get_you_set_up_on_domain": "让我们在 %s 上开始",
"input": {
"avatar": {
"delete": "删除"
@ -322,7 +322,7 @@
"confirm_email": {
"title": "最后一件事。",
"subtitle": "点击我们发送给您的链接来验证您的账户。",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "点击我们发送给您的链接来验证您的账户。",
"button": {
"open_email_app": "打开电子邮件应用",
"resend": "重新发送"
@ -347,8 +347,8 @@
"published": "已发送",
"Publishing": "正在发送...",
"accessibility": {
"logo_label": "Logo Button",
"logo_hint": "Tap to scroll to top and tap again to previous location"
"logo_label": "Logo 按钮",
"logo_hint": "轻点滚到顶部,再次轻点回到原处"
}
}
},
@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "不会显示来自其它服务器的关注者"
},
"following": {
"title": "following",
"footer": "不会显示来自其它服务器的关注"
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "搜索",
"search_bar": {
@ -605,46 +617,46 @@
"text_placeholder": "输入或粘贴额外的注释",
"reported": "已报告",
"step_one": {
"step_1_of_4": "Step 1 of 4",
"whats_wrong_with_this_post": "What's wrong with this post?",
"whats_wrong_with_this_account": "What's wrong with this account?",
"whats_wrong_with_this_username": "What's wrong with %s?",
"select_the_best_match": "Select the best match",
"i_dont_like_it": "I dont like it",
"it_is_not_something_you_want_to_see": "It is not something you want to see",
"its_spam": "Its spam",
"malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies",
"it_violates_server_rules": "It violates server rules",
"you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules",
"its_something_else": "Its something else",
"the_issue_does_not_fit_into_other_categories": "The issue does not fit into other categories"
"step_1_of_4": "第 1 步(共 4 步)",
"whats_wrong_with_this_post": "这个帖子有什么问题?",
"whats_wrong_with_this_account": "这个账户有什么问题?",
"whats_wrong_with_this_username": "%s 有什么问题?",
"select_the_best_match": "选择最佳匹配",
"i_dont_like_it": "我不喜欢它",
"it_is_not_something_you_want_to_see": "这不是你想看到的东西",
"its_spam": "它是垃圾信息",
"malicious_links_fake_engagement_or_repetetive_replies": "恶意链接、虚假参与或重复性回复",
"it_violates_server_rules": "它违反了服务器规则",
"you_are_aware_that_it_breaks_specific_rules": "你发现它违反了某个服务器规则",
"its_something_else": "其他原因",
"the_issue_does_not_fit_into_other_categories": "该问题属于其他类别"
},
"step_two": {
"step_2_of_4": "Step 2 of 4",
"which_rules_are_being_violated": "Which rules are being violated?",
"select_all_that_apply": "Select all that apply",
"i_just_dont_like_it": "I just dont like it"
"step_2_of_4": "第 2 步(共 4 步)",
"which_rules_are_being_violated": "哪些规则被违反了?",
"select_all_that_apply": "选择适用选项",
"i_just_dont_like_it": "我不喜欢它"
},
"step_three": {
"step_3_of_4": "Step 3 of 4",
"are_there_any_posts_that_back_up_this_report": "Are there any posts that back up this report?",
"select_all_that_apply": "Select all that apply"
"step_3_of_4": "第 3 步(共 4 步)",
"are_there_any_posts_that_back_up_this_report": "有任何帖子可以支持此报告吗?",
"select_all_that_apply": "选择适用选项"
},
"step_four": {
"step_4_of_4": "Step 4 of 4",
"is_there_anything_else_we_should_know": "Is there anything else we should know?"
"step_4_of_4": "第 4 步(共 4 步)",
"is_there_anything_else_we_should_know": "还有什么你认为我们应该知道的吗?"
},
"step_final": {
"dont_want_to_see_this": "Dont want to see this?",
"when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you dont like on Mastodon, you can remove the person from your experience.",
"unfollow": "Unfollow",
"unfollowed": "Unfollowed",
"unfollow_user": "Unfollow %s",
"mute_user": "Mute %s",
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "You wont see their posts or reblogs in your home feed. They wont know theyve been muted.",
"block_user": "Block %s",
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "They will no longer be able to follow or see your posts, but they can see if theyve been blocked.",
"while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s"
"dont_want_to_see_this": "不想看到这个内容?",
"when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "当你在 Mastodon 看到不喜欢的东西时,可以尝试移除它。",
"unfollow": "取消关注",
"unfollowed": "已取消关注",
"unfollow_user": "取消关注 %s",
"mute_user": "静音 %s",
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "你不会在主页里看到他们的帖子和转发。他们不会知道被静音了。",
"block_user": "屏蔽 %s",
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "他们将不再能够关注或看到你的帖子,但他们可以知道他们是否被屏蔽。",
"while_we_review_this_you_can_take_action_against_user": "当我们审核这个报告时,你可以对 %s 采取行动。"
}
},
"preview": {

View File

@ -44,6 +44,29 @@
<string>%ld 個字</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@names@%#@count_mutual@</string>
<key>names</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string></string>
</dict>
<key>count_mutual</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -251,7 +251,7 @@
},
"register": {
"title": "讓我們一起設定 %s 吧!",
"lets_get_you_set_up_on_domain": "Lets get you set up on %s",
"lets_get_you_set_up_on_domain": "讓我們一起設定 %s 吧!",
"input": {
"avatar": {
"delete": "刪除"
@ -322,7 +322,7 @@
"confirm_email": {
"title": "最後一步。",
"subtitle": "點擊我們寄送給您的帳號驗證連結。",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "點擊我們寄送給您的帳號驗證連結",
"button": {
"open_email_app": "開啟電子郵件 App",
"resend": "重新發送"
@ -462,11 +462,23 @@
}
},
"follower": {
"title": "follower",
"footer": "來自其他伺服器的跟隨者不會被顯示。"
},
"following": {
"title": "following",
"footer": "來自其他伺服器的跟隨中不會被顯示。"
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
},
"favorited_by": {
"title": "Favorited By"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "搜尋",
"search_bar": {

View File

@ -289,6 +289,17 @@
DB552D4F26BBD10C00E481F6 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = DB552D4E26BBD10C00E481F6 /* OrderedCollections */; };
DB564BD3269F3B35001E39A7 /* StatusFilterService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB564BD2269F3B35001E39A7 /* StatusFilterService.swift */; };
DB59F10E25EF724F001F1DAB /* APIService+Poll.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB59F10D25EF724F001F1DAB /* APIService+Poll.swift */; };
DB5B549A2833A60400DEF8B2 /* FamiliarFollowersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */; };
DB5B549D2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */; };
DB5B549F2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */; };
DB5B54A12833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */; };
DB5B54A32833BD1A00DEF8B2 /* UserListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A22833BD1A00DEF8B2 /* UserListViewModel.swift */; };
DB5B54A62833BE0000DEF8B2 /* UserListViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A52833BE0000DEF8B2 /* UserListViewModel+State.swift */; };
DB5B54A82833BFA500DEF8B2 /* FavoritedByViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A72833BFA500DEF8B2 /* FavoritedByViewController.swift */; };
DB5B54AB2833C12A00DEF8B2 /* RebloggedByViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54AA2833C12A00DEF8B2 /* RebloggedByViewController.swift */; };
DB5B54AE2833C15F00DEF8B2 /* UserListViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54AD2833C15F00DEF8B2 /* UserListViewModel+Diffable.swift */; };
DB5B54B02833C24200DEF8B2 /* FavoritedByViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54AF2833C24200DEF8B2 /* FavoritedByViewController+DataSourceProvider.swift */; };
DB5B54B22833C24B00DEF8B2 /* RebloggedByViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54B12833C24B00DEF8B2 /* RebloggedByViewController+DataSourceProvider.swift */; };
DB5B7295273112B100081888 /* FollowingListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B7294273112B100081888 /* FollowingListViewController.swift */; };
DB5B7298273112C800081888 /* FollowingListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B7297273112C800081888 /* FollowingListViewModel.swift */; };
DB5B729C273113C200081888 /* FollowingListViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B729B273113C200081888 /* FollowingListViewModel+Diffable.swift */; };
@ -1042,6 +1053,17 @@
DB519B17281BCC2F00F0C99D /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = tr.lproj/Intents.stringsdict; sourceTree = "<group>"; };
DB564BD2269F3B35001E39A7 /* StatusFilterService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusFilterService.swift; sourceTree = "<group>"; };
DB59F10D25EF724F001F1DAB /* APIService+Poll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Poll.swift"; sourceTree = "<group>"; };
DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FamiliarFollowersViewController.swift; sourceTree = "<group>"; };
DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FamiliarFollowersViewModel.swift; sourceTree = "<group>"; };
DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FamiliarFollowersViewModel+Diffable.swift"; sourceTree = "<group>"; };
DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FamiliarFollowersViewController+DataSourceProvider.swift"; sourceTree = "<group>"; };
DB5B54A22833BD1A00DEF8B2 /* UserListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserListViewModel.swift; sourceTree = "<group>"; };
DB5B54A52833BE0000DEF8B2 /* UserListViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserListViewModel+State.swift"; sourceTree = "<group>"; };
DB5B54A72833BFA500DEF8B2 /* FavoritedByViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritedByViewController.swift; sourceTree = "<group>"; };
DB5B54AA2833C12A00DEF8B2 /* RebloggedByViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RebloggedByViewController.swift; sourceTree = "<group>"; };
DB5B54AD2833C15F00DEF8B2 /* UserListViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserListViewModel+Diffable.swift"; sourceTree = "<group>"; };
DB5B54AF2833C24200DEF8B2 /* FavoritedByViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FavoritedByViewController+DataSourceProvider.swift"; sourceTree = "<group>"; };
DB5B54B12833C24B00DEF8B2 /* RebloggedByViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RebloggedByViewController+DataSourceProvider.swift"; sourceTree = "<group>"; };
DB5B7294273112B100081888 /* FollowingListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingListViewController.swift; sourceTree = "<group>"; };
DB5B7297273112C800081888 /* FollowingListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingListViewModel.swift; sourceTree = "<group>"; };
DB5B729B273113C200081888 /* FollowingListViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FollowingListViewModel+Diffable.swift"; sourceTree = "<group>"; };
@ -2443,6 +2465,47 @@
path = View;
sourceTree = "<group>";
};
DB5B549B2833A60600DEF8B2 /* FamiliarFollowers */ = {
isa = PBXGroup;
children = (
DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */,
DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */,
DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */,
DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */,
);
path = FamiliarFollowers;
sourceTree = "<group>";
};
DB5B54A42833BD1D00DEF8B2 /* UserLIst */ = {
isa = PBXGroup;
children = (
DB5B54A22833BD1A00DEF8B2 /* UserListViewModel.swift */,
DB5B54AD2833C15F00DEF8B2 /* UserListViewModel+Diffable.swift */,
DB5B54A52833BE0000DEF8B2 /* UserListViewModel+State.swift */,
DB5B54A92833BFAC00DEF8B2 /* FavoritedBy */,
DB5B54AC2833C12D00DEF8B2 /* RebloggedBy */,
);
path = UserLIst;
sourceTree = "<group>";
};
DB5B54A92833BFAC00DEF8B2 /* FavoritedBy */ = {
isa = PBXGroup;
children = (
DB5B54A72833BFA500DEF8B2 /* FavoritedByViewController.swift */,
DB5B54AF2833C24200DEF8B2 /* FavoritedByViewController+DataSourceProvider.swift */,
);
path = FavoritedBy;
sourceTree = "<group>";
};
DB5B54AC2833C12D00DEF8B2 /* RebloggedBy */ = {
isa = PBXGroup;
children = (
DB5B54AA2833C12A00DEF8B2 /* RebloggedByViewController.swift */,
DB5B54B12833C24B00DEF8B2 /* RebloggedByViewController+DataSourceProvider.swift */,
);
path = RebloggedBy;
sourceTree = "<group>";
};
DB5B7296273112B400081888 /* Following */ = {
isa = PBXGroup;
children = (
@ -2944,6 +3007,8 @@
DBE3CDF1261C6B3100430CC6 /* Favorite */,
DB6B74F0272FB55400C70B6E /* Follower */,
DB5B7296273112B400081888 /* Following */,
DB5B549B2833A60600DEF8B2 /* FamiliarFollowers */,
DB5B54A42833BD1D00DEF8B2 /* UserLIst */,
DBFEEC97279BDC6A004F81DD /* About */,
DB9D6BFE25E4F5940051B173 /* ProfileViewController.swift */,
DBB5255D2611F07A002F1F29 /* ProfileViewModel.swift */,
@ -3864,6 +3929,7 @@
buildActionMask = 2147483647;
files = (
DBB525212611EBD6002F1F29 /* ProfilePagingViewController.swift in Sources */,
DB5B54A82833BFA500DEF8B2 /* FavoritedByViewController.swift in Sources */,
DBDFF19E2805703700557A48 /* DiscoveryPostsViewController+DataSourceProvider.swift in Sources */,
DB6180EB26391C140018D199 /* MediaPreviewTransitionItem.swift in Sources */,
DB63F74727990B0600455B82 /* DataSourceFacade+Hashtag.swift in Sources */,
@ -3874,6 +3940,7 @@
DB1D843426579931000346B3 /* TableViewControllerNavigateable.swift in Sources */,
0FAA0FDF25E0B57E0017CCDE /* WelcomeViewController.swift in Sources */,
DB65C63727A2AF6C008BAC2E /* ReportItem.swift in Sources */,
DB5B54B22833C24B00DEF8B2 /* RebloggedByViewController+DataSourceProvider.swift in Sources */,
2D59819B25E4A581000FB903 /* MastodonConfirmEmailViewController.swift in Sources */,
DB45FB1D25CA9D23005A8AC7 /* APIService+HomeTimeline.swift in Sources */,
DBA94440265D137600C537E1 /* Mastodon+Entity+Field.swift in Sources */,
@ -3888,6 +3955,7 @@
0FB3D2F725E4C24D00AAD544 /* MastodonPickServerViewModel.swift in Sources */,
2D61335E25C1894B00CAE157 /* APIService.swift in Sources */,
2D9DB967263A76FB007C1D71 /* BlockDomainService.swift in Sources */,
DB5B54AE2833C15F00DEF8B2 /* UserListViewModel+Diffable.swift in Sources */,
DB336F43278EB1690031E64B /* MediaView+Configuration.swift in Sources */,
DB66729625F9F91600D60309 /* ComposeStatusSection.swift in Sources */,
DB482A3F261331E8008AE74C /* UserTimelineViewModel+State.swift in Sources */,
@ -3941,6 +4009,7 @@
5DDDF1932617442700311060 /* Mastodon+Entity+Account.swift in Sources */,
DB63F767279A5EB300455B82 /* NotificationTimelineViewModel.swift in Sources */,
2D607AD826242FC500B70763 /* NotificationViewModel.swift in Sources */,
DB5B54AB2833C12A00DEF8B2 /* RebloggedByViewController.swift in Sources */,
DB848E33282B62A800A302CC /* ReportResultView.swift in Sources */,
DBABE3EC25ECAC4B00879EE5 /* WelcomeIllustrationView.swift in Sources */,
DB564BD3269F3B35001E39A7 /* StatusFilterService.swift in Sources */,
@ -3963,12 +4032,14 @@
DB98EB5E27B10A7A0082E365 /* ReportSupplementaryViewModel+Diffable.swift in Sources */,
DB0FCB7C2795821F006C02E2 /* StatusThreadRootTableViewCell.swift in Sources */,
DB72601C25E36A2100235243 /* MastodonServerRulesViewController.swift in Sources */,
DB5B54A32833BD1A00DEF8B2 /* UserListViewModel.swift in Sources */,
DBB5250E2611EBAF002F1F29 /* ProfileSegmentedViewController.swift in Sources */,
DBF156DF2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift in Sources */,
DB0617F1278413D00030EE79 /* PickServerServerSectionTableHeaderView.swift in Sources */,
DB0FCB7E27958957006C02E2 /* StatusThreadRootTableViewCell+ViewModel.swift in Sources */,
DB789A0B25F9F2950071ACA0 /* ComposeViewController.swift in Sources */,
DB938F0926240F3C00E5B6C1 /* RemoteThreadViewModel.swift in Sources */,
DB5B54A62833BE0000DEF8B2 /* UserListViewModel+State.swift in Sources */,
DB0617ED277F02C50030EE79 /* OnboardingNavigationController.swift in Sources */,
DB0617F527855AB90030EE79 /* ServerRuleSection.swift in Sources */,
DB75BF1E263C1C1B00EDBF1F /* CustomScheduler.swift in Sources */,
@ -4010,11 +4081,13 @@
DBF9814A265E24F500E4BA07 /* ProfileFieldCollectionViewHeaderFooterView.swift in Sources */,
2D939AB525EDD8A90076FA61 /* String.swift in Sources */,
DB4481B925EE289600BEFB67 /* UITableView.swift in Sources */,
DB5B54B02833C24200DEF8B2 /* FavoritedByViewController+DataSourceProvider.swift in Sources */,
DBE3CDBB261C427900430CC6 /* TimelineHeaderTableViewCell.swift in Sources */,
DB159C2B27A17BAC0068DC77 /* DataSourceFacade+Media.swift in Sources */,
0FAA101C25E10E760017CCDE /* UIFont.swift in Sources */,
2D38F1D525CD465300561493 /* HomeTimelineViewController.swift in Sources */,
DB6180E926391BDF0018D199 /* MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift in Sources */,
DB5B549F2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift in Sources */,
DB6B351E2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift in Sources */,
DB8F7076279E954700E1225B /* DataSourceFacade+Follow.swift in Sources */,
DB36679F268ABAF20027D07F /* ComposeStatusAttachmentSection.swift in Sources */,
@ -4045,6 +4118,7 @@
DB98EB5327B0F9890082E365 /* ReportHeadlineTableViewCell.swift in Sources */,
DB5B729C273113C200081888 /* FollowingListViewModel+Diffable.swift in Sources */,
DB9E0D6F25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift in Sources */,
DB5B549D2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift in Sources */,
DBB9759C262462E1004620BD /* ThreadMetaView.swift in Sources */,
DB5B729E273113F300081888 /* FollowingListViewModel+State.swift in Sources */,
2DF123A725C3B0210020F248 /* ActiveLabel.swift in Sources */,
@ -4064,6 +4138,7 @@
DB6180E02639194B0018D199 /* MediaPreviewPagingViewController.swift in Sources */,
DBE0822425CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift in Sources */,
5B90C45E262599800002E742 /* SettingsViewModel.swift in Sources */,
DB5B54A12833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift in Sources */,
2D82B9FF25E7863200E36F0F /* OnboardingViewControllerAppearance.swift in Sources */,
DB73BF43271192BB00781945 /* InstanceService.swift in Sources */,
DB67D08427312970006A36CF /* APIService+Following.swift in Sources */,
@ -4239,6 +4314,7 @@
DBD376AC2692ECDB007FEC24 /* ThemePreference.swift in Sources */,
DB4F097D26A03A5B00D62E92 /* SearchHistoryItem.swift in Sources */,
DBD5B1FA27BD013700BD6B38 /* DataSourceProvider+StatusTableViewControllerNavigateable.swift in Sources */,
DB5B549A2833A60400DEF8B2 /* FamiliarFollowersViewController.swift in Sources */,
DB3E6FE22806A50100B035AE /* DiscoveryHashtagsViewModel+Diffable.swift in Sources */,
DB68046C2636DC9E00430867 /* MastodonNotification.swift in Sources */,
DBAE3F9E2616E308004B8251 /* APIService+Mute.swift in Sources */,
@ -4756,7 +4832,7 @@
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@ -4786,7 +4862,7 @@
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@ -4894,11 +4970,11 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 127;
DYLIB_CURRENT_VERSION = 130;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = AppShared/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@ -4925,11 +5001,11 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 127;
DYLIB_CURRENT_VERSION = 130;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = AppShared/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@ -5020,7 +5096,7 @@
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@ -5088,11 +5164,11 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 127;
DYLIB_CURRENT_VERSION = 130;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = AppShared/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@ -5117,7 +5193,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5140,7 +5216,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5164,7 +5240,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = MastodonIntent/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5188,7 +5264,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = MastodonIntent/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5212,7 +5288,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = MastodonIntent/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5236,7 +5312,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5260,7 +5336,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5347,7 +5423,7 @@
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@ -5414,11 +5490,11 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 127;
DYLIB_CURRENT_VERSION = 130;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = AppShared/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@ -5442,7 +5518,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5465,7 +5541,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5489,7 +5565,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = MastodonIntent/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5513,7 +5589,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5536,7 +5612,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 127;
CURRENT_PROJECT_VERSION = 130;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (

View File

@ -114,7 +114,7 @@
<key>MastodonIntent.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>20</integer>
<integer>28</integer>
</dict>
<key>MastodonIntents.xcscheme_^#shared#^_</key>
<dict>
@ -129,12 +129,12 @@
<key>NotificationService.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>21</integer>
<integer>29</integer>
</dict>
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>22</integer>
<integer>27</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>

View File

@ -178,6 +178,9 @@ extension SceneCoordinator {
case favorite(viewModel: FavoriteViewModel)
case follower(viewModel: FollowerListViewModel)
case following(viewModel: FollowingListViewModel)
case familiarFollowers(viewModel: FamiliarFollowersViewModel)
case rebloggedBy(viewModel: UserListViewModel)
case favoritedBy(viewModel: UserListViewModel)
// setting
case settings(viewModel: SettingsViewModel)
@ -445,6 +448,18 @@ private extension SceneCoordinator {
let _viewController = FollowingListViewController()
_viewController.viewModel = viewModel
viewController = _viewController
case .familiarFollowers(let viewModel):
let _viewController = FamiliarFollowersViewController()
_viewController.viewModel = viewModel
viewController = _viewController
case .rebloggedBy(let viewModel):
let _viewController = RebloggedByViewController()
_viewController.viewModel = viewModel
viewController = _viewController
case .favoritedBy(let viewModel):
let _viewController = FavoritedByViewController()
_viewController.viewModel = viewModel
viewController = _viewController
case .report(let viewModel):
let _viewController = ReportViewController()
_viewController.viewModel = viewModel

View File

@ -8,6 +8,7 @@
import os.log
import UIKit
import MastodonUI
import MastodonSDK
enum DiscoverySection: CaseIterable {
// case posts
@ -22,9 +23,14 @@ extension DiscoverySection {
class Configuration {
weak var profileCardTableViewCellDelegate: ProfileCardTableViewCellDelegate?
let familiarFollowers: Published<[Mastodon.Entity.FamiliarFollowers]>.Publisher?
public init(profileCardTableViewCellDelegate: ProfileCardTableViewCellDelegate? = nil) {
public init(
profileCardTableViewCellDelegate: ProfileCardTableViewCellDelegate? = nil,
familiarFollowers: Published<[Mastodon.Entity.FamiliarFollowers]>.Publisher? = nil
) {
self.profileCardTableViewCellDelegate = profileCardTableViewCellDelegate
self.familiarFollowers = familiarFollowers
}
}
@ -57,6 +63,15 @@ extension DiscoverySection {
user: user,
profileCardTableViewCellDelegate: configuration.profileCardTableViewCellDelegate
)
// bind familiarFollowers
if let familiarFollowers = configuration.familiarFollowers {
familiarFollowers
.map { array in array.first(where: { $0.id == user.id }) }
.assign(to: \.familiarFollowers, on: cell.profileCardView.viewModel)
.store(in: &cell.disposeBag)
} else {
cell.profileCardView.viewModel.familiarFollowers = nil
}
}
context.authenticationService.activeMastodonAuthentication
.map { $0?.user }

View File

@ -30,7 +30,9 @@ extension UserSection {
configuration: Configuration
) -> UITableViewDiffableDataSource<UserSection, UserItem> {
tableView.register(UserTableViewCell.self, forCellReuseIdentifier: String(describing: UserTableViewCell.self))
tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self))
tableView.register(TimelineFooterTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineFooterTableViewCell.self))
return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in
switch item {
case .user(let record):

View File

@ -36,3 +36,6 @@ func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith con

View File

@ -43,7 +43,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
<string>127</string>
<string>130</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false/>
<key>LSApplicationQueriesSchemes</key>

View File

@ -474,6 +474,55 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider {
}
// MARK: - StatusMetricView
extension StatusTableViewCellDelegate where Self: DataSourceProvider {
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton) {
Task {
let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil)
guard let item = await item(from: source) else {
assertionFailure()
return
}
guard case let .status(status) = item else {
assertionFailure("only works for status data provider")
return
}
let userListViewModel = UserListViewModel(
context: context,
kind: .rebloggedBy(status: status)
)
await coordinator.present(
scene: .rebloggedBy(viewModel: userListViewModel),
from: self,
transition: .show
)
} // end Task
}
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton) {
Task {
let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil)
guard let item = await item(from: source) else {
assertionFailure()
return
}
guard case let .status(status) = item else {
assertionFailure("only works for status data provider")
return
}
let userListViewModel = UserListViewModel(
context: context,
kind: .favoritedBy(status: status)
)
await coordinator.present(
scene: .favoritedBy(viewModel: userListViewModel),
from: self,
transition: .show
)
} // end Task
}
}
// MARK: a11y
extension StatusTableViewCellDelegate where Self: DataSourceProvider {
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, accessibilityActivate: Void) {

View File

@ -122,7 +122,11 @@ extension DiscoveryForYouViewController: UITableViewDelegate {
// MARK: - ProfileCardTableViewCellDelegate
extension DiscoveryForYouViewController: ProfileCardTableViewCellDelegate {
func profileCardTableViewCell(_ cell: ProfileCardTableViewCell, profileCardView: ProfileCardView, relationshipButtonDidPressed button: ProfileRelationshipActionButton) {
func profileCardTableViewCell(
_ cell: ProfileCardTableViewCell,
profileCardView: ProfileCardView,
relationshipButtonDidPressed button: ProfileRelationshipActionButton
) {
guard let authenticationBox = viewModel.context.authenticationService.activeMastodonAuthenticationBox.value else { return }
guard let indexPath = tableView.indexPath(for: cell) else { return }
guard case let .user(record) = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { return }
@ -135,6 +139,31 @@ extension DiscoveryForYouViewController: ProfileCardTableViewCellDelegate {
)
} // end Task
}
func profileCardTableViewCell(
_ cell: ProfileCardTableViewCell,
profileCardView: ProfileCardView,
familiarFollowersDashboardViewDidPressed view: FamiliarFollowersDashboardView
) {
guard let indexPath = tableView.indexPath(for: cell) else { return }
guard case let .user(record) = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { return }
guard let user = record.object(in: context.managedObjectContext) else { return }
let userID = user.id
let _familiarFollowers = viewModel.familiarFollowers.first(where: { $0.id == userID })
guard let familiarFollowers = _familiarFollowers else {
assertionFailure()
return
}
let familiarFollowersViewModel = FamiliarFollowersViewModel(context: context)
familiarFollowersViewModel.familiarFollowers = familiarFollowers
coordinator.present(
scene: .familiarFollowers(viewModel: familiarFollowersViewModel),
from: self,
transition: .show
)
}
}
// MARK: ScrollViewContainer

View File

@ -19,7 +19,8 @@ extension DiscoveryForYouViewModel {
tableView: tableView,
context: context,
configuration: DiscoverySection.Configuration(
profileCardTableViewCellDelegate: profileCardTableViewCellDelegate
profileCardTableViewCellDelegate: profileCardTableViewCellDelegate,
familiarFollowers: $familiarFollowers
)
)

View File

@ -20,6 +20,9 @@ final class DiscoveryForYouViewModel {
// input
let context: AppContext
let userFetchedResultsController: UserFetchedResultsController
@MainActor
@Published var familiarFollowers: [Mastodon.Entity.FamiliarFollowers] = []
@Published var isFetching = false
// output
@ -48,12 +51,35 @@ final class DiscoveryForYouViewModel {
}
extension DiscoveryForYouViewModel {
@MainActor
func fetch() async throws {
guard !isFetching else { return }
isFetching = true
defer { isFetching = false }
guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else { return }
guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else {
throw APIService.APIError.implicit(.badRequest)
}
do {
let userIDs = try await fetchSuggestionAccounts()
let _familiarFollowersResponse = try? await context.apiService.familiarFollowers(
query: .init(ids: userIDs),
authenticationBox: authenticationBox
)
familiarFollowers = _familiarFollowersResponse?.value ?? []
userFetchedResultsController.userIDs = userIDs
} catch {
// do nothing
}
}
private func fetchSuggestionAccounts() async throws -> [Mastodon.Entity.Account.ID] {
guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else {
throw APIService.APIError.implicit(.badRequest)
}
do {
let response = try await context.apiService.suggestionAccountV2(
@ -61,15 +87,15 @@ extension DiscoveryForYouViewModel {
authenticationBox: authenticationBox
)
let userIDs = response.value.map { $0.account.id }
userFetchedResultsController.userIDs = userIDs
return userIDs
} catch {
// fallback V1
let response2 = try await context.apiService.suggestionAccount(
let response = try await context.apiService.suggestionAccount(
query: nil,
authenticationBox: authenticationBox
)
let userIDs = response2.value.map { $0.id }
userFetchedResultsController.userIDs = userIDs
let userIDs = response.value.map { $0.id }
return userIDs
}
}
}

View File

@ -0,0 +1,34 @@
//
// FamiliarFollowersViewController+DataSourceProvider.swift
// Mastodon
//
// Created by MainasuK on 2022-5-17.
//
import UIKit
extension FamiliarFollowersViewController: DataSourceProvider {
func item(from source: DataSourceItem.Source) async -> DataSourceItem? {
var _indexPath = source.indexPath
if _indexPath == nil, let cell = source.tableViewCell {
_indexPath = await self.indexPath(for: cell)
}
guard let indexPath = _indexPath else { return nil }
guard let item = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else {
return nil
}
switch item {
case .user(let record):
return .user(record: record)
default:
return nil
}
}
@MainActor
private func indexPath(for cell: UITableViewCell) async -> IndexPath? {
return tableView.indexPath(for: cell)
}
}

View File

@ -0,0 +1,91 @@
//
// FamiliarFollowersViewController.swift
// Mastodon
//
// Created by MainasuK on 2022-5-17.
//
import os.log
import UIKit
import Combine
import MastodonLocalization
final class FamiliarFollowersViewController: UIViewController, NeedsDependency {
let logger = Logger(subsystem: "FamiliarFollowersViewController", category: "ViewController")
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
var disposeBag = Set<AnyCancellable>()
var viewModel: FamiliarFollowersViewModel!
lazy var tableView: UITableView = {
let tableView = UITableView()
tableView.rowHeight = UITableView.automaticDimension
tableView.separatorStyle = .none
tableView.backgroundColor = .clear
return tableView
}()
deinit {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
}
}
extension FamiliarFollowersViewController {
override func viewDidLoad() {
super.viewDidLoad()
title = L10n.Scene.Familiarfollowers.title
view.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor
ThemeService.shared.currentTheme
.receive(on: DispatchQueue.main)
.sink { [weak self] theme in
guard let self = self else { return }
self.view.backgroundColor = theme.secondarySystemBackgroundColor
}
.store(in: &disposeBag)
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
tableView.delegate = self
viewModel.setupDiffableDataSource(
tableView: tableView,
userTableViewCellDelegate: self
)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.deselectRow(with: transitionCoordinator, animated: animated)
}
}
// MARK: - UITableViewDelegate
extension FamiliarFollowersViewController: UITableViewDelegate, AutoGenerateTableViewDelegate {
// sourcery:inline:FamiliarFollowersViewController.AutoGenerateTableViewDelegate
// Generated using Sourcery
// DO NOT EDIT
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
aspectTableView(tableView, didSelectRowAt: indexPath)
}
// sourcery:end
}
// MARK: - UserTableViewCellDelegate
extension FamiliarFollowersViewController: UserTableViewCellDelegate { }

View File

@ -0,0 +1,39 @@
//
// FamiliarFollowersViewModel+Diffable.swift
// Mastodon
//
// Created by MainasuK on 2022-5-17.
//
import UIKit
extension FamiliarFollowersViewModel {
func setupDiffableDataSource(
tableView: UITableView,
userTableViewCellDelegate: UserTableViewCellDelegate?
) {
diffableDataSource = UserSection.diffableDataSource(
tableView: tableView,
context: context,
configuration: UserSection.Configuration(
userTableViewCellDelegate: userTableViewCellDelegate
)
)
userFetchedResultsController.$records
.receive(on: DispatchQueue.main)
.sink { [weak self] records in
guard let self = self else { return }
guard let diffableDataSource = self.diffableDataSource else { return }
var snapshot = NSDiffableDataSourceSnapshot<UserSection, UserItem>()
snapshot.appendSections([.main])
let items = records.map { UserItem.user(record: $0) }
snapshot.appendItems(items, toSection: .main)
diffableDataSource.apply(snapshot, animatingDifferences: false)
}
.store(in: &disposeBag)
}
}

View File

@ -0,0 +1,49 @@
//
// FamiliarFollowersViewModel.swift
// Mastodon
//
// Created by MainasuK on 2022-5-17.
//
import UIKit
import Combine
import MastodonSDK
import CoreDataStack
final class FamiliarFollowersViewModel {
var disposeBag = Set<AnyCancellable>()
// input
let context: AppContext
let userFetchedResultsController: UserFetchedResultsController
@Published var familiarFollowers: Mastodon.Entity.FamiliarFollowers?
// output
var diffableDataSource: UITableViewDiffableDataSource<UserSection, UserItem>?
init(context: AppContext) {
self.context = context
self.userFetchedResultsController = UserFetchedResultsController(
managedObjectContext: context.managedObjectContext,
domain: nil,
additionalPredicate: nil
)
// end init
context.authenticationService.activeMastodonAuthenticationBox
.map { $0?.domain }
.assign(to: \.domain, on: userFetchedResultsController)
.store(in: &disposeBag)
$familiarFollowers
.map { familiarFollowers -> [MastodonUser.ID] in
guard let familiarFollowers = familiarFollowers else { return [] }
return familiarFollowers.accounts.map { $0.id }
}
.assign(to: \.userIDs, on: userFetchedResultsController)
.store(in: &disposeBag)
}
}

View File

@ -9,6 +9,7 @@ import os.log
import UIKit
import GameplayKit
import Combine
import MastodonLocalization
final class FollowerListViewController: UIViewController, NeedsDependency {
@ -42,6 +43,8 @@ extension FollowerListViewController {
override func viewDidLoad() {
super.viewDidLoad()
title = L10n.Scene.Follower.title
view.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor
ThemeService.shared.currentTheme
.receive(on: DispatchQueue.main)

View File

@ -9,6 +9,7 @@ import os.log
import UIKit
import GameplayKit
import Combine
import MastodonLocalization
final class FollowingListViewController: UIViewController, NeedsDependency {
@ -42,6 +43,8 @@ extension FollowingListViewController {
override func viewDidLoad() {
super.viewDidLoad()
title = L10n.Scene.Following.title
view.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor
ThemeService.shared.currentTheme
.receive(on: DispatchQueue.main)
@ -81,12 +84,18 @@ extension FollowingListViewController {
viewModel.domain.removeDuplicates().eraseToAnyPublisher(),
viewModel.userID.removeDuplicates().eraseToAnyPublisher()
)
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
guard let self = self else { return }
self.viewModel.stateMachine.enter(FollowingListViewModel.State.Reloading.self)
}
.store(in: &disposeBag)
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
guard let self = self else { return }
self.viewModel.stateMachine.enter(FollowingListViewModel.State.Reloading.self)
}
.store(in: &disposeBag)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.deselectRow(with: transitionCoordinator, animated: animated)
}
}

View File

@ -0,0 +1,34 @@
//
// FavoritedByViewController+DataSourceProvider.swift
// Mastodon
//
// Created by MainasuK on 2022-5-17.
//
import UIKit
extension FavoritedByViewController: DataSourceProvider {
func item(from source: DataSourceItem.Source) async -> DataSourceItem? {
var _indexPath = source.indexPath
if _indexPath == nil, let cell = source.tableViewCell {
_indexPath = await self.indexPath(for: cell)
}
guard let indexPath = _indexPath else { return nil }
guard let item = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else {
return nil
}
switch item {
case .user(let record):
return .user(record: record)
default:
return nil
}
}
@MainActor
private func indexPath(for cell: UITableViewCell) async -> IndexPath? {
return tableView.indexPath(for: cell)
}
}

View File

@ -0,0 +1,109 @@
//
// FavoritedByViewController.swift
// Mastodon
//
// Created by MainasuK on 2022-5-17.
//
import os.log
import UIKit
import GameplayKit
import Combine
import MastodonLocalization
final class FavoritedByViewController: UIViewController, NeedsDependency {
let logger = Logger(subsystem: "FavoritedByViewController", category: "ViewController")
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
var disposeBag = Set<AnyCancellable>()
var viewModel: UserListViewModel!
lazy var tableView: UITableView = {
let tableView = UITableView()
tableView.rowHeight = UITableView.automaticDimension
tableView.separatorStyle = .none
tableView.backgroundColor = .clear
return tableView
}()
deinit {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
}
}
extension FavoritedByViewController {
override func viewDidLoad() {
super.viewDidLoad()
#if DEBUG
switch viewModel.kind {
case .favoritedBy: break
default: assertionFailure()
}
#endif
title = L10n.Scene.FavoritedBy.title
view.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor
ThemeService.shared.currentTheme
.receive(on: DispatchQueue.main)
.sink { [weak self] theme in
guard let self = self else { return }
self.view.backgroundColor = theme.secondarySystemBackgroundColor
}
.store(in: &disposeBag)
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
tableView.delegate = self
viewModel.setupDiffableDataSource(
tableView: tableView,
userTableViewCellDelegate: self
)
// setup batch fetch
viewModel.listBatchFetchViewModel.setup(scrollView: tableView)
viewModel.listBatchFetchViewModel.shouldFetch
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
guard let self = self else { return }
self.viewModel.stateMachine.enter(UserListViewModel.State.Loading.self)
}
.store(in: &disposeBag)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.deselectRow(with: transitionCoordinator, animated: animated)
}
}
// MARK: - UITableViewDelegate
extension FavoritedByViewController: UITableViewDelegate, AutoGenerateTableViewDelegate {
// sourcery:inline:FavoritedByViewController.AutoGenerateTableViewDelegate
// Generated using Sourcery
// DO NOT EDIT
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
aspectTableView(tableView, didSelectRowAt: indexPath)
}
// sourcery:end
}
// MARK: - UserTableViewCellDelegate
extension FavoritedByViewController: UserTableViewCellDelegate { }

View File

@ -0,0 +1,34 @@
//
// RebloggedByViewController+DataSourceProvider.swift
// Mastodon
//
// Created by MainasuK on 2022-5-17.
//
import UIKit
extension RebloggedByViewController: DataSourceProvider {
func item(from source: DataSourceItem.Source) async -> DataSourceItem? {
var _indexPath = source.indexPath
if _indexPath == nil, let cell = source.tableViewCell {
_indexPath = await self.indexPath(for: cell)
}
guard let indexPath = _indexPath else { return nil }
guard let item = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else {
return nil
}
switch item {
case .user(let record):
return .user(record: record)
default:
return nil
}
}
@MainActor
private func indexPath(for cell: UITableViewCell) async -> IndexPath? {
return tableView.indexPath(for: cell)
}
}

View File

@ -0,0 +1,109 @@
//
// RebloggedByViewController.swift
// Mastodon
//
// Created by MainasuK on 2022-5-17.
//
import os.log
import UIKit
import GameplayKit
import Combine
import MastodonLocalization
final class RebloggedByViewController: UIViewController, NeedsDependency {
let logger = Logger(subsystem: "RebloggedByViewController", category: "ViewController")
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
var disposeBag = Set<AnyCancellable>()
var viewModel: UserListViewModel!
lazy var tableView: UITableView = {
let tableView = UITableView()
tableView.rowHeight = UITableView.automaticDimension
tableView.separatorStyle = .none
tableView.backgroundColor = .clear
return tableView
}()
deinit {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
}
}
extension RebloggedByViewController {
override func viewDidLoad() {
super.viewDidLoad()
#if DEBUG
switch viewModel.kind {
case .rebloggedBy: break
default: assertionFailure()
}
#endif
title = L10n.Scene.RebloggedBy.title
view.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor
ThemeService.shared.currentTheme
.receive(on: DispatchQueue.main)
.sink { [weak self] theme in
guard let self = self else { return }
self.view.backgroundColor = theme.secondarySystemBackgroundColor
}
.store(in: &disposeBag)
tableView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(tableView)
NSLayoutConstraint.activate([
tableView.topAnchor.constraint(equalTo: view.topAnchor),
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
])
tableView.delegate = self
viewModel.setupDiffableDataSource(
tableView: tableView,
userTableViewCellDelegate: self
)
// setup batch fetch
viewModel.listBatchFetchViewModel.setup(scrollView: tableView)
viewModel.listBatchFetchViewModel.shouldFetch
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
guard let self = self else { return }
self.viewModel.stateMachine.enter(UserListViewModel.State.Loading.self)
}
.store(in: &disposeBag)
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.deselectRow(with: transitionCoordinator, animated: animated)
}
}
// MARK: - UITableViewDelegate
extension RebloggedByViewController: UITableViewDelegate, AutoGenerateTableViewDelegate {
// sourcery:inline:RebloggedByViewController.AutoGenerateTableViewDelegate
// Generated using Sourcery
// DO NOT EDIT
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
aspectTableView(tableView, didSelectRowAt: indexPath)
}
// sourcery:end
}
// MARK: - UserTableViewCellDelegate
extension RebloggedByViewController: UserTableViewCellDelegate { }

View File

@ -0,0 +1,71 @@
//
// UserListViewModel+Diffable.swift
// Mastodon
//
// Created by MainasuK on 2022-5-17.
//
import UIKit
import MastodonAsset
import MastodonLocalization
extension UserListViewModel {
@MainActor
func setupDiffableDataSource(
tableView: UITableView,
userTableViewCellDelegate: UserTableViewCellDelegate?
) {
diffableDataSource = UserSection.diffableDataSource(
tableView: tableView,
context: context,
configuration: UserSection.Configuration(
userTableViewCellDelegate: userTableViewCellDelegate
)
)
// workaround to append loader wrong animation issue
// set empty section to make update animation top-to-bottom style
var snapshot = NSDiffableDataSourceSnapshot<UserSection, UserItem>()
snapshot.appendSections([.main])
snapshot.appendItems([.bottomLoader], toSection: .main)
if #available(iOS 15.0, *) {
diffableDataSource?.applySnapshotUsingReloadData(snapshot, completion: nil)
} else {
// Fallback on earlier versions
diffableDataSource?.apply(snapshot, animatingDifferences: false)
}
// trigger initial loading
stateMachine.enter(UserListViewModel.State.Reloading.self)
userFetchedResultsController.$records
.receive(on: DispatchQueue.main)
.sink { [weak self] records in
guard let self = self else { return }
guard let diffableDataSource = self.diffableDataSource else { return }
var snapshot = NSDiffableDataSourceSnapshot<UserSection, UserItem>()
snapshot.appendSections([.main])
let items = records.map { UserItem.user(record: $0) }
snapshot.appendItems(items, toSection: .main)
if let currentState = self.stateMachine.currentState {
switch currentState {
case is State.Initial, is State.Idle, is State.Reloading, is State.Loading, is State.Fail:
snapshot.appendItems([.bottomLoader], toSection: .main)
case is State.NoMore:
if items.isEmpty {
snapshot.appendItems([.bottomHeader(text: L10n.Scene.Search.Searching.EmptyState.noResults)], toSection: .main)
}
default:
assertionFailure()
}
} else {
snapshot.appendItems([.bottomLoader], toSection: .main)
}
diffableDataSource.apply(snapshot, animatingDifferences: false)
}
.store(in: &disposeBag)
}
}

View File

@ -0,0 +1,211 @@
//
// UserListViewModel+State.swift
// Mastodon
//
// Created by MainasuK on 2022-5-17.
//
import os.log
import Foundation
import GameplayKit
import MastodonSDK
extension UserListViewModel {
class State: GKState, NamingState {
let logger = Logger(subsystem: "UserListViewModel.State", category: "StateMachine")
let id = UUID()
var name: String {
String(describing: Self.self)
}
weak var viewModel: UserListViewModel?
init(viewModel: UserListViewModel) {
self.viewModel = viewModel
}
override func didEnter(from previousState: GKState?) {
super.didEnter(from: previousState)
let previousState = previousState as? UserListViewModel.State
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [\(self.id.uuidString)] enter \(self.name), previous: \(previousState?.name ?? "<nil>")")
}
@MainActor
func enter(state: State.Type) {
stateMachine?.enter(state)
}
deinit {
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [\(self.id.uuidString)] \(self.name)")
}
}
}
extension UserListViewModel.State {
class Initial: UserListViewModel.State {
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
guard let _ = viewModel else { return false }
switch stateClass {
case is Reloading.Type:
return true
default:
return false
}
}
}
class Reloading: UserListViewModel.State {
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
switch stateClass {
case is Loading.Type:
return true
default:
return false
}
}
override func didEnter(from previousState: GKState?) {
super.didEnter(from: previousState)
guard let viewModel = viewModel, let stateMachine = stateMachine else { return }
// reset
viewModel.userFetchedResultsController.userIDs = []
stateMachine.enter(Loading.self)
}
}
class Fail: UserListViewModel.State {
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
switch stateClass {
case is Loading.Type:
return true
default:
return false
}
}
override func didEnter(from previousState: GKState?) {
super.didEnter(from: previousState)
guard let _ = viewModel, let stateMachine = stateMachine else { return }
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: retry loading 3s later…", ((#file as NSString).lastPathComponent), #line, #function)
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: retry loading", ((#file as NSString).lastPathComponent), #line, #function)
stateMachine.enter(Loading.self)
}
}
}
class Idle: UserListViewModel.State {
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
switch stateClass {
case is Reloading.Type, is Loading.Type:
return true
default:
return false
}
}
}
class Loading: UserListViewModel.State {
var maxID: String?
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
switch stateClass {
case is Fail.Type:
return true
case is Idle.Type:
return true
case is NoMore.Type:
return true
default:
return false
}
}
override func didEnter(from previousState: GKState?) {
super.didEnter(from: previousState)
if previousState is Reloading {
maxID = nil
}
guard let viewModel = viewModel, let stateMachine = stateMachine else { return }
guard let authenticationBox = viewModel.context.authenticationService.activeMastodonAuthenticationBox.value else {
stateMachine.enter(Fail.self)
return
}
let maxID = self.maxID
Task {
do {
let response: Mastodon.Response.Content<[Mastodon.Entity.Account]>
switch viewModel.kind {
case .favoritedBy(let status):
response = try await viewModel.context.apiService.favoritedBy(
status: status,
query: .init(maxID: maxID, limit: nil),
authenticationBox: authenticationBox
)
case .rebloggedBy(let status):
response = try await viewModel.context.apiService.rebloggedBy(
status: status,
query: .init(maxID: maxID, limit: nil),
authenticationBox: authenticationBox
)
}
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch \(response.value.count) accounts")
var hasNewAppend = false
var userIDs = viewModel.userFetchedResultsController.userIDs
for user in response.value {
guard !userIDs.contains(user.id) else { continue }
userIDs.append(user.id)
hasNewAppend = true
}
let maxID = response.link?.maxID
if hasNewAppend, maxID != nil {
await enter(state: Idle.self)
} else {
await enter(state: NoMore.self)
}
self.maxID = maxID
viewModel.userFetchedResultsController.userIDs = userIDs
} catch {
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch following fail: \(error.localizedDescription)")
await enter(state: Fail.self)
}
} // end Task
} // end func didEnter
}
class NoMore: UserListViewModel.State {
override func isValidNextState(_ stateClass: AnyClass) -> Bool {
switch stateClass {
case is Reloading.Type:
return true
default:
return false
}
}
override func didEnter(from previousState: GKState?) {
super.didEnter(from: previousState)
guard let viewModel = viewModel else { return }
// trigger reload
viewModel.userFetchedResultsController.records = viewModel.userFetchedResultsController.records
}
}
}

View File

@ -0,0 +1,66 @@
//
// UserListViewModel.swift
// Mastodon
//
// Created by MainasuK on 2022-5-17.
//
import os.log
import UIKit
import Combine
import CoreDataStack
import GameplayKit
final class UserListViewModel {
let logger = Logger(subsystem: "UserListViewModel", category: "ViewModel")
var disposeBag = Set<AnyCancellable>()
// input
let context: AppContext
let kind: Kind
let userFetchedResultsController: UserFetchedResultsController
let listBatchFetchViewModel = ListBatchFetchViewModel()
// output
var diffableDataSource: UITableViewDiffableDataSource<UserSection, UserItem>!
@MainActor private(set) lazy var stateMachine: GKStateMachine = {
let stateMachine = GKStateMachine(states: [
State.Initial(viewModel: self),
State.Fail(viewModel: self),
State.Idle(viewModel: self),
State.Loading(viewModel: self),
State.NoMore(viewModel: self),
])
stateMachine.enter(State.Initial.self)
return stateMachine
}()
init(
context: AppContext,
kind: Kind
) {
self.context = context
self.kind = kind
self.userFetchedResultsController = UserFetchedResultsController(
managedObjectContext: context.managedObjectContext,
domain: nil,
additionalPredicate: nil
)
// end init
context.authenticationService.activeMastodonAuthenticationBox
.map { $0?.domain }
.assign(to: \.domain, on: userFetchedResultsController)
.store(in: &disposeBag)
}
}
extension UserListViewModel {
// TODO: refactor follower and following into user list
enum Kind {
case rebloggedBy(status: ManagedObjectRecord<Status>)
case favoritedBy(status: ManagedObjectRecord<Status>)
}
}

View File

@ -120,26 +120,15 @@ extension ReportViewController: ReportReasonViewControllerDelegate {
// MARK: - ReportServerRulesViewControllerDelegate
extension ReportViewController: ReportServerRulesViewControllerDelegate {
func reportServerRulesViewController(_ viewController: ReportServerRulesViewController, nextButtonPressed button: UIButton) {
if viewController.viewModel.isDislike {
let reportResultViewModel = ReportResultViewModel(
context: context,
user: viewModel.user,
isReported: false
)
coordinator.present(
scene: .reportResult(viewModel: reportResultViewModel),
from: self,
transition: .show
)
} else if viewController.viewModel.selectRule != nil {
coordinator.present(
scene: .reportStatus(viewModel: viewModel.reportStatusViewModel),
from: self,
transition: .show
)
} else {
assertionFailure()
guard !viewController.viewModel.selectRules.isEmpty else {
return
}
coordinator.present(
scene: .reportStatus(viewModel: viewModel.reportStatusViewModel),
from: self,
transition: .show
)
}
}

View File

@ -125,41 +125,12 @@ extension ReportViewModel {
// the user comment is essential step in report flow
// only check isSkip or not
let comment: String? = {
var suffixes: [String] = []
let content: String?
// the server rules is NOT essential step in report flow
// append suffix depends which reason
if let reason = self.reportReasonViewModel.selectReason {
switch reason {
case .spam:
suffixes.append(reason.rawValue)
case .violateRule:
suffixes.append(reason.rawValue)
if let rule = self.reportServerRulesViewModel.selectRule {
suffixes.append(rule.text)
} else {
assertionFailure("should select valid rule")
}
case .dislike:
assertionFailure("should not enter the report flow")
case .other:
break
}
let _comment = self.reportSupplementaryViewModel.isSkip ? nil : self.reportSupplementaryViewModel.commentContext.comment
if let comment = _comment, !comment.isEmpty {
return comment
} else {
return nil
}
content = self.reportSupplementaryViewModel.isSkip ? nil : self.reportSupplementaryViewModel.commentContext.comment
let suffix: String? = {
let text = suffixes.joined(separator: ". ")
guard !text.isEmpty else { return nil }
return "<" + text + ">"
}()
let comment = [content, suffix]
.compactMap { $0 }
.joined(separator: " ")
return comment.isEmpty ? nil : comment
}()
return Mastodon.API.Reports.FileReportQuery(
accountID: user.id,
@ -178,8 +149,8 @@ extension ReportViewModel {
ruleIDs: {
switch self.reportReasonViewModel.selectReason {
case .violateRule:
guard let rule = self.reportServerRulesViewModel.selectRule else { return nil }
return [rule.id]
let ruleIDs = self.reportServerRulesViewModel.selectRules.map { $0.id }.sorted()
return ruleIDs
default:
return nil
}

View File

@ -41,9 +41,7 @@ struct ReportReasonView: View {
EmptyView()
default:
ReportReasonRowView(reason: reason, isSelect: reason == viewModel.selectReason)
.background(
Color(viewModel.backgroundColor)
)
.contentShape(Rectangle())
.onTapGesture {
viewModel.selectReason = reason
}

View File

@ -51,7 +51,7 @@ struct ReportResultView: View {
.font(Font(UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 28, weight: .bold)) as CTFont))
if viewModel.isReported {
avatarView
Text(verbatim: "While we review this, you can take action against @\(viewModel.username)")
Text(verbatim: L10n.Scene.Report.StepFinal.whileWeReviewThisYouCanTakeActionAgainstUser("@\(viewModel.username)"))
.foregroundColor(Color(Asset.Colors.Label.secondary.color))
.font(Font(UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 17, weight: .regular)) as CTFont))
} else {
@ -74,7 +74,7 @@ struct ReportResultView: View {
action: {
viewModel.followActionPublisher.send()
},
title: viewModel.relationshipViewModel.isFollowing ? "Unfollow" : "Unfollowed",
title: viewModel.relationshipViewModel.isFollowing ? L10n.Scene.Report.StepFinal.unfollow : L10n.Scene.Report.StepFinal.unfollowed,
isBusy: viewModel.isRequestFollow
)
}
@ -138,14 +138,15 @@ struct ReportActionButton: View {
ZStack {
ProgressView()
.opacity(isBusy ? 1 : 0)
.progressViewStyle(CircularProgressViewStyle(tint: .gray))
Text(title)
.font(.headline)
.foregroundColor(Color(Asset.Colors.Label.primary.color))
.foregroundColor(Color(UIColor.black))
.opacity(isBusy ? 0 : 1)
}
.frame(maxWidth: .infinity)
.padding()
.background(Color(UIColor.systemBackground))
.background(Color(UIColor.white)) // using white for Light & Dark
.cornerRadius(10)
.shadow(color: .black.opacity(0.1), radius: 2, x: 0, y: 1)
}

View File

@ -37,27 +37,19 @@ struct ReportServerRulesView: View {
ForEach(viewModel.serverRules, id: \.self) { rule in
ReportServerRulesRowView(
title: rule.text,
isSelect: rule == viewModel.selectRule
isSelect: viewModel.selectRules.contains(rule)
)
.background(
Color(viewModel.backgroundColor)
)
.onTapGesture {
viewModel.selectRule = rule
viewModel.isDislike = false
if viewModel.selectRules.contains(rule) {
viewModel.selectRules.remove(rule)
} else {
viewModel.selectRules.insert(rule)
}
}
}
ReportServerRulesRowView(
title: L10n.Scene.Report.StepTwo.iJustDonTLikeIt,
isSelect: viewModel.isDislike
)
.background(
Color(viewModel.backgroundColor)
)
.onTapGesture {
viewModel.selectRule = nil
viewModel.isDislike = true
}
}
.padding()
.transition(.opacity)
@ -80,7 +72,7 @@ struct ReportServerRulesRowView: View {
var body: some View {
HStack(spacing: 14) {
Image(systemName: isSelect ? "checkmark.circle.fill" : "circle")
Image(systemName: isSelect ? "checkmark.square.fill" : "square")
.resizable()
.frame(width: 28, height: 28, alignment: .center)
VStack(alignment: .leading, spacing: 4) {

View File

@ -88,13 +88,10 @@ extension ReportServerRulesViewController {
}
.store(in: &observations)
Publishers.CombineLatest(
viewModel.$selectRule,
viewModel.$isDislike
)
.map { $0 != nil || $1 }
.assign(to: \.isEnabled, on: navigationActionView.nextButton)
.store(in: &disposeBag)
viewModel.$selectRules
.map { !$0.isEmpty }
.assign(to: \.isEnabled, on: navigationActionView.nextButton)
.store(in: &disposeBag)
navigationActionView.nextButton.addTarget(self, action: #selector(ReportServerRulesViewController.nextButtonPressed(_:)), for: .touchUpInside)
}

View File

@ -25,8 +25,7 @@ final class ReportServerRulesViewModel: ObservableObject {
@Published var backgroundColor: UIColor = Asset.Scene.Report.background.color
// output
@Published var selectRule: Mastodon.Entity.Instance.Rule?
@Published var isDislike: Bool = false
@Published var selectRules: Set<Mastodon.Entity.Instance.Rule> = Set()
init(context: AppContext) {
self.context = context

View File

@ -86,15 +86,17 @@ extension ReportStatusTableViewCell {
separatorLine.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
separatorLine.heightAnchor.constraint(equalToConstant: UIView.separatorLineHeight(of: contentView)).priority(.required - 1),
])
statusView.isUserInteractionEnabled = false
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if selected {
checkbox.image = UIImage(systemName: "checkmark.circle.fill")
checkbox.image = UIImage(systemName: "checkmark.square.fill")
checkbox.tintColor = Asset.Colors.Label.primary.color
} else {
checkbox.image = UIImage(systemName: "circle")
checkbox.image = UIImage(systemName: "square")
checkbox.tintColor = Asset.Colors.Label.secondary.color
}
}

View File

@ -34,6 +34,8 @@ protocol StatusTableViewCellDelegate: AnyObject, AutoGenerateProtocolDelegate {
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, menuButton button: UIButton, didSelectAction action: MastodonMenu.Action)
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView)
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaSensitiveButtonDidPressed button: UIButton)
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton)
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton)
func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, accessibilityActivate: Void)
// sourcery:end
}
@ -87,6 +89,14 @@ extension StatusViewDelegate where Self: StatusViewContainerTableViewCell {
delegate?.tableViewCell(self, statusView: statusView, mediaGridContainerView: mediaGridContainerView, mediaSensitiveButtonDidPressed: button)
}
func statusView(_ statusView: StatusView, statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton) {
delegate?.tableViewCell(self, statusView: statusView, statusMetricView: statusMetricView, reblogButtonDidPressed: button)
}
func statusView(_ statusView: StatusView, statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton) {
delegate?.tableViewCell(self, statusView: statusView, statusMetricView: statusMetricView, favoriteButtonDidPressed: button)
}
func statusView(_ statusView: StatusView, accessibilityActivate: Void) {
delegate?.tableViewCell(self, statusView: statusView, accessibilityActivate: accessibilityActivate)
}

Some files were not shown because too many files have changed in this diff Show More