Merge branch 'develop' into kb/refresh-control-z-index

* develop: (224 commits)
  Fix build
  feat: improve the i18n workflow
  chore: update SwiftGen to the latest version
  chore: code clean
  chore: Move updateActiveUserAccountPublisher to AuthenticationService
  Fix authenticated user account not reloaded
  feat: restore keyboard shortcut for compose scene
  feat: update i18n string
  chore: update i18n resources
  feat: restore post compose limit
  fix: iPad navigation bar still could be large title issue
  feat: add throttle for post compose auto-complete query
  fix: visibility missing bind back to source issue
  Update Localization/app.json
  New translations app.json (Galician)
  New translations Intents.strings (Portuguese, Brazilian)
  New translations app.json (Portuguese, Brazilian)
  New translations Intents.stringsdict (Portuguese, Brazilian)
  New translations ios-infoPlist.json (Portuguese, Brazilian)
  New translations app.json (Portuguese, Brazilian)
  ...
This commit is contained in:
Kyle Bashour 2022-11-14 14:21:16 -08:00
commit 754cc10d8c
200 changed files with 7672 additions and 6642 deletions

View File

@ -68,6 +68,28 @@
<string>%ld characters</string>
</dict>
</dict>
<key>a11y.plural.count.characters_left</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@character_count@ left</string>
<key>character_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>no characters</string>
<key>one</key>
<string>1 character</string>
<key>few</key>
<string>%ld characters</string>
<key>many</key>
<string>%ld characters</string>
<key>other</key>
<string>%ld characters</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -1,51 +1,51 @@
"16wxgf" = "Post on Mastodon";
"16wxgf" = "Příspěvek na Mastodon";
"751xkl" = "Text Content";
"751xkl" = "Textový obsah";
"CsR7G2" = "Post on Mastodon";
"CsR7G2" = "Příspěvek na Mastodon";
"HZSGTr" = "What content to post?";
"HZSGTr" = "Jaký obsah se má přidat?";
"HdGikU" = "Posting failed";
"HdGikU" = "Odeslání se nezdařilo";
"KDNTJ4" = "Failure Reason";
"KDNTJ4" = "Důvod selhání";
"RHxKOw" = "Send Post with text content";
"RHxKOw" = "Odeslat příspěvek s textovým obsahem";
"RxSqsb" = "Post";
"RxSqsb" = "Příspěvek";
"WCIR3D" = "Post ${content} on Mastodon";
"WCIR3D" = "Zveřejnit ${content} na Mastodon";
"ZKJSNu" = "Post";
"ZKJSNu" = "Příspěvek";
"ZS1XaK" = "${content}";
"ZbSjzC" = "Visibility";
"ZbSjzC" = "Viditelnost";
"Zo4jgJ" = "Post Visibility";
"Zo4jgJ" = "Viditelnost příspěvku";
"apSxMG-dYQ5NN" = "There are ${count} options matching Public.";
"apSxMG-dYQ5NN" = "Existuje ${count} možností odpovídajících 'Veřejný'.";
"apSxMG-ehFLjY" = "There are ${count} options matching Followers Only.";
"apSxMG-ehFLjY" = "Existuje ${count} možností, které odpovídají „jen sledujícím“.";
"ayoYEb-dYQ5NN" = "${content}, Public";
"ayoYEb-dYQ5NN" = "${content}, veřejné";
"ayoYEb-ehFLjY" = "${content}, Followers Only";
"ayoYEb-ehFLjY" = "${content}, pouze sledující";
"dUyuGg" = "Post on Mastodon";
"dUyuGg" = "Příspěvek na Mastodon";
"dYQ5NN" = "Public";
"dYQ5NN" = "Veřejný";
"ehFLjY" = "Followers Only";
"ehFLjY" = "Pouze sledující";
"gfePDu" = "Posting failed. ${failureReason}";
"gfePDu" = "Odeslání se nezdařilo. ${failureReason}";
"k7dbKQ" = "Post was sent successfully.";
"k7dbKQ" = "Příspěvek byl úspěšně odeslán.";
"oGiqmY-dYQ5NN" = "Just to confirm, you wanted Public?";
"oGiqmY-dYQ5NN" = "Jen pro kontrolu, chtěli jste „Veřejný“?";
"oGiqmY-ehFLjY" = "Just to confirm, you wanted Followers Only?";
"oGiqmY-ehFLjY" = "Jen pro kontrolu, chtěli jste „Pouze sledující“?";
"rM6dvp" = "URL";
"ryJLwG" = "Post was sent successfully. ";
"ryJLwG" = "Příspěvek byl úspěšně odeslán. ";

View File

@ -5,7 +5,7 @@
<key>There are ${count} options matching ${content}. - 2</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>There are %#@count_option@ matching ${content}.</string>
<string>Existuje %#@count_option@ odpovídající „${content}“.</string>
<key>count_option</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>

View File

@ -1,26 +1,26 @@
"16wxgf" = "Post on Mastodon";
"16wxgf" = "Postar no Mastodon";
"751xkl" = "Text Content";
"751xkl" = "Conteúdo do texto";
"CsR7G2" = "Post on Mastodon";
"CsR7G2" = "Postar no Mastodon";
"HZSGTr" = "What content to post?";
"HdGikU" = "Posting failed";
"KDNTJ4" = "Failure Reason";
"KDNTJ4" = "Motivo da falha";
"RHxKOw" = "Send Post with text content";
"RHxKOw" = "Enviar postagem com conteúdo de texto";
"RxSqsb" = "Post";
"RxSqsb" = "Postagem";
"WCIR3D" = "Post ${content} on Mastodon";
"WCIR3D" = "Postar ${content} no Mastodon";
"ZKJSNu" = "Post";
"ZKJSNu" = "Postar";
"ZS1XaK" = "${content}";
"ZbSjzC" = "Visibility";
"ZbSjzC" = "Visibilidade";
"Zo4jgJ" = "Post Visibility";

View File

@ -5,7 +5,7 @@
<key>There are ${count} options matching ${content}. - 2</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>There are %#@count_option@ matching ${content}.</string>
<string>Existem %#@count_option@ opções correspondentes a ${content}.</string>
<key>count_option</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
@ -13,15 +13,15 @@
<key>NSStringFormatValueTypeKey</key>
<string>%ld</string>
<key>one</key>
<string>1 option</string>
<string>1 opção</string>
<key>other</key>
<string>%ld options</string>
<string>%ld opções</string>
</dict>
</dict>
<key>There are ${count} options matching ${visibility}.</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>There are %#@count_option@ matching ${visibility}.</string>
<string>Existem %#@count_option@ opções correspondentes a ${visibility}.</string>
<key>count_option</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
@ -29,9 +29,9 @@
<key>NSStringFormatValueTypeKey</key>
<string>%ld</string>
<key>one</key>
<string>1 option</string>
<string>1 opção</string>
<key>other</key>
<string>%ld options</string>
<string>%ld opções</string>
</dict>
</dict>
</dict>

View File

@ -47,6 +47,7 @@ private func convert(from inputDirectoryURL: URL, to outputDirectory: URL) {
private func map(language: String) -> String? {
switch language {
case "Base.lproj": return "Base"
case "ar.lproj": return "ar" // Arabic
case "eu.lproj": return "eu" // Basque
case "ca.lproj": return "ca" // Catalan

View File

@ -0,0 +1,631 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>a11y.plural.count.unread.notification</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@notification_count_unread_notification@</string>
<key>notification_count_unread_notification</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>no unread notification</string>
<key>one</key>
<string>1 unread notification</string>
<key>few</key>
<string>%ld unread notifications</string>
<key>many</key>
<string>%ld unread notification</string>
<key>other</key>
<string>%ld unread notification</string>
</dict>
</dict>
<key>a11y.plural.count.input_limit_exceeds</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Input limit exceeds %#@character_count@</string>
<key>character_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 characters</string>
<key>one</key>
<string>1 character</string>
<key>few</key>
<string>%ld characters</string>
<key>many</key>
<string>%ld characters</string>
<key>other</key>
<string>%ld characters</string>
</dict>
</dict>
<key>a11y.plural.count.input_limit_remains</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Input limit remains %#@character_count@</string>
<key>character_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 characters</string>
<key>one</key>
<string>1 character</string>
<key>few</key>
<string>%ld characters</string>
<key>many</key>
<string>%ld characters</string>
<key>other</key>
<string>%ld characters</string>
</dict>
</dict>
<key>a11y.plural.count.characters_left</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@character_count@ left</string>
<key>character_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>no characters</string>
<key>one</key>
<string>1 character</string>
<key>few</key>
<string>%ld characters</string>
<key>many</key>
<string>%ld characters</string>
<key>other</key>
<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>zero</key>
<string>Followed by %1$@</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</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>
<string>%@ %#@post_count@</string>
<key>post_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>posts</string>
<key>one</key>
<string>post</string>
<key>few</key>
<string>posts</string>
<key>many</key>
<string>posts</string>
<key>other</key>
<string>posts</string>
</dict>
</dict>
<key>plural.count.media</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@media_count@</string>
<key>media_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 media</string>
<key>one</key>
<string>1 media</string>
<key>few</key>
<string>%ld media</string>
<key>many</key>
<string>%ld media</string>
<key>other</key>
<string>%ld media</string>
</dict>
</dict>
<key>plural.count.post</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@post_count@</string>
<key>post_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 posts</string>
<key>one</key>
<string>1 post</string>
<key>few</key>
<string>%ld posts</string>
<key>many</key>
<string>%ld posts</string>
<key>other</key>
<string>%ld posts</string>
</dict>
</dict>
<key>plural.count.favorite</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@favorite_count@</string>
<key>favorite_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 favorites</string>
<key>one</key>
<string>1 favorite</string>
<key>few</key>
<string>%ld favorites</string>
<key>many</key>
<string>%ld favorites</string>
<key>other</key>
<string>%ld favorites</string>
</dict>
</dict>
<key>plural.count.reblog</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@reblog_count@</string>
<key>reblog_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 reblogs</string>
<key>one</key>
<string>1 reblog</string>
<key>few</key>
<string>%ld reblogs</string>
<key>many</key>
<string>%ld reblogs</string>
<key>other</key>
<string>%ld reblogs</string>
</dict>
</dict>
<key>plural.count.reply</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@reply_count@</string>
<key>reply_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 replies</string>
<key>one</key>
<string>1 reply</string>
<key>few</key>
<string>%ld replies</string>
<key>many</key>
<string>%ld replies</string>
<key>other</key>
<string>%ld replies</string>
</dict>
</dict>
<key>plural.count.vote</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@vote_count@</string>
<key>vote_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 votes</string>
<key>one</key>
<string>1 vote</string>
<key>few</key>
<string>%ld votes</string>
<key>many</key>
<string>%ld votes</string>
<key>other</key>
<string>%ld votes</string>
</dict>
</dict>
<key>plural.count.voter</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@voter_count@</string>
<key>voter_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 voters</string>
<key>one</key>
<string>1 voter</string>
<key>few</key>
<string>%ld voters</string>
<key>many</key>
<string>%ld voters</string>
<key>other</key>
<string>%ld voters</string>
</dict>
</dict>
<key>plural.people_talking</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_people_talking@</string>
<key>count_people_talking</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 people talking</string>
<key>one</key>
<string>1 people talking</string>
<key>few</key>
<string>%ld people talking</string>
<key>many</key>
<string>%ld people talking</string>
<key>other</key>
<string>%ld people talking</string>
</dict>
</dict>
<key>plural.count.following</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_following@</string>
<key>count_following</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 following</string>
<key>one</key>
<string>1 following</string>
<key>few</key>
<string>%ld following</string>
<key>many</key>
<string>%ld following</string>
<key>other</key>
<string>%ld following</string>
</dict>
</dict>
<key>plural.count.follower</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_follower@</string>
<key>count_follower</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 followers</string>
<key>one</key>
<string>1 follower</string>
<key>few</key>
<string>%ld followers</string>
<key>many</key>
<string>%ld followers</string>
<key>other</key>
<string>%ld followers</string>
</dict>
</dict>
<key>date.year.left</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_year_left@</string>
<key>count_year_left</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 years left</string>
<key>one</key>
<string>1 year left</string>
<key>few</key>
<string>%ld years left</string>
<key>many</key>
<string>%ld years left</string>
<key>other</key>
<string>%ld years left</string>
</dict>
</dict>
<key>date.month.left</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_month_left@</string>
<key>count_month_left</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 months left</string>
<key>one</key>
<string>1 months left</string>
<key>few</key>
<string>%ld months left</string>
<key>many</key>
<string>%ld months left</string>
<key>other</key>
<string>%ld months left</string>
</dict>
</dict>
<key>date.day.left</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_day_left@</string>
<key>count_day_left</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 days left</string>
<key>one</key>
<string>1 day left</string>
<key>few</key>
<string>%ld days left</string>
<key>many</key>
<string>%ld days left</string>
<key>other</key>
<string>%ld days left</string>
</dict>
</dict>
<key>date.hour.left</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_hour_left@</string>
<key>count_hour_left</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 hours left</string>
<key>one</key>
<string>1 hour left</string>
<key>few</key>
<string>%ld hours left</string>
<key>many</key>
<string>%ld hours left</string>
<key>other</key>
<string>%ld hours left</string>
</dict>
</dict>
<key>date.minute.left</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_minute_left@</string>
<key>count_minute_left</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 minutes left</string>
<key>one</key>
<string>1 minute left</string>
<key>few</key>
<string>%ld minutes left</string>
<key>many</key>
<string>%ld minutes left</string>
<key>other</key>
<string>%ld minutes left</string>
</dict>
</dict>
<key>date.second.left</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_second_left@</string>
<key>count_second_left</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0 seconds left</string>
<key>one</key>
<string>1 second left</string>
<key>few</key>
<string>%ld seconds left</string>
<key>many</key>
<string>%ld seconds left</string>
<key>other</key>
<string>%ld seconds left</string>
</dict>
</dict>
<key>date.year.ago.abbr</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_year_ago_abbr@</string>
<key>count_year_ago_abbr</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0y ago</string>
<key>one</key>
<string>1y ago</string>
<key>few</key>
<string>%ldy ago</string>
<key>many</key>
<string>%ldy ago</string>
<key>other</key>
<string>%ldy ago</string>
</dict>
</dict>
<key>date.month.ago.abbr</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_month_ago_abbr@</string>
<key>count_month_ago_abbr</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0M ago</string>
<key>one</key>
<string>1M ago</string>
<key>few</key>
<string>%ldM ago</string>
<key>many</key>
<string>%ldM ago</string>
<key>other</key>
<string>%ldM ago</string>
</dict>
</dict>
<key>date.day.ago.abbr</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_day_ago_abbr@</string>
<key>count_day_ago_abbr</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0d ago</string>
<key>one</key>
<string>1d ago</string>
<key>few</key>
<string>%ldd ago</string>
<key>many</key>
<string>%ldd ago</string>
<key>other</key>
<string>%ldd ago</string>
</dict>
</dict>
<key>date.hour.ago.abbr</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_hour_ago_abbr@</string>
<key>count_hour_ago_abbr</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0h ago</string>
<key>one</key>
<string>1h ago</string>
<key>few</key>
<string>%ldh ago</string>
<key>many</key>
<string>%ldh ago</string>
<key>other</key>
<string>%ldh ago</string>
</dict>
</dict>
<key>date.minute.ago.abbr</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_minute_ago_abbr@</string>
<key>count_minute_ago_abbr</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0m ago</string>
<key>one</key>
<string>1m ago</string>
<key>few</key>
<string>%ldm ago</string>
<key>many</key>
<string>%ldm ago</string>
<key>other</key>
<string>%ldm ago</string>
</dict>
</dict>
<key>date.second.ago.abbr</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@count_second_ago_abbr@</string>
<key>count_second_ago_abbr</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>0s ago</string>
<key>one</key>
<string>1s ago</string>
<key>few</key>
<string>%lds ago</string>
<key>many</key>
<string>%lds ago</string>
<key>other</key>
<string>%lds ago</string>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,722 @@
{
"common": {
"alerts": {
"common": {
"please_try_again": "Please try again.",
"please_try_again_later": "Please try again later."
},
"sign_up_failure": {
"title": "Sign Up Failure"
},
"server_error": {
"title": "Server Error"
},
"vote_failure": {
"title": "Vote Failure",
"poll_ended": "The poll has ended"
},
"discard_post_content": {
"title": "Discard Draft",
"message": "Confirm to discard composed post content."
},
"publish_post_failure": {
"title": "Publish Failure",
"message": "Failed to publish the post.\nPlease check your internet connection.",
"attachments_message": {
"video_attach_with_photo": "Cannot attach a video to a post that already contains images.",
"more_than_one_video": "Cannot attach more than one video."
}
},
"edit_profile_failure": {
"title": "Edit Profile Error",
"message": "Cannot edit profile. Please try again."
},
"sign_out": {
"title": "Sign Out",
"message": "Are you sure you want to sign out?",
"confirm": "Sign Out"
},
"block_domain": {
"title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.",
"block_entire_domain": "Block Domain"
},
"save_photo_failure": {
"title": "Save Photo Failure",
"message": "Please enable the photo library access permission to save the photo."
},
"delete_post": {
"title": "Delete Post",
"message": "Are you sure you want to delete this post?"
},
"clean_cache": {
"title": "Clean Cache",
"message": "Successfully cleaned %s cache."
}
},
"controls": {
"actions": {
"back": "Back",
"next": "Next",
"previous": "Previous",
"open": "Open",
"add": "Add",
"remove": "Remove",
"edit": "Edit",
"save": "Save",
"ok": "OK",
"done": "Done",
"confirm": "Confirm",
"continue": "Continue",
"compose": "Compose",
"cancel": "Cancel",
"discard": "Discard",
"try_again": "Try Again",
"take_photo": "Take Photo",
"save_photo": "Save Photo",
"copy_photo": "Copy Photo",
"sign_in": "Sign In",
"sign_up": "Sign Up",
"see_more": "See More",
"preview": "Preview",
"share": "Share",
"share_user": "Share %s",
"share_post": "Share Post",
"open_in_safari": "Open in Safari",
"open_in_browser": "Open in Browser",
"find_people": "Find people to follow",
"manually_search": "Manually search instead",
"skip": "Skip",
"reply": "Reply",
"report_user": "Report %s",
"block_domain": "Block %s",
"unblock_domain": "Unblock %s",
"settings": "Settings",
"delete": "Delete"
},
"tabs": {
"home": "Home",
"search": "Search",
"notification": "Notification",
"profile": "Profile"
},
"keyboard": {
"common": {
"switch_to_tab": "Switch to %s",
"compose_new_post": "Compose New Post",
"show_favorites": "Show Favorites",
"open_settings": "Open Settings"
},
"timeline": {
"previous_status": "Previous Post",
"next_status": "Next Post",
"open_status": "Open Post",
"open_author_profile": "Open Author's Profile",
"open_reblogger_profile": "Open Reblogger's Profile",
"reply_status": "Reply to Post",
"toggle_reblog": "Toggle Reblog on Post",
"toggle_favorite": "Toggle Favorite on Post",
"toggle_content_warning": "Toggle Content Warning",
"preview_image": "Preview Image"
},
"segmented_control": {
"previous_section": "Previous Section",
"next_section": "Next Section"
}
},
"status": {
"user_reblogged": "%s reblogged",
"user_replied_to": "Replied to %s",
"show_post": "Show Post",
"show_user_profile": "Show user profile",
"content_warning": "Content Warning",
"sensitive_content": "Sensitive Content",
"media_content_warning": "Tap anywhere to reveal",
"tap_to_reveal": "Tap to reveal",
"poll": {
"vote": "Vote",
"closed": "Closed"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Reply",
"reblog": "Reblog",
"unreblog": "Undo reblog",
"favorite": "Favorite",
"unfavorite": "Unfavorite",
"menu": "Menu",
"hide": "Hide",
"show_image": "Show image",
"show_gif": "Show GIF",
"show_video_player": "Show video player",
"tap_then_hold_to_show_menu": "Tap then hold to show menu"
},
"tag": {
"url": "URL",
"mention": "Mention",
"link": "Link",
"hashtag": "Hashtag",
"email": "Email",
"emoji": "Emoji"
},
"visibility": {
"unlisted": "Everyone can see this post but not display in the public timeline.",
"private": "Only their followers can see this post.",
"private_from_me": "Only my followers can see this post.",
"direct": "Only mentioned user can see this post."
}
},
"friendship": {
"follow": "Follow",
"following": "Following",
"request": "Request",
"pending": "Pending",
"block": "Block",
"block_user": "Block %s",
"block_domain": "Block %s",
"unblock": "Unblock",
"unblock_user": "Unblock %s",
"blocked": "Blocked",
"mute": "Mute",
"mute_user": "Mute %s",
"unmute": "Unmute",
"unmute_user": "Unmute %s",
"muted": "Muted",
"edit_info": "Edit Info",
"show_reblogs": "Show Reblogs",
"hide_reblogs": "Hide Reblogs"
},
"timeline": {
"filtered": "Filtered",
"timestamp": {
"now": "Now"
},
"loader": {
"load_missing_posts": "Load missing posts",
"loading_missing_posts": "Loading missing posts...",
"show_more_replies": "Show more replies"
},
"header": {
"no_status_found": "No Post Found",
"blocking_warning": "You cant view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.",
"user_blocking_warning": "You cant view %ss profile\nuntil you unblock them.\nYour profile looks like this to them.",
"blocked_warning": "You cant view this users profile\nuntil they unblock you.",
"user_blocked_warning": "You cant view %ss profile\nuntil they unblock you.",
"suspended_warning": "This user has been suspended.",
"user_suspended_warning": "%ss account has been suspended."
}
}
}
},
"scene": {
"welcome": {
"slogan": "Social networking\nback in your hands.",
"get_started": "Get Started",
"log_in": "Log In"
},
"server_picker": {
"title": "Mastodon is made of users in different servers.",
"subtitle": "Pick a server based on your interests, region, or a general purpose one.",
"subtitle_extend": "Pick a server based on your interests, region, or a general purpose one. Each server is operated by an entirely independent organization or individual.",
"button": {
"category": {
"all": "All",
"all_accessiblity_description": "Category: All",
"academia": "academia",
"activism": "activism",
"food": "food",
"furry": "furry",
"games": "games",
"general": "general",
"journalism": "journalism",
"lgbt": "lgbt",
"regional": "regional",
"art": "art",
"music": "music",
"tech": "tech"
},
"see_less": "See Less",
"see_more": "See More"
},
"label": {
"language": "LANGUAGE",
"users": "USERS",
"category": "CATEGORY"
},
"input": {
"placeholder": "Search servers",
"search_servers_or_enter_url": "Search servers or enter URL"
},
"empty_state": {
"finding_servers": "Finding available servers...",
"bad_network": "Something went wrong while loading the data. Check your internet connection.",
"no_results": "No results"
}
},
"register": {
"title": "Lets get you set up on %s",
"lets_get_you_set_up_on_domain": "Lets get you set up on %s",
"input": {
"avatar": {
"delete": "Delete"
},
"username": {
"placeholder": "username",
"duplicate_prompt": "This username is taken."
},
"display_name": {
"placeholder": "display name"
},
"email": {
"placeholder": "email"
},
"password": {
"placeholder": "password",
"require": "Your password needs at least:",
"character_limit": "8 characters",
"accessibility": {
"checked": "checked",
"unchecked": "unchecked"
},
"hint": "Your password needs at least eight characters"
},
"invite": {
"registration_user_invite_request": "Why do you want to join?"
}
},
"error": {
"item": {
"username": "Username",
"email": "Email",
"password": "Password",
"agreement": "Agreement",
"locale": "Locale",
"reason": "Reason"
},
"reason": {
"blocked": "%s contains a disallowed email provider",
"unreachable": "%s does not seem to exist",
"taken": "%s is already in use",
"reserved": "%s is a reserved keyword",
"accepted": "%s must be accepted",
"blank": "%s is required",
"invalid": "%s is invalid",
"too_long": "%s is too long",
"too_short": "%s is too short",
"inclusion": "%s is not a supported value"
},
"special": {
"username_invalid": "Username must only contain alphanumeric characters and underscores",
"username_too_long": "Username is too long (cant be longer than 30 characters)",
"email_invalid": "This is not a valid email address",
"password_too_short": "Password is too short (must be at least 8 characters)"
}
}
},
"server_rules": {
"title": "Some ground rules.",
"subtitle": "These are set and enforced by the %s moderators.",
"prompt": "By continuing, youre subject to the terms of service and privacy policy for %s.",
"terms_of_service": "terms of service",
"privacy_policy": "privacy policy",
"button": {
"confirm": "I Agree"
}
},
"confirm_email": {
"title": "One last thing.",
"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": "Open Email App",
"resend": "Resend"
},
"dont_receive_email": {
"title": "Check your email",
"description": "Check if your email address is correct as well as your junk folder if you havent.",
"resend_email": "Resend Email"
},
"open_email_app": {
"title": "Check your inbox.",
"description": "We just sent you an email. Check your junk folder if you havent.",
"mail": "Mail",
"open_email_client": "Open Email Client"
}
},
"home_timeline": {
"title": "Home",
"navigation_bar_state": {
"offline": "Offline",
"new_posts": "See new posts",
"published": "Published!",
"Publishing": "Publishing post...",
"accessibility": {
"logo_label": "Logo Button",
"logo_hint": "Tap to scroll to top and tap again to previous location"
}
}
},
"suggestion_account": {
"title": "Find People to Follow",
"follow_explain": "When you follow someone, youll see their posts in your home feed."
},
"compose": {
"title": {
"new_post": "New Post",
"new_reply": "New Reply"
},
"media_selection": {
"camera": "Take Photo",
"photo_library": "Photo Library",
"browse": "Browse"
},
"content_input_placeholder": "Type or paste whats on your mind",
"compose_action": "Publish",
"replying_to_user": "replying to %s",
"attachment": {
"photo": "photo",
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not recognize this media attachment",
"attachment_too_large": "Attachment too large",
"compressing_state": "Compressing...",
"server_processing_state": "Server Processing..."
},
"poll": {
"duration_time": "Duration: %s",
"thirty_minutes": "30 minutes",
"one_hour": "1 Hour",
"six_hours": "6 Hours",
"one_day": "1 Day",
"three_days": "3 Days",
"seven_days": "7 Days",
"option_number": "Option %ld",
"the_poll_is_invalid": "The poll is invalid",
"the_poll_has_empty_option": "The poll has empty option"
},
"content_warning": {
"placeholder": "Write an accurate warning here..."
},
"visibility": {
"public": "Public",
"unlisted": "Unlisted",
"private": "Followers only",
"direct": "Only people I mention"
},
"auto_complete": {
"space_to_add": "Space to add"
},
"accessibility": {
"append_attachment": "Add Attachment",
"append_poll": "Add Poll",
"remove_poll": "Remove Poll",
"custom_emoji_picker": "Custom Emoji Picker",
"enable_content_warning": "Enable Content Warning",
"disable_content_warning": "Disable Content Warning",
"post_visibility_menu": "Post Visibility Menu",
"post_options": "Post Options",
"posting_as": "Posting as %s"
},
"keyboard": {
"discard_post": "Discard Post",
"publish_post": "Publish Post",
"toggle_poll": "Toggle Poll",
"toggle_content_warning": "Toggle Content Warning",
"append_attachment_entry": "Add Attachment - %s",
"select_visibility_entry": "Select Visibility - %s"
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "posts",
"following": "following",
"followers": "followers"
},
"fields": {
"add_row": "Add Row",
"placeholder": {
"label": "Label",
"content": "Content"
},
"verified": {
"short": "Verified on %s",
"long": "Ownership of this link was checked on %s"
}
},
"segmented_control": {
"posts": "Posts",
"replies": "Replies",
"posts_and_replies": "Posts and Replies",
"media": "Media",
"about": "About"
},
"relationship_action_alert": {
"confirm_mute_user": {
"title": "Mute Account",
"message": "Confirm to mute %s"
},
"confirm_unmute_user": {
"title": "Unmute Account",
"message": "Confirm to unmute %s"
},
"confirm_block_user": {
"title": "Block Account",
"message": "Confirm to block %s"
},
"confirm_unblock_user": {
"title": "Unblock Account",
"message": "Confirm to unblock %s"
},
"confirm_show_reblogs": {
"title": "Show Reblogs",
"message": "Confirm to show reblogs"
},
"confirm_hide_reblogs": {
"title": "Hide Reblogs",
"message": "Confirm to hide reblogs"
}
},
"accessibility": {
"show_avatar_image": "Show avatar image",
"edit_avatar_image": "Edit avatar image",
"show_banner_image": "Show banner image",
"double_tap_to_open_the_list": "Double tap to open the list"
}
},
"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": {
"placeholder": "Search hashtags and users",
"cancel": "Cancel"
},
"recommend": {
"button_text": "See All",
"hash_tag": {
"title": "Trending on Mastodon",
"description": "Hashtags that are getting quite a bit of attention",
"people_talking": "%s people are talking"
},
"accounts": {
"title": "Accounts you might like",
"description": "You may like to follow these accounts",
"follow": "Follow"
}
},
"searching": {
"segment": {
"all": "All",
"people": "People",
"hashtags": "Hashtags",
"posts": "Posts"
},
"empty_state": {
"no_results": "No results"
},
"recent_search": "Recent searches",
"clear": "Clear"
}
},
"discovery": {
"tabs": {
"posts": "Posts",
"hashtags": "Hashtags",
"news": "News",
"community": "Community",
"for_you": "For You"
},
"intro": "These are the posts gaining traction in your corner of Mastodon."
},
"favorite": {
"title": "Your Favorites"
},
"notification": {
"title": {
"Everything": "Everything",
"Mentions": "Mentions"
},
"notification_description": {
"followed_you": "followed you",
"favorited_your_post": "favorited your post",
"reblogged_your_post": "reblogged your post",
"mentioned_you": "mentioned you",
"request_to_follow_you": "request to follow you",
"poll_has_ended": "poll has ended"
},
"keyobard": {
"show_everything": "Show Everything",
"show_mentions": "Show Mentions"
},
"follow_request": {
"accept": "Accept",
"accepted": "Accepted",
"reject": "reject",
"rejected": "Rejected"
}
},
"thread": {
"back_title": "Post",
"title": "Post from %s"
},
"settings": {
"title": "Settings",
"section": {
"appearance": {
"title": "Appearance",
"automatic": "Automatic",
"light": "Always Light",
"dark": "Always Dark"
},
"look_and_feel": {
"title": "Look and Feel",
"use_system": "Use System",
"really_dark": "Really Dark",
"sorta_dark": "Sorta Dark",
"light": "Light"
},
"notifications": {
"title": "Notifications",
"favorites": "Favorites my post",
"follows": "Follows me",
"boosts": "Reblogs my post",
"mentions": "Mentions me",
"trigger": {
"anyone": "anyone",
"follower": "a follower",
"follow": "anyone I follow",
"noone": "no one",
"title": "Notify me when"
}
},
"preference": {
"title": "Preferences",
"true_black_dark_mode": "True black dark mode",
"disable_avatar_animation": "Disable animated avatars",
"disable_emoji_animation": "Disable animated emojis",
"using_default_browser": "Use default browser to open links",
"open_links_in_mastodon": "Open links in Mastodon"
},
"boring_zone": {
"title": "The Boring Zone",
"account_settings": "Account Settings",
"terms": "Terms of Service",
"privacy": "Privacy Policy"
},
"spicy_zone": {
"title": "The Spicy Zone",
"clear": "Clear Media Cache",
"signout": "Sign Out"
}
},
"footer": {
"mastodon_description": "Mastodon is open source software. You can report issues on GitHub at %s (%s)"
},
"keyboard": {
"close_settings_window": "Close Settings Window"
}
},
"report": {
"title_report": "Report",
"title": "Report %s",
"step1": "Step 1 of 2",
"step2": "Step 2 of 2",
"content1": "Are there any other posts youd like to add to the report?",
"content2": "Is there anything the moderators should know about this report?",
"report_sent_title": "Thanks for reporting, well look into this.",
"send": "Send Report",
"skip_to_send": "Send without comment",
"text_placeholder": "Type or paste additional comments",
"reported": "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_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_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_four": {
"step_4_of_4": "Step 4 of 4",
"is_there_anything_else_we_should_know": "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"
}
},
"preview": {
"keyboard": {
"close_preview": "Close Preview",
"show_next": "Show Next",
"show_previous": "Show Previous"
}
},
"account_list": {
"tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher",
"dismiss_account_switcher": "Dismiss Account Switcher",
"add_account": "Add Account"
},
"wizard": {
"new_in_mastodon": "New in Mastodon",
"multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.",
"accessibility_hint": "Double tap to dismiss this wizard"
},
"bookmark": {
"title": "Bookmarks"
}
}
}

View File

@ -0,0 +1,6 @@
{
"NSCameraUsageDescription": "Used to take photo for post status",
"NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library",
"NewPostShortcutItemTitle": "New Post",
"SearchShortcutItemTitle": "Search"
}

View File

@ -136,6 +136,12 @@
"vote": "صَوِّت",
"closed": "انتهى"
},
"meta_entity": {
"url": "رابِط: %s",
"hashtag": "وَسْم: %s",
"mention": "إظهار المِلف التعريفي: %s",
"email": "عُنوان البريد الإلكتُروني: %s"
},
"actions": {
"reply": "الرَّد",
"reblog": "إعادة النشر",
@ -181,8 +187,8 @@
"unmute_user": "رفع الكتم عن %s",
"muted": "مكتوم",
"edit_info": "تَحريرُ المَعلُومات",
"show_reblogs": "Show Reblogs",
"hide_reblogs": "Hide Reblogs"
"show_reblogs": "إظهار إعادات التدوين",
"hide_reblogs": "إخفاء إعادات التدوين"
},
"timeline": {
"filtered": "مُصفَّى",
@ -376,7 +382,11 @@
"video": "مقطع مرئي",
"attachment_broken": "هذا ال%s مُعطَّل\nويتعذَّرُ رفعُه إلى ماستودون.",
"description_photo": "صِف الصورة للمَكفوفين...",
"description_video": "صِف المقطع المرئي للمَكفوفين..."
"description_video": "صِف المقطع المرئي للمَكفوفين...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "المُدَّة: %s",
@ -459,12 +469,12 @@
"message": "تأكيدُ رَفع الحَظرِ عَن %s"
},
"confirm_show_reblogs": {
"title": "Show Reblogs",
"message": "Confirm to show reblogs"
"title": "إظهار إعادات التدوين",
"message": "التأكيد لِإظهار إعادات التدوين"
},
"confirm_hide_reblogs": {
"title": "Hide Reblogs",
"message": "Confirm to hide reblogs"
"title": "إخفاء إعادات التدوين",
"message": "التأكيد لِإخفاء إعادات التدوين"
}
},
"accessibility": {
@ -696,7 +706,7 @@
"accessibility_hint": "انقر نقرًا مزدوجًا لتجاهُل النافذة المنبثقة"
},
"bookmark": {
"title": "Bookmarks"
"title": "العَلاماتُ المَرجعيَّة"
}
}
}

View File

@ -136,6 +136,12 @@
"vote": "Vota",
"closed": "Finalitzada"
},
"meta_entity": {
"url": "Enllaç: %s",
"hashtag": "Etiqueta %s",
"mention": "Mostra el Perfil: %s",
"email": "Correu electrònic: %s"
},
"actions": {
"reply": "Respon",
"reblog": "Impuls",
@ -376,7 +382,11 @@
"video": "vídeo",
"attachment_broken": "Aquest %s està trencat i no pot ser\ncarregat a Mastodon.",
"description_photo": "Descriu la foto per als disminuïts visuals...",
"description_video": "Descriu el vídeo per als disminuïts visuals..."
"description_video": "Descriu el vídeo per als disminuïts visuals...",
"load_failed": "Ha fallat la càrrega",
"upload_failed": "Pujada fallida",
"can_not_recognize_this_media_attachment": "No es pot reconèixer l'adjunt multimèdia",
"attachment_too_large": "El fitxer adjunt és massa gran"
},
"poll": {
"duration_time": "Durada: %s",
@ -696,7 +706,7 @@
"accessibility_hint": "Toca dues vegades per descartar l'assistent"
},
"bookmark": {
"title": "Bookmarks"
"title": "Marcadors"
}
}
}

View File

@ -136,6 +136,12 @@
"vote": "دەنگ بدە",
"closed": "داخراوە"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "وەڵامی بدەوە",
"reblog": "پۆستی بکەوە",
@ -376,7 +382,11 @@
"video": "ڤیدیۆ",
"attachment_broken": "ئەم %sـە تێک چووە و ناتوانیت بەرزی بکەیتەوە.",
"description_photo": "وێنەکەت بۆ نابیناکان باس بکە...",
"description_video": "ڤیدیۆکەت بۆ نابیناکان باس بکە..."
"description_video": "ڤیدیۆکەت بۆ نابیناکان باس بکە...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "کات: %s",

View File

@ -13,19 +13,19 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 unread notification</string>
<string>1 nepřečtené oznámení</string>
<key>few</key>
<string>%ld unread notification</string>
<string>%ld nepřečtené oznámení</string>
<key>many</key>
<string>%ld unread notification</string>
<string>%ld nepřečtených oznámení</string>
<key>other</key>
<string>%ld unread notification</string>
<string>%ld nepřečtených oznámení</string>
</dict>
</dict>
<key>a11y.plural.count.input_limit_exceeds</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Input limit exceeds %#@character_count@</string>
<string>Vstupní limit přesahuje %#@character_count@</string>
<key>character_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
@ -33,19 +33,19 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 character</string>
<string>1 znak</string>
<key>few</key>
<string>%ld characters</string>
<string>%ld znaky</string>
<key>many</key>
<string>%ld characters</string>
<string>%ld znaků</string>
<key>other</key>
<string>%ld characters</string>
<string>%ld znaků</string>
</dict>
</dict>
<key>a11y.plural.count.input_limit_remains</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>Input limit remains %#@character_count@</string>
<string>Vstupní limit zůstává %#@character_count@</string>
<key>character_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
@ -53,13 +53,13 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 character</string>
<string>1 znak</string>
<key>few</key>
<string>%ld characters</string>
<string>%ld znaky</string>
<key>many</key>
<string>%ld characters</string>
<string>%ld znaků</string>
<key>other</key>
<string>%ld characters</string>
<string>%ld znaků</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
@ -108,13 +108,13 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>post</string>
<string>příspěvek</string>
<key>few</key>
<string>posts</string>
<string>příspěvky</string>
<key>many</key>
<string>posts</string>
<string>příspěvků</string>
<key>other</key>
<string>posts</string>
<string>příspěvků</string>
</dict>
</dict>
<key>plural.count.media</key>
@ -128,13 +128,13 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 media</string>
<string>1 médium</string>
<key>few</key>
<string>%ld media</string>
<string>%ld média</string>
<key>many</key>
<string>%ld media</string>
<string>%ld médií</string>
<key>other</key>
<string>%ld media</string>
<string>%ld médií</string>
</dict>
</dict>
<key>plural.count.post</key>
@ -148,13 +148,13 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 post</string>
<string>1 příspěvek</string>
<key>few</key>
<string>%ld posts</string>
<string>%ld příspěvky</string>
<key>many</key>
<string>%ld posts</string>
<string>%ld příspěvků</string>
<key>other</key>
<string>%ld posts</string>
<string>%ld příspěvků</string>
</dict>
</dict>
<key>plural.count.favorite</key>
@ -168,7 +168,7 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 favorite</string>
<string>1 oblíbený</string>
<key>few</key>
<string>%ld favorites</string>
<key>many</key>
@ -208,13 +208,13 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 reply</string>
<string>1 odpověď</string>
<key>few</key>
<string>%ld replies</string>
<string>%ld odpovědi</string>
<key>many</key>
<string>%ld replies</string>
<string>%ld odpovědí</string>
<key>other</key>
<string>%ld replies</string>
<string>%ld odpovědí</string>
</dict>
</dict>
<key>plural.count.vote</key>
@ -228,13 +228,13 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 vote</string>
<string>1 hlas</string>
<key>few</key>
<string>%ld votes</string>
<string>%ld hlasy</string>
<key>many</key>
<string>%ld votes</string>
<string>%ld hlasů</string>
<key>other</key>
<string>%ld votes</string>
<string>%ld hlasů</string>
</dict>
</dict>
<key>plural.count.voter</key>
@ -248,13 +248,13 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 voter</string>
<string>1 hlasující</string>
<key>few</key>
<string>%ld voters</string>
<string>%ld hlasující</string>
<key>many</key>
<string>%ld voters</string>
<string>%ld hlasujících</string>
<key>other</key>
<string>%ld voters</string>
<string>%ld hlasujících</string>
</dict>
</dict>
<key>plural.people_talking</key>

View File

@ -37,12 +37,12 @@
"confirm": "Odhlásit se"
},
"block_domain": {
"title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.",
"title": "Opravdu chcete blokovat celou doménu %s? Ve většině případů stačí zablokovat nebo skrýt pár konkrétních uživatelů, což také doporučujeme. Z této domény neuvidíte obsah v žádné veřejné časové ose ani v oznámeních. Vaši sledující z této domény budou odstraněni.",
"block_entire_domain": "Blokovat doménu"
},
"save_photo_failure": {
"title": "Uložení fotografie se nezdařilo",
"message": "Please enable the photo library access permission to save the photo."
"message": "Pro uložení fotografie povolte přístup k knihovně fotografií."
},
"delete_post": {
"title": "Odstranit příspěvek",
@ -79,7 +79,7 @@
"see_more": "Zobrazit více",
"preview": "Náhled",
"share": "Sdílet",
"share_user": "Share %s",
"share_user": "Sdílet %s",
"share_post": "Sdílet příspěvek",
"open_in_safari": "Otevřít v Safari",
"open_in_browser": "Otevřít v prohlížeči",
@ -125,7 +125,7 @@
},
"status": {
"user_reblogged": "%s reblogged",
"user_replied_to": "Replied to %s",
"user_replied_to": "Odpověděl %s",
"show_post": "Zobrazit příspěvek",
"show_user_profile": "Zobrazit profil uživatele",
"content_warning": "Varování o obsahu",
@ -136,18 +136,24 @@
"vote": "Hlasovat",
"closed": "Uzavřeno"
},
"meta_entity": {
"url": "Odkaz: %s",
"hashtag": "Hashtag: %s",
"mention": "Zobrazit profil: %s",
"email": "E-mailová adresa: %s"
},
"actions": {
"reply": "Odpovědět",
"reblog": "Boostnout",
"unreblog": "Undo reblog",
"favorite": "Favorite",
"favorite": "Oblíbit",
"unfavorite": "Odebrat z oblízených",
"menu": "Nabídka",
"hide": "Skrýt",
"show_image": "Zobrazit obrázek",
"show_gif": "Zobrazit GIF",
"show_video_player": "Zobrazit video přehrávač",
"tap_then_hold_to_show_menu": "Tap then hold to show menu"
"tap_then_hold_to_show_menu": "Klepnutím podržte pro zobrazení nabídky"
},
"tag": {
"url": "URL",
@ -159,22 +165,22 @@
},
"visibility": {
"unlisted": "Každý může vidět tento příspěvek, ale nezobrazovat ve veřejné časové ose.",
"private": "Only their followers can see this post.",
"private_from_me": "Only my followers can see this post.",
"direct": "Only mentioned user can see this post."
"private": "Pouze jejich sledující mohou vidět tento příspěvek.",
"private_from_me": "Pouze moji sledující mohou vidět tento příspěvek.",
"direct": "Pouze zmíněný uživatel může vidět tento příspěvek."
}
},
"friendship": {
"follow": "Sledovat",
"following": "Following",
"request": "Request",
"following": "Sleduji",
"request": "Požadavek",
"pending": "Čekající",
"block": "Blokovat",
"block_user": "Blokovat %s",
"block_domain": "Blokovat %s",
"unblock": "Odblokovat",
"unblock_user": "Odblokovat %s",
"blocked": "Blocked",
"blocked": "Blokovaný",
"mute": "Skrýt",
"mute_user": "Skrýt %s",
"unmute": "Odkrýt",
@ -185,7 +191,7 @@
"hide_reblogs": "Hide Reblogs"
},
"timeline": {
"filtered": "Filtered",
"filtered": "Filtrováno",
"timestamp": {
"now": "Nyní"
},
@ -196,26 +202,26 @@
},
"header": {
"no_status_found": "Nebyl nalezen žádný příspěvek",
"blocking_warning": "You cant view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.",
"user_blocking_warning": "You cant view %ss profile\nuntil you unblock them.\nYour profile looks like this to them.",
"blocked_warning": "You cant view this users profile\nuntil they unblock you.",
"user_blocked_warning": "You cant view %ss profile\nuntil they unblock you.",
"suspended_warning": "This user has been suspended.",
"user_suspended_warning": "%ss account has been suspended."
"blocking_warning": "Nemůžete zobrazit profil tohoto uživatele, dokud ho neodblokujete.\nVáš profil pro něj vypadá takto.",
"user_blocking_warning": "Nemůžete zobrazit profil %s, dokud ho neodblokujete.\nVáš profil pro něj vypadá takto.",
"blocked_warning": "Nemůžeš zobrazit profil tohoto uživatele, dokud tě neodblokují.",
"user_blocked_warning": "Nemůžete zobrazit profil %s, dokud vás neodblokuje.",
"suspended_warning": "Tento uživatel byl pozastaven.",
"user_suspended_warning": "Účet %s byl pozastaven."
}
}
}
},
"scene": {
"welcome": {
"slogan": "Social networking\nback in your hands.",
"slogan": "Sociální sítě opět ve vašich rukou.",
"get_started": "Začínáme",
"log_in": "Přihlásit se"
},
"server_picker": {
"title": "Mastodon tvoří uživatelé z různých serverů.",
"subtitle": "Pick a server based on your interests, region, or a general purpose one.",
"subtitle_extend": "Pick a server based on your interests, region, or a general purpose one. Each server is operated by an entirely independent organization or individual.",
"subtitle": "Vyberte server založený na vašich zájmech, regionu nebo obecném účelu.",
"subtitle_extend": "Vyberte server založený na vašich zájmech, regionu nebo obecném účelu. Každý server je provozován zcela nezávislou organizací nebo jednotlivcem.",
"button": {
"category": {
"all": "Vše",
@ -224,7 +230,7 @@
"activism": "aktivismus",
"food": "jídlo",
"furry": "furry",
"games": "games",
"games": "hry",
"general": "obecné",
"journalism": "žurnalistika",
"lgbt": "lgbt",
@ -252,8 +258,8 @@
}
},
"register": {
"title": "Lets get you set up on %s",
"lets_get_you_set_up_on_domain": "Lets get you set up on %s",
"title": "Pojďme si nastavit %s",
"lets_get_you_set_up_on_domain": "Pojďme si nastavit %s",
"input": {
"avatar": {
"delete": "Smazat"
@ -292,51 +298,51 @@
"reason": "Důvod"
},
"reason": {
"blocked": "%s contains a disallowed email provider",
"unreachable": "%s does not seem to exist",
"blocked": "%s používá zakázanou e-mailovou službu",
"unreachable": "%s pravděpodobně neexistuje",
"taken": "%s se již používá",
"reserved": "%s je rezervované klíčové slovo",
"accepted": "%s musí být přijato",
"blank": "%s je vyžadováno",
"invalid": "%s is invalid",
"too_long": "%s is too long",
"too_short": "%s is too short",
"inclusion": "%s is not a supported value"
"invalid": "%s je neplatné",
"too_long": "%s je příliš dlouhé",
"too_short": "%s je příliš krátké",
"inclusion": "%s není podporovaná hodnota"
},
"special": {
"username_invalid": "Username must only contain alphanumeric characters and underscores",
"username_too_long": "Username is too long (cant be longer than 30 characters)",
"username_invalid": "Uživatelské jméno musí obsahovat pouze alfanumerické znaky a podtržítka",
"username_too_long": "Uživatelské jméno je příliš dlouhé (nemůže být delší než 30 znaků)",
"email_invalid": "Toto není platná e-mailová adresa",
"password_too_short": "Password is too short (must be at least 8 characters)"
"password_too_short": "Heslo je příliš krátké (musí mít alespoň 8 znaků)"
}
}
},
"server_rules": {
"title": "Some ground rules.",
"subtitle": "These are set and enforced by the %s moderators.",
"prompt": "By continuing, youre subject to the terms of service and privacy policy for %s.",
"terms_of_service": "terms of service",
"privacy_policy": "privacy policy",
"title": "Některá základní pravidla.",
"subtitle": "Ty nastavují a prosazují moderátoři %s.",
"prompt": "Pokračováním budete podléhat podmínkám služby a zásad ochrany osobních údajů pro uživatele %s.",
"terms_of_service": "podmínky služby",
"privacy_policy": "zásady ochrany osobních údajů",
"button": {
"confirm": "I Agree"
"confirm": "Souhlasím"
}
},
"confirm_email": {
"title": "One last thing.",
"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",
"title": "Ještě jedna věc.",
"subtitle": "Klepněte na odkaz, který jsme vám poslali e-mailem, abyste ověřili Váš účet.",
"tap_the_link_we_emailed_to_you_to_verify_your_account": "Klepněte na odkaz, který jsme vám poslali e-mailem, abyste ověřili Váš účet",
"button": {
"open_email_app": "Open Email App",
"resend": "Resend"
"open_email_app": "Otevřít e-mailovou aplikaci",
"resend": "Poslat znovu"
},
"dont_receive_email": {
"title": "Check your email",
"description": "Check if your email address is correct as well as your junk folder if you havent.",
"resend_email": "Resend Email"
"title": "Zkontrolujte svůj e-mail",
"description": "Zkontrolujte, zda je vaše e-mailová adresa správná, stejně jako složka nevyžádané pošty, pokud ji máte.",
"resend_email": "Znovu odeslat e-mail"
},
"open_email_app": {
"title": "Check your inbox.",
"description": "We just sent you an email. Check your junk folder if you havent.",
"title": "Zkontrolujte doručenou poštu.",
"description": "Právě jsme vám poslali e-mail. Zkontrolujte složku nevyžádané zprávy, pokud ji máte.",
"mail": "Pošta",
"open_email_client": "Otevřít e-mailového klienta"
}
@ -349,37 +355,41 @@
"published": "Publikováno!",
"Publishing": "Publikování příspěvku...",
"accessibility": {
"logo_label": "Logo Button",
"logo_hint": "Tap to scroll to top and tap again to previous location"
"logo_label": "Tlačítko s logem",
"logo_hint": "Klepnutím přejdete nahoru a znovu klepněte na předchozí místo"
}
}
},
"suggestion_account": {
"title": "Find People to Follow",
"follow_explain": "When you follow someone, youll see their posts in your home feed."
"title": "Najít lidi pro sledování",
"follow_explain": "Když někoho sledujete, uvidíte jejich příspěvky ve vašem domovském kanálu."
},
"compose": {
"title": {
"new_post": "Nový příspěvek",
"new_reply": "New Reply"
"new_reply": "Nová odpověď"
},
"media_selection": {
"camera": "Take Photo",
"photo_library": "Photo Library",
"browse": "Browse"
"camera": "Vyfotit",
"photo_library": "Knihovna fotografií",
"browse": "Procházet"
},
"content_input_placeholder": "Type or paste whats on your mind",
"compose_action": "Publish",
"replying_to_user": "replying to %s",
"content_input_placeholder": "Napište nebo vložte, co je na mysli",
"compose_action": "Zveřejnit",
"replying_to_user": "odpovídá na %s",
"attachment": {
"photo": "photo",
"photo": "fotka",
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"attachment_broken": "Tento %s je poškozený a nemůže být\nnahrán do Mastodonu.",
"description_photo": "Popište fotografii pro zrakově postižené osoby...",
"description_video": "Popište video pro zrakově postižené...",
"load_failed": "Načtení se nezdařilo",
"upload_failed": "Nahrání selhalo",
"can_not_recognize_this_media_attachment": "Nelze rozpoznat toto medium přílohy",
"attachment_too_large": "Příloha je příliš velká"
},
"poll": {
"duration_time": "Duration: %s",
"duration_time": "Doba trvání: %s",
"thirty_minutes": "30 minut",
"one_hour": "1 hodina",
"six_hours": "6 hodin",
@ -389,7 +399,7 @@
"option_number": "Možnost %ld"
},
"content_warning": {
"placeholder": "Write an accurate warning here..."
"placeholder": "Zde napište přesné varování..."
},
"visibility": {
"public": "Veřejný",
@ -398,7 +408,7 @@
"direct": "Pouze lidé, které zmíním"
},
"auto_complete": {
"space_to_add": "Space to add"
"space_to_add": "Mezera k přidání"
},
"accessibility": {
"append_attachment": "Přidat přílohu",
@ -413,7 +423,7 @@
"discard_post": "Zahodit příspěvek",
"publish_post": "Publikovat příspěvek",
"toggle_poll": "Přepnout anketu",
"toggle_content_warning": "Toggle Content Warning",
"toggle_content_warning": "Přepnout varování obsahu",
"append_attachment_entry": "Přidat přílohu - %s",
"select_visibility_entry": "Vyberte viditelnost - %s"
}
@ -424,13 +434,13 @@
},
"dashboard": {
"posts": "příspěvky",
"following": "following",
"following": "sledování",
"followers": "sledující"
},
"fields": {
"add_row": "Přidat řádek",
"placeholder": {
"label": "Label",
"label": "Označení",
"content": "Obsah"
}
},
@ -439,7 +449,7 @@
"replies": "Odpovědí",
"posts_and_replies": "Příspěvky a odpovědi",
"media": "Média",
"about": "About"
"about": "O uživateli"
},
"relationship_action_alert": {
"confirm_mute_user": {
@ -448,7 +458,7 @@
},
"confirm_unmute_user": {
"title": "Zrušit skrytí účtu",
"message": "Confirm to unmute %s"
"message": "Potvrďte zrušení ztlumení %s"
},
"confirm_block_user": {
"title": "Blokovat účet",
@ -456,7 +466,7 @@
},
"confirm_unblock_user": {
"title": "Odblokovat účet",
"message": "Confirm to unblock %s"
"message": "Potvrďte odblokování %s"
},
"confirm_show_reblogs": {
"title": "Show Reblogs",
@ -468,235 +478,235 @@
}
},
"accessibility": {
"show_avatar_image": "Show avatar image",
"edit_avatar_image": "Edit avatar image",
"show_banner_image": "Show banner image",
"double_tap_to_open_the_list": "Double tap to open the list"
"show_avatar_image": "Zobrazit obrázek avataru",
"edit_avatar_image": "Upravit obrázek avataru",
"show_banner_image": "Zobrazit obrázek banneru",
"double_tap_to_open_the_list": "Dvojitým poklepáním otevřete seznam"
}
},
"follower": {
"title": "follower",
"footer": "Followers from other servers are not displayed."
"title": "sledující",
"footer": "Sledující z jiných serverů nejsou zobrazeni."
},
"following": {
"title": "following",
"footer": "Follows from other servers are not displayed."
"title": "sledování",
"footer": "Sledování z jiných serverů není zobrazeno."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
"title": "Sledující, které znáte",
"followed_by_names": "Sledován od %s"
},
"favorited_by": {
"title": "Favorited By"
"title": "Oblíben"
},
"reblogged_by": {
"title": "Reblogged By"
},
"search": {
"title": "Search",
"title": "Hledat",
"search_bar": {
"placeholder": "Search hashtags and users",
"cancel": "Cancel"
"placeholder": "Hledat hashtagy a uživatele",
"cancel": "Zrušit"
},
"recommend": {
"button_text": "See All",
"button_text": "Zobrazit vše",
"hash_tag": {
"title": "Trending on Mastodon",
"description": "Hashtags that are getting quite a bit of attention",
"people_talking": "%s people are talking"
"title": "Populární na Mastodonu",
"description": "Hashtagy, kterým se dostává dosti pozornosti",
"people_talking": "%s lidí mluví"
},
"accounts": {
"title": "Accounts you might like",
"description": "You may like to follow these accounts",
"follow": "Follow"
"title": "Účty, které by se vám mohly líbit",
"description": "Možná budete chtít sledovat tyto účty",
"follow": "Sledovat"
}
},
"searching": {
"segment": {
"all": "All",
"people": "People",
"hashtags": "Hashtags",
"posts": "Posts"
"all": "Vše",
"people": "Lidé",
"hashtags": "Hashtagy",
"posts": "Příspěvky"
},
"empty_state": {
"no_results": "No results"
"no_results": "Žádné výsledky"
},
"recent_search": "Recent searches",
"clear": "Clear"
"recent_search": "Nedávná hledání",
"clear": "Vymazat"
}
},
"discovery": {
"tabs": {
"posts": "Posts",
"hashtags": "Hashtags",
"news": "News",
"community": "Community",
"for_you": "For You"
"posts": "Příspěvky",
"hashtags": "Hashtagy",
"news": "Zprávy",
"community": "Komunita",
"for_you": "Pro vás"
},
"intro": "These are the posts gaining traction in your corner of Mastodon."
"intro": "Toto jsou příspěvky, které získávají pozornost ve vašem koutu Mastodonu."
},
"favorite": {
"title": "Your Favorites"
"title": "Vaše oblíbené"
},
"notification": {
"title": {
"Everything": "Everything",
"Mentions": "Mentions"
"Everything": "Všechno",
"Mentions": "Zmínky"
},
"notification_description": {
"followed_you": "followed you",
"favorited_your_post": "favorited your post",
"reblogged_your_post": "reblogged your post",
"mentioned_you": "mentioned you",
"request_to_follow_you": "request to follow you",
"poll_has_ended": "poll has ended"
"followed_you": "vás sleduje",
"favorited_your_post": "si oblíbil váš příspěvek",
"reblogged_your_post": "boostnul váš příspěvek",
"mentioned_you": "vás zmínil/a",
"request_to_follow_you": "požádat vás o sledování",
"poll_has_ended": "anketa skončila"
},
"keyobard": {
"show_everything": "Show Everything",
"show_mentions": "Show Mentions"
"show_everything": "Zobrazit vše",
"show_mentions": "Zobrazit zmínky"
},
"follow_request": {
"accept": "Accept",
"accepted": "Accepted",
"reject": "reject",
"rejected": "Rejected"
"accept": "Přijmout",
"accepted": "Přijato",
"reject": "odmítnout",
"rejected": "Zamítnuto"
}
},
"thread": {
"back_title": "Post",
"title": "Post from %s"
"back_title": "Příspěvek",
"title": "Příspěvek od %s"
},
"settings": {
"title": "Settings",
"title": "Nastavení",
"section": {
"appearance": {
"title": "Appearance",
"automatic": "Automatic",
"light": "Always Light",
"dark": "Always Dark"
"title": "Vzhled",
"automatic": "Automaticky",
"light": "Vždy světlý",
"dark": "Vždy tmavý"
},
"look_and_feel": {
"title": "Look and Feel",
"use_system": "Use System",
"really_dark": "Really Dark",
"title": "Vzhled a chování",
"use_system": "Použít systém",
"really_dark": "Skutečně tmavý",
"sorta_dark": "Sorta Dark",
"light": "Light"
"light": "Světlý"
},
"notifications": {
"title": "Notifications",
"favorites": "Favorites my post",
"follows": "Follows me",
"boosts": "Reblogs my post",
"mentions": "Mentions me",
"title": "Upozornění",
"favorites": "Oblíbil si můj příspěvek",
"follows": "Sleduje mě",
"boosts": "Boostnul můj příspěvek",
"mentions": "Zmiňuje mě",
"trigger": {
"anyone": "anyone",
"follower": "a follower",
"follow": "anyone I follow",
"noone": "no one",
"title": "Notify me when"
"anyone": "kdokoliv",
"follower": "sledující",
"follow": "kdokoli, koho sleduji",
"noone": "nikdo",
"title": "Upozornit, když"
}
},
"preference": {
"title": "Preferences",
"true_black_dark_mode": "True black dark mode",
"disable_avatar_animation": "Disable animated avatars",
"disable_emoji_animation": "Disable animated emojis",
"using_default_browser": "Use default browser to open links",
"open_links_in_mastodon": "Open links in Mastodon"
"title": "Předvolby",
"true_black_dark_mode": "Skutečný černý tmavý režim",
"disable_avatar_animation": "Zakázat animované avatary",
"disable_emoji_animation": "Zakázat animované emoji",
"using_default_browser": "Použít výchozí prohlížeč pro otevírání odkazů",
"open_links_in_mastodon": "Otevřít odkazy v Mastodonu"
},
"boring_zone": {
"title": "The Boring Zone",
"account_settings": "Account Settings",
"terms": "Terms of Service",
"privacy": "Privacy Policy"
"title": "Nudná část",
"account_settings": "Nastavení účtu",
"terms": "Podmínky služby",
"privacy": "Zásady ochrany osobních údajů"
},
"spicy_zone": {
"title": "The Spicy Zone",
"clear": "Clear Media Cache",
"signout": "Sign Out"
"title": "Ostrá část",
"clear": "Vymazat mezipaměť médií",
"signout": "Odhlásit se"
}
},
"footer": {
"mastodon_description": "Mastodon is open source software. You can report issues on GitHub at %s (%s)"
"mastodon_description": "Mastodon je open source software. Na GitHub můžete nahlásit problémy na %s (%s)"
},
"keyboard": {
"close_settings_window": "Close Settings Window"
"close_settings_window": "Zavřít okno nastavení"
}
},
"report": {
"title_report": "Report",
"title": "Report %s",
"step1": "Step 1 of 2",
"step2": "Step 2 of 2",
"content1": "Are there any other posts youd like to add to the report?",
"content2": "Is there anything the moderators should know about this report?",
"report_sent_title": "Thanks for reporting, well look into this.",
"send": "Send Report",
"skip_to_send": "Send without comment",
"text_placeholder": "Type or paste additional comments",
"reported": "REPORTED",
"title_report": "Nahlásit",
"title": "Nahlásit %s",
"step1": "Krok 1 ze 2",
"step2": "Krok 2 ze 2",
"content1": "Existují nějaké další příspěvky, které byste chtěli přidat do zprávy?",
"content2": "Je o tomto hlášení něco, co by měli vědět moderátoři?",
"report_sent_title": "Děkujeme za nahlášení, podíváme se na to.",
"send": "Odeslat hlášení",
"skip_to_send": "Odeslat bez komentáře",
"text_placeholder": "Napište nebo vložte další komentáře",
"reported": "NAHLÁŠEN",
"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": "Krok 1 ze 4",
"whats_wrong_with_this_post": "Co je na tomto příspěvku špatně?",
"whats_wrong_with_this_account": "Co je špatně s tímto účtem?",
"whats_wrong_with_this_username": "Co je špatně na %s?",
"select_the_best_match": "Vyberte nejbližší možnost",
"i_dont_like_it": "Nelíbí se mi",
"it_is_not_something_you_want_to_see": "Není to něco, co chcete vidět",
"its_spam": "Je to spam",
"malicious_links_fake_engagement_or_repetetive_replies": "Škodlivé odkazy, falešné zapojení nebo opakující se odpovědi",
"it_violates_server_rules": "Porušuje pravidla serveru",
"you_are_aware_that_it_breaks_specific_rules": "Máte za to, že porušuje konkrétní pravidla",
"its_something_else": "Jde o něco jiného",
"the_issue_does_not_fit_into_other_categories": "Problém neodpovídá ostatním kategoriím"
},
"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": "Krok 2 ze 4",
"which_rules_are_being_violated": "Jaká pravidla jsou porušována?",
"select_all_that_apply": "Vyberte všechna relevantní",
"i_just_dont_like_it": "Jen se mi to nelíbí"
},
"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": "Krok 3 ze 4",
"are_there_any_posts_that_back_up_this_report": "Existují příspěvky dokládající toto hlášení?",
"select_all_that_apply": "Vyberte všechna relevantní"
},
"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": "Krok 4 ze 4",
"is_there_anything_else_we_should_know": "Je ještě něco jiného, co bychom měli vědět?"
},
"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": "Nechcete to vidět?",
"when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Když uvidíte něco, co se vám nelíbí na Mastodonu, můžete odstranit tuto osobu ze svého zážitku.",
"unfollow": "Přestat sledovat",
"unfollowed": "Už nesledujete",
"unfollow_user": "Přestat sledovat %s",
"mute_user": "Skrýt %s",
"you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Neuvidíte jejich příspěvky nebo boostnutí v domovském kanálu. Nebudou vědět, že jsou skrytí.",
"block_user": "Blokovat %s",
"they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Už nebudou moci sledovat nebo vidět vaše příspěvky, ale mohou vidět, zda byly zablokovány.",
"while_we_review_this_you_can_take_action_against_user": "Zatímco to posuzujeme, můžete podniknout kroky proti %s"
}
},
"preview": {
"keyboard": {
"close_preview": "Close Preview",
"show_next": "Show Next",
"show_previous": "Show Previous"
"close_preview": "Zavřít náhled",
"show_next": "Zobrazit další",
"show_previous": "Zobrazit předchozí"
}
},
"account_list": {
"tab_bar_hint": "Current selected profile: %s. Double tap then hold to show account switcher",
"dismiss_account_switcher": "Dismiss Account Switcher",
"add_account": "Add Account"
"tab_bar_hint": "Aktuální vybraný profil: %s. Dvojitým poklepáním zobrazíte přepínač účtů",
"dismiss_account_switcher": "Zrušit přepínač účtů",
"add_account": "Přidat účet"
},
"wizard": {
"new_in_mastodon": "New in Mastodon",
"multiple_account_switch_intro_description": "Switch between multiple accounts by holding the profile button.",
"accessibility_hint": "Double tap to dismiss this wizard"
"new_in_mastodon": "Nový v Mastodonu",
"multiple_account_switch_intro_description": "Přepínání mezi více účty podržením tlačítka profilu.",
"accessibility_hint": "Dvojitým poklepáním tohoto průvodce odmítnete"
},
"bookmark": {
"title": "Bookmarks"
"title": "Záložky"
}
}
}

View File

@ -1,6 +1,6 @@
{
"NSCameraUsageDescription": "Used to take photo for post status",
"NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library",
"NewPostShortcutItemTitle": "New Post",
"SearchShortcutItemTitle": "Search"
"NSCameraUsageDescription": "Slouží k pořízení fotografie pro příspěvek",
"NSPhotoLibraryAddUsageDescription": "Slouží k uložení fotografie do knihovny fotografií",
"NewPostShortcutItemTitle": "Nový příspěvek",
"SearchShortcutItemTitle": "Hledat"
}

View File

@ -136,6 +136,12 @@
"vote": "Vote",
"closed": "Closed"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Reply",
"reblog": "Hybwch",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duration: %s",

View File

@ -136,6 +136,12 @@
"vote": "Vote",
"closed": "Closed"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Reply",
"reblog": "Reblog",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duration: %s",

View File

@ -248,9 +248,9 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 Follower</string>
<string>1 Folgender</string>
<key>other</key>
<string>%ld Follower</string>
<string>%ld Folgende</string>
</dict>
</dict>
<key>date.year.left</key>

View File

@ -136,6 +136,12 @@
"vote": "Abstimmen",
"closed": "Beendet"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Antworten",
"reblog": "Teilen",
@ -376,7 +382,11 @@
"video": "Video",
"attachment_broken": "Dieses %s scheint defekt zu sein und\nkann nicht auf Mastodon hochgeladen werden.",
"description_photo": "Für Menschen mit Sehbehinderung beschreiben...",
"description_video": "Für Menschen mit Sehbehinderung beschreiben..."
"description_video": "Für Menschen mit Sehbehinderung beschreiben...",
"load_failed": "Laden fehlgeschlagen",
"upload_failed": "Upload fehlgeschlagen",
"can_not_recognize_this_media_attachment": "Medienanhang wurde nicht erkannt",
"attachment_too_large": "Anhang zu groß"
},
"poll": {
"duration_time": "Dauer: %s",
@ -425,7 +435,7 @@
"dashboard": {
"posts": "Beiträge",
"following": "Gefolgte",
"followers": "Folger"
"followers": "Folgende"
},
"fields": {
"add_row": "Zeile hinzufügen",
@ -460,7 +470,7 @@
},
"confirm_show_reblogs": {
"title": "Reblogs anzeigen",
"message": "Confirm to show reblogs"
"message": "Bestätigen um Reblogs anzuzeigen"
},
"confirm_hide_reblogs": {
"title": "Reblogs ausblenden",
@ -476,11 +486,11 @@
},
"follower": {
"title": "Follower",
"footer": "Follower von anderen Servern werden nicht angezeigt."
"footer": "Folger, die nicht auf deinem Server registriert sind, werden nicht angezeigt."
},
"following": {
"title": "Folgende",
"footer": "Wem das Konto folgt wird von anderen Servern werden nicht angezeigt."
"footer": "Gefolgte, die nicht auf deinem Server registriert sind, werden nicht angezeigt."
},
"familiarFollowers": {
"title": "Follower, die dir bekannt vorkommen",
@ -590,7 +600,7 @@
"mentions": "Mich erwähnt",
"trigger": {
"anyone": "jeder",
"follower": "ein Folger",
"follower": "ein Folgender",
"follow": "ein von mir Gefolgter",
"noone": "niemand",
"title": "Benachrichtige mich, wenn"
@ -696,7 +706,7 @@
"accessibility_hint": "Doppeltippen, um diesen Assistenten zu schließen"
},
"bookmark": {
"title": "Bookmarks"
"title": "Lesezeichen"
}
}
}

View File

@ -1,6 +1,6 @@
{
"NSCameraUsageDescription": "Verwendet um Fotos für neue Beiträge aufzunehmen",
"NSPhotoLibraryAddUsageDescription": "Verwendet um Fotos zu speichern",
"NSCameraUsageDescription": "Wird verwendet, um Fotos für neue Beiträge aufzunehmen",
"NSPhotoLibraryAddUsageDescription": "Wird verwendet, um Foto in der Foto-Mediathek zu speichern",
"NewPostShortcutItemTitle": "Neuer Beitrag",
"SearchShortcutItemTitle": "Suche"
"SearchShortcutItemTitle": "Suchen"
}

View File

@ -136,6 +136,12 @@
"vote": "Vote",
"closed": "Closed"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Reply",
"reblog": "Reblog",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duration: %s",

View File

@ -50,6 +50,28 @@
<string>%ld characters</string>
</dict>
</dict>
<key>a11y.plural.count.characters_left</key>
<dict>
<key>NSStringLocalizedFormatKey</key>
<string>%#@character_count@ left</string>
<key>character_count</key>
<dict>
<key>NSStringFormatSpecTypeKey</key>
<string>NSStringPluralRuleType</string>
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>zero</key>
<string>no characters</string>
<key>one</key>
<string>1 character</string>
<key>few</key>
<string>%ld characters</string>
<key>many</key>
<string>%ld characters</string>
<key>other</key>
<string>%ld characters</string>
</dict>
</dict>
<key>plural.count.followed_by_and_mutual</key>
<dict>
<key>NSStringLocalizedFormatKey</key>

View File

@ -138,7 +138,7 @@
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hastag %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
@ -382,7 +382,11 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duration: %s",
@ -413,7 +417,9 @@
"custom_emoji_picker": "Custom Emoji Picker",
"enable_content_warning": "Enable Content Warning",
"disable_content_warning": "Disable Content Warning",
"post_visibility_menu": "Post Visibility Menu"
"post_visibility_menu": "Post Visibility Menu",
"post_options": "Post Options",
"posting_as": "Posting as %s"
},
"keyboard": {
"discard_post": "Discard Post",

View File

@ -136,6 +136,12 @@
"vote": "Votar",
"closed": "Cerrada"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Responder",
"reblog": "Adherir",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "Este archivo de %s está roto\ny no se puede subir a Mastodon.",
"description_photo": "Describí la imagen para personas con dificultades visuales…",
"description_video": "Describí el video para personas con dificultades visuales…"
"description_video": "Describí el video para personas con dificultades visuales…",
"load_failed": "Falló la descarga",
"upload_failed": "Falló la subida",
"can_not_recognize_this_media_attachment": "No se pudo reconocer este archivo adjunto",
"attachment_too_large": "Adjunto demasiado grande"
},
"poll": {
"duration_time": "Duración: %s",

View File

@ -136,6 +136,12 @@
"vote": "Vota",
"closed": "Cerrado"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Responder",
"reblog": "Rebloguear",
@ -376,7 +382,11 @@
"video": "vídeo",
"attachment_broken": "Este %s está roto y no puede\nsubirse a Mastodon.",
"description_photo": "Describe la foto para los usuarios con dificultad visual...",
"description_video": "Describe el vídeo para los usuarios con dificultad visual..."
"description_video": "Describe el vídeo para los usuarios con dificultad visual...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duración: %s",

View File

@ -136,6 +136,12 @@
"vote": "Bozkatu",
"closed": "Itxita"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Erantzun",
"reblog": "Bultzada",
@ -376,7 +382,11 @@
"video": "bideoa",
"attachment_broken": "%s hondatuta dago eta ezin da\nMastodonera igo.",
"description_photo": "Deskribatu argazkia ikusmen arazoak dituztenentzat...",
"description_video": "Deskribatu bideoa ikusmen arazoak dituztenentzat..."
"description_video": "Deskribatu bideoa ikusmen arazoak dituztenentzat...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Iraupena: %s",

View File

@ -136,6 +136,12 @@
"vote": "Vote",
"closed": "Suljettu"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Vastaa",
"reblog": "Jaa edelleen",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Kuvaile kuva näkövammaisille...",
"description_video": "Kuvaile video näkövammaisille..."
"description_video": "Kuvaile video näkövammaisille...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Kesto: %s",

View File

@ -136,6 +136,12 @@
"vote": "Voter",
"closed": "Fermé"
},
"meta_entity": {
"url": "Lien : %s",
"hashtag": "Hashtag : %s",
"mention": "Afficher le profile : %s",
"email": "Adresse e-mail : %s"
},
"actions": {
"reply": "Répondre",
"reblog": "Rebloguer",
@ -376,7 +382,11 @@
"video": "vidéo",
"attachment_broken": "Ce %s est brisé et ne peut pas être\ntéléversé sur Mastodon.",
"description_photo": "Décrire cette photo pour les personnes malvoyantes...",
"description_video": "Décrire cette vidéo pour les personnes malvoyantes..."
"description_video": "Décrire cette vidéo pour les personnes malvoyantes...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Durée: %s",
@ -696,7 +706,7 @@
"accessibility_hint": "Tapotez deux fois pour fermer cet assistant"
},
"bookmark": {
"title": "Bookmarks"
"title": "Favoris"
}
}
}

View File

@ -136,6 +136,12 @@
"vote": "Cuir bhòt",
"closed": "Dùinte"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Freagair",
"reblog": "Brosnaich",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "Seo %s a tha briste is cha ghabh\na luchdadh suas gu Mastodon.",
"description_photo": "Mìnich an dealbh dhan fheadhainn air a bheil cion-lèirsinne…",
"description_video": "Mìnich a video dhan fheadhainn air a bheil cion-lèirsinne…"
"description_video": "Mìnich a video dhan fheadhainn air a bheil cion-lèirsinne…",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Faide: %s",

View File

@ -136,6 +136,12 @@
"vote": "Votar",
"closed": "Pechada"
},
"meta_entity": {
"url": "Ligazón: %s",
"hashtag": "Cancelo: %s",
"mention": "Mostrar Perfil: %s",
"email": "Enderezo de email: %s"
},
"actions": {
"reply": "Responder",
"reblog": "Promover",
@ -181,8 +187,8 @@
"unmute_user": "Deixar de acalar a @%s",
"muted": "Acalada",
"edit_info": "Editar info",
"show_reblogs": "Show Reblogs",
"hide_reblogs": "Hide Reblogs"
"show_reblogs": "Mostrar Promocións",
"hide_reblogs": "Agochar Promocións"
},
"timeline": {
"filtered": "Filtrado",
@ -376,7 +382,11 @@
"video": "vídeo",
"attachment_broken": "Este %s está estragado e non pode\nser subido a Mastodon.",
"description_photo": "Describe a foto para persoas con problemas visuais...",
"description_video": "Describe o vídeo para persoas con problemas visuais..."
"description_video": "Describe o vídeo para persoas con problemas visuais...",
"load_failed": "Fallou a carga",
"upload_failed": "Erro na subida",
"can_not_recognize_this_media_attachment": "Non se recoñece o tipo de multimedia",
"attachment_too_large": "Adxunto demasiado grande"
},
"poll": {
"duration_time": "Duración: %s",
@ -459,12 +469,12 @@
"message": "Confirma o desbloqueo de %s"
},
"confirm_show_reblogs": {
"title": "Show Reblogs",
"message": "Confirm to show reblogs"
"title": "Mostrar Promocións",
"message": "Confirma para ver promocións"
},
"confirm_hide_reblogs": {
"title": "Hide Reblogs",
"message": "Confirm to hide reblogs"
"title": "Agochar Promocións",
"message": "Confirma para agochar promocións"
}
},
"accessibility": {
@ -696,7 +706,7 @@
"accessibility_hint": "Dobre toque para desbotar este asistente"
},
"bookmark": {
"title": "Bookmarks"
"title": "Marcadores"
}
}
}

View File

@ -136,6 +136,12 @@
"vote": "Vote",
"closed": "Closed"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Reply",
"reblog": "Reblog",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duration: %s",

View File

@ -6,29 +6,29 @@
"please_try_again_later": "Silakan coba lagi nanti."
},
"sign_up_failure": {
"title": "Sign Up Failure"
"title": "Gagal Mendaftar"
},
"server_error": {
"title": "Kesalahan Server"
},
"vote_failure": {
"title": "Vote Failure",
"title": "Gagal Voting",
"poll_ended": "Japat telah berakhir"
},
"discard_post_content": {
"title": "Hapus Draf",
"message": "Confirm to discard composed post content."
"message": "Konfirmasi untuk mengabaikan postingan yang dibuat."
},
"publish_post_failure": {
"title": "Publish Failure",
"message": "Failed to publish the post.\nPlease check your internet connection.",
"title": "Gagal Mempublikasikan",
"message": "Gagal mempublikasikan postingan.\nMohon periksa koneksi Internet Anda.",
"attachments_message": {
"video_attach_with_photo": "Tidak dapat melampirkan video di postingan yang sudah mengandung gambar.",
"more_than_one_video": "Tidak dapat melampirkan lebih dari satu video."
}
},
"edit_profile_failure": {
"title": "Edit Profile Error",
"title": "Masalah dalam mengubah profil",
"message": "Tidak dapat menyunting profil. Harap coba lagi."
},
"sign_out": {
@ -37,16 +37,16 @@
"confirm": "Keluar"
},
"block_domain": {
"title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.",
"title": "Apakah Anda benar, benar yakin ingin memblokir keseluruhan %s? Dalam kebanyakan kasus, beberapa pemblokiran atau pembisuan yang ditargetkan sudah cukup dan lebih disukai. Anda tidak akan melihat konten dari domain tersebut dan semua pengikut Anda dari domain itu akan dihapus.",
"block_entire_domain": "Blokir Domain"
},
"save_photo_failure": {
"title": "Save Photo Failure",
"message": "Please enable the photo library access permission to save the photo."
"title": "Gagal Menyimpan Foto",
"message": "Mohon aktifkan izin akses pustaka foto untuk menyimpan foto."
},
"delete_post": {
"title": "Apakah Anda yakin ingin menghapus postingan ini?",
"message": "Are you sure you want to delete this post?"
"message": "Apakah Anda yakin untuk menghapus kiriman ini?"
},
"clean_cache": {
"title": "Bersihkan Cache",
@ -67,11 +67,11 @@
"done": "Selesai",
"confirm": "Konfirmasi",
"continue": "Lanjut",
"compose": "Compose",
"compose": "Tulis",
"cancel": "Batal",
"discard": "Discard",
"discard": "Buang",
"try_again": "Coba Lagi",
"take_photo": "Take Photo",
"take_photo": "Ambil Foto",
"save_photo": "Simpan Foto",
"copy_photo": "Salin Foto",
"sign_in": "Masuk",
@ -82,9 +82,9 @@
"share_user": "Bagikan %s",
"share_post": "Bagikan Postingan",
"open_in_safari": "Buka di Safari",
"open_in_browser": "Open in Browser",
"open_in_browser": "Buka di Peramban",
"find_people": "Cari orang untuk diikuti",
"manually_search": "Manually search instead",
"manually_search": "Cari secara manual saja",
"skip": "Lewati",
"reply": "Balas",
"report_user": "Laporkan %s",
@ -111,16 +111,16 @@
"next_status": "Postingan Selanjutnya",
"open_status": "Buka Postingan",
"open_author_profile": "Buka Profil Penulis",
"open_reblogger_profile": "Open Reblogger's Profile",
"open_reblogger_profile": "Buka Profil Reblogger",
"reply_status": "Balas Postingan",
"toggle_reblog": "Toggle Reblog on Post",
"toggle_favorite": "Toggle Favorite on Post",
"toggle_content_warning": "Toggle Content Warning",
"preview_image": "Preview Image"
"toggle_reblog": "Nyalakan Reblog pada Postingan",
"toggle_favorite": "Nyalakan Favorit pada Postingan",
"toggle_content_warning": "Nyalakan Peringatan Konten",
"preview_image": "Pratinjau Gambar"
},
"segmented_control": {
"previous_section": "Previous Section",
"next_section": "Next Section"
"previous_section": "Bagian Sebelumnya",
"next_section": "Bagian Selanjutnya"
}
},
"status": {
@ -136,6 +136,12 @@
"vote": "Vote",
"closed": "Ditutup"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Balas",
"reblog": "Reblog",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "%s ini rusak dan tidak dapat diunggah ke Mastodon.",
"description_photo": "Jelaskan fotonya untuk mereka yang tidak dapat melihat dengan jelas...",
"description_video": "Jelaskan videonya untuk mereka yang tidak dapat melihat dengan jelas..."
"description_video": "Jelaskan videonya untuk mereka yang tidak dapat melihat dengan jelas...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Durasi: %s",

View File

@ -136,6 +136,12 @@
"vote": "Vota",
"closed": "Chiuso"
},
"meta_entity": {
"url": "Collegamento: %s",
"hashtag": "Hashtag: %s",
"mention": "Mostra il profilo: %s",
"email": "Indirizzo email: %s"
},
"actions": {
"reply": "Rispondi",
"reblog": "Condivisione",
@ -376,7 +382,11 @@
"video": "filmato",
"attachment_broken": "Questo %s è rotto e non può essere\ncaricato su Mastodon.",
"description_photo": "Descrivi la foto per gli utenti ipovedenti...",
"description_video": "Descrivi il filmato per gli utenti ipovedenti..."
"description_video": "Descrivi il filmato per gli utenti ipovedenti...",
"load_failed": "Caricamento fallito",
"upload_failed": "Caricamento fallito",
"can_not_recognize_this_media_attachment": "Impossibile riconoscere questo allegato multimediale",
"attachment_too_large": "Allegato troppo grande"
},
"poll": {
"duration_time": "Durata: %s",
@ -696,7 +706,7 @@
"accessibility_hint": "Doppio tocco per eliminare questa procedura guidata"
},
"bookmark": {
"title": "Bookmarks"
"title": "Segnalibri"
}
}
}

View File

@ -136,6 +136,12 @@
"vote": "投票",
"closed": "終了"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "返信",
"reblog": "ブースト",
@ -376,7 +382,11 @@
"video": "動画",
"attachment_broken": "%sは壊れていてMastodonにアップロードできません。",
"description_photo": "閲覧が難しいユーザーへの画像説明",
"description_video": "閲覧が難しいユーザーへの映像説明"
"description_video": "閲覧が難しいユーザーへの映像説明",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "期間: %s",

View File

@ -136,6 +136,12 @@
"vote": "Dɣeṛ",
"closed": "Ifukk"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Err",
"reblog": "Aɛiwed n usuffeɣ",
@ -376,7 +382,11 @@
"video": "tavidyutt",
"attachment_broken": "%s-a yerreẓ, ur yezmir ara\nAd d-yettwasali ɣef Mastodon.",
"description_photo": "Glem-d tawlaft i wid yesɛan ugur deg yiẓri...",
"description_video": "Glem-d tavidyut i wid yesɛan ugur deg yiẓri..."
"description_video": "Glem-d tavidyut i wid yesɛan ugur deg yiẓri...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Tangazt: %s",

View File

@ -136,6 +136,12 @@
"vote": "Deng bide",
"closed": "Girtî"
},
"meta_entity": {
"url": "Girêdan: %s",
"hashtag": "Hashtagê: %s",
"mention": "Profîlê nîşan bide: %s",
"email": "Navnîşanên e-nameyê: %s"
},
"actions": {
"reply": "Bersivê bide",
"reblog": "Ji nû ve nivîsandin",
@ -181,8 +187,8 @@
"unmute_user": "%s bêdeng neke",
"muted": "Bêdengkirî",
"edit_info": "Zanyariyan serrast bike",
"show_reblogs": "Show Reblogs",
"hide_reblogs": "Hide Reblogs"
"show_reblogs": "Bilindkirinan nîşan bide",
"hide_reblogs": "Bilindkirinan veşêre"
},
"timeline": {
"filtered": "Parzûnkirî",
@ -376,7 +382,11 @@
"video": "vîdyo",
"attachment_broken": "Ev %s naxebite û nayê barkirin\n li ser Mastodon.",
"description_photo": "Wêneyê ji bo kêmbînên dîtbar bide nasîn...",
"description_video": "Vîdyoyê ji bo kêmbînên dîtbar bide nasîn..."
"description_video": "Vîdyoyê ji bo kêmbînên dîtbar bide nasîn...",
"load_failed": "Barkirin têk çû",
"upload_failed": "Barkirin têk çû",
"can_not_recognize_this_media_attachment": "Nikare ev pêveka medyayê nas bike",
"attachment_too_large": "Pêvek pir mezin e"
},
"poll": {
"duration_time": "Dirêjî: %s",
@ -459,12 +469,12 @@
"message": "Ji bo rakirina astengkirinê %s bipejirîne"
},
"confirm_show_reblogs": {
"title": "Show Reblogs",
"message": "Confirm to show reblogs"
"title": "Bilindkirinan nîşan bide",
"message": "Bo nîşandana bilindkirinan bipejirîne"
},
"confirm_hide_reblogs": {
"title": "Hide Reblogs",
"message": "Confirm to hide reblogs"
"title": "Bilindkirinan veşêre",
"message": "Bo veşartina bilindkirinan bipejirîne"
}
},
"accessibility": {
@ -696,7 +706,7 @@
"accessibility_hint": "Du caran bitikîne da ku çarçoveyahilpekok ji holê rakî"
},
"bookmark": {
"title": "Bookmarks"
"title": "Şûnpel"
}
}
}

View File

@ -129,13 +129,19 @@
"show_post": "게시물 보기",
"show_user_profile": "사용자 프로필 보기",
"content_warning": "열람 주의",
"sensitive_content": "Sensitive Content",
"sensitive_content": "민감한 콘텐츠",
"media_content_warning": "아무 곳이나 눌러서 보기",
"tap_to_reveal": "눌러서 확인",
"poll": {
"vote": "투표",
"closed": "마감"
},
"meta_entity": {
"url": "링크: %s",
"hashtag": "해시태그: %s",
"mention": "프로필 보기: %s",
"email": "이메일 주소: %s"
},
"actions": {
"reply": "답글",
"reblog": "리블로그",
@ -376,7 +382,11 @@
"video": "동영상",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "시각장애인을 위한 사진 설명…",
"description_video": "시각장애인을 위한 영상 설명…"
"description_video": "시각장애인을 위한 영상 설명…",
"load_failed": "불러오기 실패",
"upload_failed": "업로드 실패",
"can_not_recognize_this_media_attachment": "이 미디어 첨부파일을 인식할 수 없습니다",
"attachment_too_large": "첨부파일이 너무 큽니다"
},
"poll": {
"duration_time": "기간: %s",

View File

@ -136,6 +136,12 @@
"vote": "Balsot",
"closed": "Aizvērts"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Atbildēt",
"reblog": "Reblogot",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duration: %s",

View File

@ -136,6 +136,12 @@
"vote": "Stemmen",
"closed": "Gesloten"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Reageren",
"reblog": "Delen",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "Deze %s is corrupt en kan niet geüpload worden naar Mastodon.",
"description_photo": "Omschrijf de foto voor mensen met een visuele beperking...",
"description_video": "Omschrijf de video voor mensen met een visuele beperking..."
"description_video": "Omschrijf de video voor mensen met een visuele beperking...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duur: %s",

View File

@ -6,7 +6,7 @@
"please_try_again_later": "Tente novamente mais tarde."
},
"sign_up_failure": {
"title": "Sign Up Failure"
"title": "Falha no cadastro"
},
"server_error": {
"title": "Erro do servidor"
@ -17,7 +17,7 @@
},
"discard_post_content": {
"title": "Deletar Rascunho",
"message": "Confirm to discard composed post content."
"message": "Confirme para descartar o conteúdo da publicação composta."
},
"publish_post_failure": {
"title": "Falha ao publicar",
@ -42,7 +42,7 @@
},
"save_photo_failure": {
"title": "Falha ao salvar foto",
"message": "Please enable the photo library access permission to save the photo."
"message": "Por favor, ative a permissão de acesso à galeria para salvar a foto."
},
"delete_post": {
"title": "Deletar Toot",
@ -71,212 +71,218 @@
"cancel": "Cancelar",
"discard": "Descartar",
"try_again": "Tente novamente",
"take_photo": "Take Photo",
"take_photo": "Tirar foto",
"save_photo": "Salvar foto",
"copy_photo": "Copiar foto",
"sign_in": "Sign In",
"sign_up": "Sign Up",
"see_more": "See More",
"preview": "Preview",
"sign_in": "Entrar",
"sign_up": "Criar conta",
"see_more": "Ver mais",
"preview": "Pré-visualização",
"share": "Compartilhar",
"share_user": "Compartilhar %s",
"share_post": "Share Post",
"open_in_safari": "Open in Safari",
"open_in_browser": "Open in Browser",
"find_people": "Find people to follow",
"manually_search": "Manually search instead",
"skip": "Skip",
"reply": "Reply",
"report_user": "Report %s",
"block_domain": "Block %s",
"unblock_domain": "Unblock %s",
"settings": "Settings",
"delete": "Delete"
"share_post": "Compartilhar postagem",
"open_in_safari": "Abrir no Safari",
"open_in_browser": "Abrir no navegador",
"find_people": "Encontre pessoas para seguir",
"manually_search": "Procure manualmente em vez disso",
"skip": "Pular",
"reply": "Responder",
"report_user": "Denunciar %s",
"block_domain": "Bloquear %s",
"unblock_domain": "Desbloquear %s",
"settings": "Configurações",
"delete": "Excluir"
},
"tabs": {
"home": "Home",
"search": "Search",
"notification": "Notification",
"profile": "Profile"
"home": "Início",
"search": "Buscar",
"notification": "Notificação",
"profile": "Perfil"
},
"keyboard": {
"common": {
"switch_to_tab": "Switch to %s",
"compose_new_post": "Compose New Post",
"show_favorites": "Show Favorites",
"open_settings": "Open Settings"
"switch_to_tab": "Mudar para %s",
"compose_new_post": "Compor novo toot",
"show_favorites": "Mostrar favoritos",
"open_settings": "Abrir configurações"
},
"timeline": {
"previous_status": "Previous Post",
"next_status": "Next Post",
"open_status": "Open Post",
"open_author_profile": "Open Author's Profile",
"open_reblogger_profile": "Open Reblogger's Profile",
"reply_status": "Reply to Post",
"toggle_reblog": "Toggle Reblog on Post",
"toggle_favorite": "Toggle Favorite on Post",
"toggle_content_warning": "Toggle Content Warning",
"preview_image": "Preview Image"
"previous_status": "Postagem anterior",
"next_status": "Próxima postagem",
"open_status": "Abrir toot",
"open_author_profile": "Abrir perfil do autor",
"open_reblogger_profile": "Abrir perfil do reblogger",
"reply_status": "Responder toot",
"toggle_reblog": "Ativar/desativar Reblog na postagem",
"toggle_favorite": "Ativar/desativar Favorito na postagem",
"toggle_content_warning": "Ativar/desativar Aviso de Conteúdo",
"preview_image": "Pré-visualizar imagem"
},
"segmented_control": {
"previous_section": "Previous Section",
"next_section": "Next Section"
"previous_section": "Seção anterior",
"next_section": "Próxima seção"
}
},
"status": {
"user_reblogged": "%s reblogged",
"user_replied_to": "Replied to %s",
"show_post": "Show Post",
"show_user_profile": "Show user profile",
"content_warning": "Content Warning",
"sensitive_content": "Sensitive Content",
"media_content_warning": "Tap anywhere to reveal",
"tap_to_reveal": "Tap to reveal",
"user_reblogged": "%s reblogou",
"user_replied_to": "Em resposta a %s",
"show_post": "Mostrar postagem",
"show_user_profile": "Mostrar perfil de usuário",
"content_warning": "Aviso de Conteúdo",
"sensitive_content": "Conteúdo sensível",
"media_content_warning": "Toque em qualquer lugar para revelar",
"tap_to_reveal": "Toque para revelar",
"poll": {
"vote": "Vote",
"closed": "Closed"
"vote": "Votar",
"closed": "Fechado"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Mostrar perfil: %s",
"email": "Endereço de e-mail: %s"
},
"actions": {
"reply": "Responder",
"reblog": "Reblog",
"unreblog": "Undo reblog",
"favorite": "Favorite",
"unfavorite": "Unfavorite",
"reblog": "Reblogar",
"unreblog": "Desfazer reblog",
"favorite": "Favoritar",
"unfavorite": "Remover favorito",
"menu": "Menu",
"hide": "Hide",
"show_image": "Show image",
"show_gif": "Show GIF",
"show_video_player": "Show video player",
"tap_then_hold_to_show_menu": "Tap then hold to show menu"
"hide": "Ocultar",
"show_image": "Exibir imagem",
"show_gif": "Exibir GIF",
"show_video_player": "Mostrar reprodutor de vídeo",
"tap_then_hold_to_show_menu": "Toque e em seguida segure para exibir o menu"
},
"tag": {
"url": "URL",
"mention": "Mention",
"mention": "Mencionar",
"link": "Link",
"hashtag": "Hashtag",
"email": "Email",
"email": "E-mail",
"emoji": "Emoji"
},
"visibility": {
"unlisted": "Everyone can see this post but not display in the public timeline.",
"private": "Only their followers can see this post.",
"private_from_me": "Only my followers can see this post.",
"direct": "Only mentioned user can see this post."
"private": "Somente seus seguidores podem ver essa postagem.",
"private_from_me": "Somente meus seguidores podem ver essa postagem.",
"direct": "Somente o usuário mencionado pode ver essa postagem."
}
},
"friendship": {
"follow": "Follow",
"following": "Following",
"request": "Request",
"pending": "Pending",
"block": "Block",
"block_user": "Block %s",
"block_domain": "Block %s",
"unblock": "Unblock",
"unblock_user": "Unblock %s",
"blocked": "Blocked",
"mute": "Mute",
"mute_user": "Mute %s",
"unmute": "Unmute",
"unmute_user": "Unmute %s",
"muted": "Muted",
"edit_info": "Edit Info",
"show_reblogs": "Show Reblogs",
"hide_reblogs": "Hide Reblogs"
"follow": "Seguir",
"following": "Seguindo",
"request": "Solicitação",
"pending": "Pendente",
"block": "Bloquear",
"block_user": "Bloquear %s",
"block_domain": "Bloquear %s",
"unblock": "Desbloquear",
"unblock_user": "Desbloquear %s",
"blocked": "Bloqueado",
"mute": "Silenciar",
"mute_user": "Silenciar %s",
"unmute": "Remover silenciado",
"unmute_user": "Remover silenciado %s",
"muted": "Silenciado",
"edit_info": "Editar informação",
"show_reblogs": "Mostrar Reblogs",
"hide_reblogs": "Ocultar Reblogs"
},
"timeline": {
"filtered": "Filtered",
"filtered": "Filtrado",
"timestamp": {
"now": "Now"
"now": "Agora"
},
"loader": {
"load_missing_posts": "Load missing posts",
"loading_missing_posts": "Loading missing posts...",
"show_more_replies": "Show more replies"
"load_missing_posts": "Carregar postagens em falta",
"loading_missing_posts": "Carregando postagens em falta...",
"show_more_replies": "Exibir mais respostas"
},
"header": {
"no_status_found": "No Post Found",
"no_status_found": "Nenhuma postagem encontrada",
"blocking_warning": "You cant view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.",
"user_blocking_warning": "You cant view %ss profile\nuntil you unblock them.\nYour profile looks like this to them.",
"blocked_warning": "You cant view this users profile\nuntil they unblock you.",
"user_blocked_warning": "You cant view %ss profile\nuntil they unblock you.",
"suspended_warning": "This user has been suspended.",
"user_suspended_warning": "%ss account has been suspended."
"blocked_warning": "Você não pode ver o perfil desse usuário até que ele o desbloqueie.",
"user_blocked_warning": "Você não pode ver o perfil de %s até que ele o desbloqueie.",
"suspended_warning": "Esse usuário foi suspenso.",
"user_suspended_warning": "A conta de %s foi suspensa."
}
}
}
},
"scene": {
"welcome": {
"slogan": "Social networking\nback in your hands.",
"get_started": "Get Started",
"log_in": "Log In"
"slogan": "Você no controle de sua rede social.",
"get_started": "Comece já",
"log_in": "Entrar"
},
"server_picker": {
"title": "Mastodon is made of users in different servers.",
"subtitle": "Pick a server based on your interests, region, or a general purpose one.",
"subtitle_extend": "Pick a server based on your interests, region, or a general purpose one. Each server is operated by an entirely independent organization or individual.",
"title": "Mastodon é feito de usuários em instâncias diferentes.",
"subtitle": "Escolha uma instância baseada nos seus interesses, região, ou em uma proposta geral.",
"subtitle_extend": "Escolha uma instância baseada nos seus interesses, região, ou em uma proposta geral. Cada instância é operada por um indivíduo ou uma organização totalmente independente.",
"button": {
"category": {
"all": "All",
"all_accessiblity_description": "Category: All",
"academia": "academia",
"activism": "activism",
"food": "food",
"all": "Todos",
"all_accessiblity_description": "Categoria: Todos",
"academia": "acadêmico",
"activism": "ativismo",
"food": "comida",
"furry": "furry",
"games": "games",
"general": "general",
"journalism": "journalism",
"games": "jogos",
"general": "geral",
"journalism": "jornalismo",
"lgbt": "lgbt",
"regional": "regional",
"art": "art",
"music": "music",
"tech": "tech"
"art": "arte",
"music": "música",
"tech": "tecnologia"
},
"see_less": "See Less",
"see_more": "See More"
"see_less": "Ver menos",
"see_more": "Ver mais"
},
"label": {
"language": "LANGUAGE",
"users": "USERS",
"category": "CATEGORY"
"language": "Idioma",
"users": "Usuários",
"category": "Categoria"
},
"input": {
"placeholder": "Search servers",
"search_servers_or_enter_url": "Search servers or enter URL"
"placeholder": "Procurar instâncias",
"search_servers_or_enter_url": "Procurar instâncias ou inserir URL"
},
"empty_state": {
"finding_servers": "Finding available servers...",
"bad_network": "Something went wrong while loading the data. Check your internet connection.",
"no_results": "No results"
"finding_servers": "Procurando instâncias disponíveis...",
"bad_network": "Algo deu errado ao carregar os dados. Verifique sua conexão com a internet.",
"no_results": "Sem resultados"
}
},
"register": {
"title": "Lets get you set up on %s",
"title": "Vamos configurar você em %s",
"lets_get_you_set_up_on_domain": "Lets get you set up on %s",
"input": {
"avatar": {
"delete": "Delete"
"delete": "Excluir"
},
"username": {
"placeholder": "username",
"duplicate_prompt": "This username is taken."
"placeholder": "nome de usuário",
"duplicate_prompt": "Esse nome de usuário já está sendo usado."
},
"display_name": {
"placeholder": "display name"
"placeholder": "nome de exibição"
},
"email": {
"placeholder": "email"
"placeholder": "e-mail"
},
"password": {
"placeholder": "password",
"require": "Your password needs at least:",
"character_limit": "8 characters",
"placeholder": "senha",
"require": "Sua senha deve ter pelo menos:",
"character_limit": "8 carácteres",
"accessibility": {
"checked": "checked",
"unchecked": "unchecked"
},
"hint": "Your password needs at least eight characters"
"hint": "Sua senha precisa ter pelo menos oito carácteres"
},
"invite": {
"registration_user_invite_request": "Why do you want to join?"
@ -284,17 +290,17 @@
},
"error": {
"item": {
"username": "Username",
"email": "Email",
"password": "Password",
"agreement": "Agreement",
"locale": "Locale",
"reason": "Reason"
"username": "Nome de usuário",
"email": "E-mail",
"password": "Senha",
"agreement": "Termos de uso",
"locale": "Localidade",
"reason": "Motivo"
},
"reason": {
"blocked": "%s contains a disallowed email provider",
"unreachable": "%s does not seem to exist",
"taken": "%s is already in use",
"unreachable": "%s parece não existir",
"taken": "%s já está em uso",
"reserved": "%s is a reserved keyword",
"accepted": "%s must be accepted",
"blank": "%s is required",
@ -366,27 +372,31 @@
"media_selection": {
"camera": "Take Photo",
"photo_library": "Photo Library",
"browse": "Browse"
"browse": "Navegar"
},
"content_input_placeholder": "Type or paste whats on your mind",
"compose_action": "Publish",
"replying_to_user": "replying to %s",
"content_input_placeholder": "Digite ou cole o que está na sua mente",
"compose_action": "Publicar",
"replying_to_user": "em resposta a %s",
"attachment": {
"photo": "photo",
"video": "video",
"photo": "foto",
"video": "vídeo",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duration: %s",
"thirty_minutes": "30 minutes",
"one_hour": "1 Hour",
"six_hours": "6 Hours",
"one_day": "1 Day",
"three_days": "3 Days",
"seven_days": "7 Days",
"option_number": "Option %ld"
"duration_time": "Duração: %s",
"thirty_minutes": "30 minutos",
"one_hour": "1 hora",
"six_hours": "6 horas",
"one_day": "1 dia",
"three_days": "3 dias",
"seven_days": "7 dias",
"option_number": "Opção %ld"
},
"content_warning": {
"placeholder": "Write an accurate warning here..."
@ -423,9 +433,9 @@
"follows_you": "Follows You"
},
"dashboard": {
"posts": "posts",
"following": "following",
"followers": "followers"
"posts": "toots",
"following": "seguindo",
"followers": "seguidores"
},
"fields": {
"add_row": "Add Row",
@ -508,30 +518,30 @@
"accounts": {
"title": "Accounts you might like",
"description": "You may like to follow these accounts",
"follow": "Follow"
"follow": "Seguir"
}
},
"searching": {
"segment": {
"all": "All",
"people": "People",
"all": "Todos",
"people": "Pessoas",
"hashtags": "Hashtags",
"posts": "Posts"
"posts": "Toots"
},
"empty_state": {
"no_results": "No results"
"no_results": "Sem resultados"
},
"recent_search": "Recent searches",
"clear": "Clear"
"recent_search": "Pesquisas recentes",
"clear": "Limpar"
}
},
"discovery": {
"tabs": {
"posts": "Posts",
"posts": "Toots",
"hashtags": "Hashtags",
"news": "News",
"community": "Community",
"for_you": "For You"
"news": "Notícias",
"community": "Comunidade",
"for_you": "Para você"
},
"intro": "These are the posts gaining traction in your corner of Mastodon."
},

View File

@ -1,6 +1,6 @@
{
"NSCameraUsageDescription": "Used to take photo for post status",
"NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library",
"NewPostShortcutItemTitle": "New Post",
"SearchShortcutItemTitle": "Search"
"NSCameraUsageDescription": "Usado para tirar uma foto para postagem",
"NSPhotoLibraryAddUsageDescription": "Usado para salvar foto na Galeria",
"NewPostShortcutItemTitle": "Novo Toot",
"SearchShortcutItemTitle": "Buscar"
}

View File

@ -136,6 +136,12 @@
"vote": "Vote",
"closed": "Closed"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Reply",
"reblog": "Reblog",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duration: %s",

View File

@ -32,9 +32,9 @@
"message": "Nu se poate edita profilul. Vă rugăm să încercaţi din nou."
},
"sign_out": {
"title": "Deconectați-vă",
"title": "Deconectare",
"message": "Sigur doriți să vă deconectați?",
"confirm": "Deconectați-vă"
"confirm": "Deconectare"
},
"block_domain": {
"title": "Are you really, really sure you want to block the entire %s? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain and any of your followers from that domain will be removed.",
@ -136,6 +136,12 @@
"vote": "Vote",
"closed": "Closed"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Reply",
"reblog": "Reblog",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duration: %s",

View File

@ -136,6 +136,12 @@
"vote": "Проголосовать",
"closed": "Завершён"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Ответить",
"reblog": "Продвинуть",
@ -376,7 +382,11 @@
"video": "видео",
"attachment_broken": "Это %s повреждено и не может\nбыть отправлено в Mastodon.",
"description_photo": "Опишите фото для людей с нарушениями зрения...",
"description_video": "Опишите видео для людей с нарушениями зрения..."
"description_video": "Опишите видео для людей с нарушениями зрения...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Продолжительность: %s",

View File

@ -136,6 +136,12 @@
"vote": "ඡන්දය",
"closed": "වසා ඇත"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "පිළිතුරු",
"reblog": "Reblog",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duration: %s",

View File

@ -136,6 +136,12 @@
"vote": "Glasuj",
"closed": "Zaprto"
},
"meta_entity": {
"url": "Povezava: %s",
"hashtag": "Ključnik: %s",
"mention": "Pokaži profil: %s",
"email": "E-naslov: %s"
},
"actions": {
"reply": "Odgovori",
"reblog": "Poobjavi",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "To %s je okvarjeno in ga ni\nmožno naložiti v Mastodon.",
"description_photo": "Opiši fotografijo za slabovidne in osebe z okvaro vida ...",
"description_video": "Opiši video za slabovidne in osebe z okvaro vida ..."
"description_video": "Opiši video za slabovidne in osebe z okvaro vida ...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Trajanje: %s",
@ -696,7 +706,7 @@
"accessibility_hint": "Dvakrat tapnite, da zapustite tega čarovnika"
},
"bookmark": {
"title": "Bookmarks"
"title": "Zaznamki"
}
}
}

View File

@ -152,9 +152,9 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>%ld puff</string>
<string>%ld boost</string>
<key>other</key>
<string>%ld puffar</string>
<string>%ld boostar</string>
</dict>
</dict>
<key>plural.count.reply</key>

View File

@ -111,9 +111,9 @@
"next_status": "Nästa inlägg",
"open_status": "Öppna inlägg",
"open_author_profile": "Öppna författarens profil",
"open_reblogger_profile": "Öppna ompostarens profil",
"open_reblogger_profile": "Öppna boostarens profil",
"reply_status": "Svara på inlägg",
"toggle_reblog": "Växla puff på inlägg",
"toggle_reblog": "Växla boost på inlägg",
"toggle_favorite": "Växla favorit på inlägg",
"toggle_content_warning": "Växla innehållsvarning",
"preview_image": "Förhandsgranska bild"
@ -124,7 +124,7 @@
}
},
"status": {
"user_reblogged": "%s puffade",
"user_reblogged": "%s boostade",
"user_replied_to": "Svarade på %s",
"show_post": "Visa inlägg",
"show_user_profile": "Visa användarprofil",
@ -136,10 +136,16 @@
"vote": "Rösta",
"closed": "Stängd"
},
"meta_entity": {
"url": "Länk: %s",
"hashtag": "Hashtag: %s",
"mention": "Visa profil: %s",
"email": "E-postadress: %s"
},
"actions": {
"reply": "Svara",
"reblog": "Puffa",
"unreblog": "Ångra puff",
"reblog": "Boosta",
"unreblog": "Ångra boost",
"favorite": "Favorit",
"unfavorite": "Ta bort favorit",
"menu": "Meny",
@ -181,8 +187,8 @@
"unmute_user": "Avtysta %s",
"muted": "Tystad",
"edit_info": "Redigera info",
"show_reblogs": "Visa knuffar",
"hide_reblogs": "Dölj puffar"
"show_reblogs": "Visa boostar",
"hide_reblogs": "Dölj boostar"
},
"timeline": {
"filtered": "Filtrerat",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "Denna %s är trasig och kan inte\nladdas upp till Mastodon.",
"description_photo": "Beskriv fotot för synskadade...",
"description_video": "Beskriv videon för de synskadade..."
"description_video": "Beskriv videon för de synskadade...",
"load_failed": "Det gick inte att läsa in",
"upload_failed": "Uppladdning misslyckades",
"can_not_recognize_this_media_attachment": "Känner inte igen mediebilagan",
"attachment_too_large": "Bilagan är för stor"
},
"poll": {
"duration_time": "Längd: %s",
@ -459,12 +469,12 @@
"message": "Bekräfta för att avblockera %s"
},
"confirm_show_reblogs": {
"title": "Visa puffar",
"message": "Bekräfta för att visa puffar"
"title": "Visa boostar",
"message": "Bekräfta för att visa boostar"
},
"confirm_hide_reblogs": {
"title": "Dölj puffar",
"message": "Bekräfta för att dölja puffar"
"title": "Dölj boostar",
"message": "Bekräfta för att dölja boostar"
}
},
"accessibility": {
@ -490,7 +500,7 @@
"title": "Favoriserad av"
},
"reblogged_by": {
"title": "Puffat av"
"title": "Boostat av"
},
"search": {
"title": "Sök",
@ -546,7 +556,7 @@
"notification_description": {
"followed_you": "följde dig",
"favorited_your_post": "favoriserade ditt inlägg",
"reblogged_your_post": "puffade ditt inlägg",
"reblogged_your_post": "boostade ditt inlägg",
"mentioned_you": "nämnde dig",
"request_to_follow_you": "begär att följa dig",
"poll_has_ended": "omröstningen har avslutats"
@ -586,7 +596,7 @@
"title": "Notiser",
"favorites": "Favoriserar mitt inlägg",
"follows": "Följer mig",
"boosts": "Ompostar mitt inlägg",
"boosts": "Boostar mitt inlägg",
"mentions": "Nämner mig",
"trigger": {
"anyone": "alla",
@ -672,7 +682,7 @@
"unfollowed": "Slutade följa",
"unfollow_user": "Avfölj %s",
"mute_user": "Tysta %s",
"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.",
"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 boostar 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": "Medan vi granskar detta kan du vidta åtgärder mot %s"
@ -696,7 +706,7 @@
"accessibility_hint": "Dubbeltryck för att avvisa den här guiden"
},
"bookmark": {
"title": "Bookmarks"
"title": "Bokmärken"
}
}
}

View File

@ -136,6 +136,12 @@
"vote": "ลงคะแนน",
"closed": "ปิดแล้ว"
},
"meta_entity": {
"url": "ลิงก์: %s",
"hashtag": "แฮชแท็ก: %s",
"mention": "โปรไฟล์ที่แสดง: %s",
"email": "ที่อยู่อีเมล: %s"
},
"actions": {
"reply": "ตอบกลับ",
"reblog": "ดัน",
@ -181,8 +187,8 @@
"unmute_user": "เลิกซ่อน %s",
"muted": "ซ่อนอยู่",
"edit_info": "แก้ไขข้อมูล",
"show_reblogs": "Show Reblogs",
"hide_reblogs": "Hide Reblogs"
"show_reblogs": "แสดงการดัน",
"hide_reblogs": "ซ่อนการดัน"
},
"timeline": {
"filtered": "กรองอยู่",
@ -215,7 +221,7 @@
"server_picker": {
"title": "Mastodon ประกอบด้วยผู้ใช้ในเซิร์ฟเวอร์ต่าง ๆ",
"subtitle": "เลือกเซิร์ฟเวอร์ตามความสนใจ, ภูมิภาค หรือวัตถุประสงค์ทั่วไปของคุณ",
"subtitle_extend": "เลือกเซิร์ฟเวอร์ตามความสนใจ, ภูมิภาค หรือวัตถุประสงค์ทั่วไปของคุณ แต่ละเซิร์ฟเวอร์ดำเนินการโดยองค์กรหรือบุคคลที่เป็นอิสระโดยสิ้นเชิง",
"subtitle_extend": "เลือกเซิร์ฟเวอร์ตามความสนใจ, ภูมิภาค หรือวัตถุประสงค์ทั่วไปของคุณ แต่ละเซิร์ฟเวอร์ได้รับการดำเนินงานโดยองค์กรหรือบุคคลที่เป็นอิสระโดยสิ้นเชิง",
"button": {
"category": {
"all": "ทั้งหมด",
@ -376,7 +382,11 @@
"video": "วิดีโอ",
"attachment_broken": "%s นี้เสียหายและไม่สามารถ\nอัปโหลดไปยัง Mastodon",
"description_photo": "อธิบายรูปภาพสำหรับผู้บกพร่องทางการมองเห็น...",
"description_video": "อธิบายวิดีโอสำหรับผู้บกพร่องทางการมองเห็น..."
"description_video": "อธิบายวิดีโอสำหรับผู้บกพร่องทางการมองเห็น...",
"load_failed": "การโหลดล้มเหลว",
"upload_failed": "การอัปโหลดล้มเหลว",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "ไฟล์แนบใหญ่เกินไป"
},
"poll": {
"duration_time": "ระยะเวลา: %s",
@ -459,12 +469,12 @@
"message": "ยืนยันเพื่อเลิกปิดกั้น %s"
},
"confirm_show_reblogs": {
"title": "Show Reblogs",
"message": "Confirm to show reblogs"
"title": "แสดงการดัน",
"message": "ยืนยันเพื่อแสดงการดัน"
},
"confirm_hide_reblogs": {
"title": "Hide Reblogs",
"message": "Confirm to hide reblogs"
"title": "ซ่อนการดัน",
"message": "ยืนยันเพื่อซ่อนการดัน"
}
},
"accessibility": {
@ -696,7 +706,7 @@
"accessibility_hint": "แตะสองครั้งเพื่อปิดตัวช่วยสร้างนี้"
},
"bookmark": {
"title": "Bookmarks"
"title": "ที่คั่นหน้า"
}
}
}

View File

@ -136,6 +136,12 @@
"vote": "Oy ver",
"closed": "Kapandı"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Yanıtla",
"reblog": "Yeniden paylaş",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "Bu %s bozuk ve Mastodon'a\nyüklenemiyor.",
"description_photo": "Görme engelliler için fotoğrafı tarif edin...",
"description_video": "Görme engelliler için videoyu tarif edin..."
"description_video": "Görme engelliler için videoyu tarif edin...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Süre: %s",

View File

@ -136,6 +136,12 @@
"vote": "Vote",
"closed": "Closed"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "Reply",
"reblog": "Reblog",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Duration: %s",

View File

@ -136,6 +136,12 @@
"vote": "Bình chọn",
"closed": "Kết thúc"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Hiện hồ sơ: %s",
"email": "Email: %s"
},
"actions": {
"reply": "Trả lời",
"reblog": "Đăng lại",
@ -376,7 +382,11 @@
"video": "video",
"attachment_broken": "%s này bị lỗi và không thể\ntải lên Mastodon.",
"description_photo": "Mô tả hình ảnh cho người khiếm thị...",
"description_video": "Mô tả video cho người khiếm thị..."
"description_video": "Mô tả video cho người khiếm thị...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "Thời hạn: %s",
@ -696,7 +706,7 @@
"accessibility_hint": "Nhấn hai lần để bỏ qua"
},
"bookmark": {
"title": "Bookmarks"
"title": "Tút đã lưu"
}
}
}

View File

@ -136,6 +136,12 @@
"vote": "投票",
"closed": "已关闭"
},
"meta_entity": {
"url": "Link: %s",
"hashtag": "Hashtag: %s",
"mention": "Show Profile: %s",
"email": "Email address: %s"
},
"actions": {
"reply": "回复",
"reblog": "转发",
@ -376,7 +382,11 @@
"video": "视频",
"attachment_broken": "%s已损坏\n无法上传到 Mastodon",
"description_photo": "为视觉障碍人士添加照片的文字说明...",
"description_video": "为视觉障碍人士添加视频的文字说明..."
"description_video": "为视觉障碍人士添加视频的文字说明...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "时长:%s",

View File

@ -136,6 +136,12 @@
"vote": "投票",
"closed": "已關閉"
},
"meta_entity": {
"url": "連結:%s",
"hashtag": "主題標籤: %s",
"mention": "顯示個人檔案:%s",
"email": "電子郵件地址:%s"
},
"actions": {
"reply": "回覆",
"reblog": "轉嘟",
@ -376,7 +382,11 @@
"video": "影片",
"attachment_broken": "此 %s 已損毀,並無法被上傳至 Mastodon。",
"description_photo": "為視障人士提供圖片說明...",
"description_video": "為視障人士提供影片說明..."
"description_video": "為視障人士提供影片說明...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not regonize this media attachment",
"attachment_too_large": "Attachment too large"
},
"poll": {
"duration_time": "持續時間:%s",
@ -696,7 +706,7 @@
"accessibility_hint": "點兩下以關閉此設定精靈"
},
"bookmark": {
"title": "Bookmarks"
"title": "書籤"
}
}
}

View File

@ -382,7 +382,13 @@
"video": "video",
"attachment_broken": "This %s is broken and cant be\nuploaded to Mastodon.",
"description_photo": "Describe the photo for the visually-impaired...",
"description_video": "Describe the video for the visually-impaired..."
"description_video": "Describe the video for the visually-impaired...",
"load_failed": "Load Failed",
"upload_failed": "Upload Failed",
"can_not_recognize_this_media_attachment": "Can not recognize this media attachment",
"attachment_too_large": "Attachment too large",
"compressing_state": "Compressing...",
"server_processing_state": "Server Processing..."
},
"poll": {
"duration_time": "Duration: %s",
@ -392,7 +398,9 @@
"one_day": "1 Day",
"three_days": "3 Days",
"seven_days": "7 Days",
"option_number": "Option %ld"
"option_number": "Option %ld",
"the_poll_is_invalid": "The poll is invalid",
"the_poll_has_empty_option": "The poll has empty option"
},
"content_warning": {
"placeholder": "Write an accurate warning here..."
@ -413,7 +421,9 @@
"custom_emoji_picker": "Custom Emoji Picker",
"enable_content_warning": "Enable Content Warning",
"disable_content_warning": "Disable Content Warning",
"post_visibility_menu": "Post Visibility Menu"
"post_visibility_menu": "Post Visibility Menu",
"post_options": "Post Options",
"posting_as": "Posting as %s"
},
"keyboard": {
"discard_post": "Discard Post",
@ -438,6 +448,10 @@
"placeholder": {
"label": "Label",
"content": "Content"
},
"verified": {
"short": "Verified on %s",
"long": "Ownership of this link was checked on %s"
}
},
"segmented_control": {
@ -705,4 +719,4 @@
"title": "Bookmarks"
}
}
}
}

View File

@ -152,7 +152,6 @@
DB1FD44425F26CCC004CFCFC /* PickServerSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1FD44325F26CCC004CFCFC /* PickServerSection.swift */; };
DB1FD45025F26FA1004CFCFC /* MastodonPickServerViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1FD44F25F26FA1004CFCFC /* MastodonPickServerViewModel+Diffable.swift */; };
DB1FD45A25F27898004CFCFC /* CategoryPickerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB1FD45925F27898004CFCFC /* CategoryPickerItem.swift */; };
DB221B16260C395900AEFE46 /* CustomEmojiPickerInputViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB221B15260C395900AEFE46 /* CustomEmojiPickerInputViewModel.swift */; };
DB22C92228E700A10082A9E9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DB22C92128E700A10082A9E9 /* MastodonSDK */; };
DB22C92428E700A80082A9E9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DB22C92328E700A80082A9E9 /* MastodonSDK */; };
DB22C92628E700AF0082A9E9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DB22C92528E700AF0082A9E9 /* MastodonSDK */; };
@ -186,9 +185,6 @@
DB427DED25BAA00100D1B89D /* MastodonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DEC25BAA00100D1B89D /* MastodonTests.swift */; };
DB427DF825BAA00100D1B89D /* MastodonUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DF725BAA00100D1B89D /* MastodonUITests.swift */; };
DB443CD42694627B00159B29 /* AppearanceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB443CD32694627B00159B29 /* AppearanceView.swift */; };
DB44767B260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB44767A260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift */; };
DB447691260B406600B66B82 /* CustomEmojiPickerItemCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB447690260B406600B66B82 /* CustomEmojiPickerItemCollectionViewCell.swift */; };
DB447697260B439000B66B82 /* CustomEmojiPickerHeaderCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB447696260B439000B66B82 /* CustomEmojiPickerHeaderCollectionReusableView.swift */; };
DB4481B925EE289600BEFB67 /* UITableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4481B825EE289600BEFB67 /* UITableView.swift */; };
DB45FAB625CA5485005A8AC7 /* UIAlertController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FAB525CA5485005A8AC7 /* UIAlertController.swift */; };
DB45FAD725CA6C76005A8AC7 /* UIBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FAD625CA6C76005A8AC7 /* UIBarButtonItem.swift */; };
@ -258,7 +254,6 @@
DB64BA452851F23000ADF1B7 /* MastodonAuthentication+Fetch.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB64BA442851F23000ADF1B7 /* MastodonAuthentication+Fetch.swift */; };
DB64BA482851F29300ADF1B7 /* Account+Fetch.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB64BA472851F29300ADF1B7 /* Account+Fetch.swift */; };
DB65C63727A2AF6C008BAC2E /* ReportItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB65C63627A2AF6C008BAC2E /* ReportItem.swift */; };
DB66728C25F9F8DC00D60309 /* ComposeViewModel+DataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB66728B25F9F8DC00D60309 /* ComposeViewModel+DataSource.swift */; };
DB6746EB278ED8B0008A6B94 /* PollOptionView+Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6746EA278ED8B0008A6B94 /* PollOptionView+Configuration.swift */; };
DB6746ED278F45F0008A6B94 /* AutoGenerateProtocolRelayDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6746EC278F45F0008A6B94 /* AutoGenerateProtocolRelayDelegate.swift */; };
DB6746F0278F463B008A6B94 /* AutoGenerateProtocolDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB6746EF278F463B008A6B94 /* AutoGenerateProtocolDelegate.swift */; };
@ -338,7 +333,6 @@
DB98EB6927B21A7C0082E365 /* ReportResultActionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB6827B21A7C0082E365 /* ReportResultActionTableViewCell.swift */; };
DB98EB6B27B243470082E365 /* SettingsAppearanceTableViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB6A27B243470082E365 /* SettingsAppearanceTableViewCell+ViewModel.swift */; };
DB9A486C26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A486B26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift */; };
DB9A488A26034D40008B817C /* ComposeViewModel+PublishState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9A488926034D40008B817C /* ComposeViewModel+PublishState.swift */; };
DB9D6BE925E4F5340051B173 /* SearchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6BE825E4F5340051B173 /* SearchViewController.swift */; };
DB9D6BF825E4F5690051B173 /* NotificationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6BF725E4F5690051B173 /* NotificationViewController.swift */; };
DB9D6BFF25E4F5940051B173 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D6BFE25E4F5940051B173 /* ProfileViewController.swift */; };
@ -377,12 +371,11 @@
DBB8AB4626AECDE200F6D281 /* SendPostIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB8AB4526AECDE200F6D281 /* SendPostIntentHandler.swift */; };
DBB8AB4F26AED13F00F6D281 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB427DDE25BAA00100D1B89D /* Assets.xcassets */; };
DBB9759C262462E1004620BD /* ThreadMetaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB9759B262462E1004620BD /* ThreadMetaView.swift */; };
DBBC24DC26A54BCB00398BB9 /* MastodonRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24D626A54BCB00398BB9 /* MastodonRegex.swift */; };
DBBE1B4525F3474B0081417A /* MastodonPickServerAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBE1B4425F3474B0081417A /* MastodonPickServerAppearance.swift */; };
DBC6461526A170AB00B0E31B /* ComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC6461426A170AB00B0E31B /* ComposeViewController.swift */; };
DBC3872429214121001EC0FD /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC3872329214121001EC0FD /* ShareViewController.swift */; };
DBC6461826A170AB00B0E31B /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DBC6461626A170AB00B0E31B /* MainInterface.storyboard */; };
DBC6461C26A170AB00B0E31B /* ShareActionExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
DBC6462326A1712000B0E31B /* ComposeViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC6462226A1712000B0E31B /* ComposeViewModel.swift */; };
DBC6462326A1712000B0E31B /* ShareViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC6462226A1712000B0E31B /* ShareViewModel.swift */; };
DBC6462826A1736300B0E31B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB427DDE25BAA00100D1B89D /* Assets.xcassets */; };
DBC7A672260C897100E57475 /* StatusContentWarningEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC7A671260C897100E57475 /* StatusContentWarningEditorView.swift */; };
DBCA0EBC282BB38A0029E2B0 /* PageboyNavigateable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCA0EBB282BB38A0029E2B0 /* PageboyNavigateable.swift */; };
@ -683,7 +676,6 @@
DB1FD44F25F26FA1004CFCFC /* MastodonPickServerViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonPickServerViewModel+Diffable.swift"; sourceTree = "<group>"; };
DB1FD45925F27898004CFCFC /* CategoryPickerItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryPickerItem.swift; sourceTree = "<group>"; };
DB1FD45F25F278AF004CFCFC /* CategoryPickerSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryPickerSection.swift; sourceTree = "<group>"; };
DB221B15260C395900AEFE46 /* CustomEmojiPickerInputViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiPickerInputViewModel.swift; sourceTree = "<group>"; };
DB2B3ABD25E37E15007045F9 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationViewModel.swift; sourceTree = "<group>"; };
DB2FF50F260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeStatusPollExpiresOptionCollectionViewCell.swift; sourceTree = "<group>"; };
@ -720,9 +712,6 @@
DB427DF725BAA00100D1B89D /* MastodonUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonUITests.swift; sourceTree = "<group>"; };
DB427DF925BAA00100D1B89D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DB443CD32694627B00159B29 /* AppearanceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceView.swift; sourceTree = "<group>"; };
DB44767A260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiPickerInputView.swift; sourceTree = "<group>"; };
DB447690260B406600B66B82 /* CustomEmojiPickerItemCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiPickerItemCollectionViewCell.swift; sourceTree = "<group>"; };
DB447696260B439000B66B82 /* CustomEmojiPickerHeaderCollectionReusableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiPickerHeaderCollectionReusableView.swift; sourceTree = "<group>"; };
DB4481B825EE289600BEFB67 /* UITableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UITableView.swift; sourceTree = "<group>"; };
DB45FAB525CA5485005A8AC7 /* UIAlertController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAlertController.swift; sourceTree = "<group>"; };
DB45FAD625CA6C76005A8AC7 /* UIBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIBarButtonItem.swift; sourceTree = "<group>"; };
@ -822,7 +811,6 @@
DB64BA442851F23000ADF1B7 /* MastodonAuthentication+Fetch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonAuthentication+Fetch.swift"; sourceTree = "<group>"; };
DB64BA472851F29300ADF1B7 /* Account+Fetch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Fetch.swift"; sourceTree = "<group>"; };
DB65C63627A2AF6C008BAC2E /* ReportItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportItem.swift; sourceTree = "<group>"; };
DB66728B25F9F8DC00D60309 /* ComposeViewModel+DataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ComposeViewModel+DataSource.swift"; sourceTree = "<group>"; };
DB6746EA278ED8B0008A6B94 /* PollOptionView+Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PollOptionView+Configuration.swift"; sourceTree = "<group>"; };
DB6746EC278F45F0008A6B94 /* AutoGenerateProtocolRelayDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoGenerateProtocolRelayDelegate.swift; sourceTree = "<group>"; };
DB6746EF278F463B008A6B94 /* AutoGenerateProtocolDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoGenerateProtocolDelegate.swift; sourceTree = "<group>"; };
@ -914,7 +902,6 @@
DB98EB6827B21A7C0082E365 /* ReportResultActionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportResultActionTableViewCell.swift; sourceTree = "<group>"; };
DB98EB6A27B243470082E365 /* SettingsAppearanceTableViewCell+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SettingsAppearanceTableViewCell+ViewModel.swift"; sourceTree = "<group>"; };
DB9A486B26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AttachmentContainerView+EmptyStateView.swift"; sourceTree = "<group>"; };
DB9A488926034D40008B817C /* ComposeViewModel+PublishState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ComposeViewModel+PublishState.swift"; sourceTree = "<group>"; };
DB9D6BE825E4F5340051B173 /* SearchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchViewController.swift; sourceTree = "<group>"; };
DB9D6BF725E4F5690051B173 /* NotificationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationViewController.swift; sourceTree = "<group>"; };
DB9D6BFE25E4F5940051B173 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = "<group>"; };
@ -963,14 +950,12 @@
DBB525632612C988002F1F29 /* MeProfileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeProfileViewModel.swift; sourceTree = "<group>"; };
DBB8AB4526AECDE200F6D281 /* SendPostIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendPostIntentHandler.swift; sourceTree = "<group>"; };
DBB9759B262462E1004620BD /* ThreadMetaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadMetaView.swift; sourceTree = "<group>"; };
DBBC24A726A52F9000398BB9 /* ComposeToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeToolbarView.swift; sourceTree = "<group>"; };
DBBC24D626A54BCB00398BB9 /* MastodonRegex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MastodonRegex.swift; sourceTree = "<group>"; };
DBBE1B4425F3474B0081417A /* MastodonPickServerAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonPickServerAppearance.swift; sourceTree = "<group>"; };
DBC3872329214121001EC0FD /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareActionExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
DBC6461426A170AB00B0E31B /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = "<group>"; };
DBC6461726A170AB00B0E31B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
DBC6461926A170AB00B0E31B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
DBC6462226A1712000B0E31B /* ComposeViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComposeViewModel.swift; sourceTree = "<group>"; };
DBC6462226A1712000B0E31B /* ShareViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareViewModel.swift; sourceTree = "<group>"; };
DBC7A671260C897100E57475 /* StatusContentWarningEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusContentWarningEditorView.swift; sourceTree = "<group>"; };
DBC9E3A3282E13BB0063A4D9 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Intents.strings; sourceTree = "<group>"; };
DBC9E3A4282E13BB0063A4D9 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/InfoPlist.strings; sourceTree = "<group>"; };
@ -1044,15 +1029,7 @@
DBFEEC98279BDCDE004F81DD /* ProfileAboutViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileAboutViewModel.swift; sourceTree = "<group>"; };
DBFEEC9A279BDDD9004F81DD /* ProfileAboutViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProfileAboutViewModel+Diffable.swift"; sourceTree = "<group>"; };
DBFEEC9C279C12C1004F81DD /* ProfileFieldEditCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileFieldEditCollectionViewCell.swift; sourceTree = "<group>"; };
DBFEF05526A576EE006D7ED1 /* StatusEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusEditorView.swift; sourceTree = "<group>"; };
DBFEF05626A576EE006D7ED1 /* ComposeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeView.swift; sourceTree = "<group>"; };
DBFEF05726A576EE006D7ED1 /* ComposeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewModel.swift; sourceTree = "<group>"; };
DBFEF05826A576EE006D7ED1 /* ContentWarningEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentWarningEditorView.swift; sourceTree = "<group>"; };
DBFEF05926A576EE006D7ED1 /* StatusAuthorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusAuthorView.swift; sourceTree = "<group>"; };
DBFEF05A26A576EE006D7ED1 /* StatusAttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusAttachmentView.swift; sourceTree = "<group>"; };
DBFEF06226A577F2006D7ED1 /* StatusAttachmentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusAttachmentViewModel.swift; sourceTree = "<group>"; };
DBFEF06726A58D07006D7ED1 /* ShareActionExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ShareActionExtension.entitlements; sourceTree = "<group>"; };
DBFEF06C26A67FB7006D7ED1 /* StatusAttachmentViewModel+UploadState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "StatusAttachmentViewModel+UploadState.swift"; sourceTree = "<group>"; };
DDB1B139FA8EA26F510D58B6 /* Pods-AppShared.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.asdk - release.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.asdk - release.xcconfig"; sourceTree = "<group>"; };
DF65937EC1FF64462BC002EE /* Pods-MastodonTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.profile.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.profile.xcconfig"; sourceTree = "<group>"; };
E5C7236E58D14A0322FE00F2 /* Pods-Mastodon-MastodonUITests.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk - debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk - debug.xcconfig"; sourceTree = "<group>"; };
@ -1344,7 +1321,7 @@
path = Protocol;
sourceTree = "<group>";
};
2D76319C25C151DE00929FB9 /* Diffiable */ = {
2D76319C25C151DE00929FB9 /* Diffable */ = {
isa = PBXGroup;
children = (
DB4F097826A039B400D62E92 /* Onboarding */,
@ -1359,7 +1336,7 @@
DB3E6FE52806A5BA00B035AE /* Discovery */,
DB0617FA27855B660030EE79 /* Settings */,
);
path = Diffiable;
path = Diffable;
sourceTree = "<group>";
};
2D7631A425C1532200929FB9 /* Share */ = {
@ -1764,7 +1741,7 @@
children = (
DB89BA1025C10FF5008580ED /* Mastodon.entitlements */,
DB427DE325BAA00100D1B89D /* Info.plist */,
2D76319C25C151DE00929FB9 /* Diffiable */,
2D76319C25C151DE00929FB9 /* Diffable */,
DB8AF55525C1379F002E6C99 /* Scene */,
DB8AF54125C13647002E6C99 /* Coordinator */,
DB8AF56225C138BC002E6C99 /* Extension */,
@ -1880,8 +1857,6 @@
DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */,
DB8190C52601FF0400020C08 /* AttachmentContainerView.swift */,
DB9A486B26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift */,
DB44767A260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift */,
DB221B15260C395900AEFE46 /* CustomEmojiPickerInputViewModel.swift */,
DBC7A671260C897100E57475 /* StatusContentWarningEditorView.swift */,
);
path = View;
@ -2148,8 +2123,6 @@
DB789A2125F9F76D0071ACA0 /* CollectionViewCell */,
DB789A0A25F9F2950071ACA0 /* ComposeViewController.swift */,
DB789A1125F9F2CC0071ACA0 /* ComposeViewModel.swift */,
DB66728B25F9F8DC00D60309 /* ComposeViewModel+DataSource.swift */,
DB9A488926034D40008B817C /* ComposeViewModel+PublishState.swift */,
);
path = Compose;
sourceTree = "<group>";
@ -2161,8 +2134,6 @@
DB87D4442609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift */,
DB87D4502609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift */,
DB2FF50F260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift */,
DB447690260B406600B66B82 /* CustomEmojiPickerItemCollectionViewCell.swift */,
DB447696260B439000B66B82 /* CustomEmojiPickerHeaderCollectionReusableView.swift */,
);
path = CollectionViewCell;
sourceTree = "<group>";
@ -2523,7 +2494,6 @@
DBBC24D526A54BCB00398BB9 /* Helper */ = {
isa = PBXGroup;
children = (
DBBC24D626A54BCB00398BB9 /* MastodonRegex.swift */,
DBF3B7402733EB9400E21627 /* MastodonLocalCode.swift */,
);
path = Helper;
@ -2690,28 +2660,11 @@
path = Cell;
sourceTree = "<group>";
};
DBFEF05426A576EE006D7ED1 /* View */ = {
isa = PBXGroup;
children = (
DBBC24A726A52F9000398BB9 /* ComposeToolbarView.swift */,
DBFEF05526A576EE006D7ED1 /* StatusEditorView.swift */,
DBFEF05626A576EE006D7ED1 /* ComposeView.swift */,
DBFEF05726A576EE006D7ED1 /* ComposeViewModel.swift */,
DBFEF05826A576EE006D7ED1 /* ContentWarningEditorView.swift */,
DBFEF05926A576EE006D7ED1 /* StatusAuthorView.swift */,
DBFEF05A26A576EE006D7ED1 /* StatusAttachmentView.swift */,
DBFEF06226A577F2006D7ED1 /* StatusAttachmentViewModel.swift */,
DBFEF06C26A67FB7006D7ED1 /* StatusAttachmentViewModel+UploadState.swift */,
);
path = View;
sourceTree = "<group>";
};
DBFEF06126A57721006D7ED1 /* Scene */ = {
isa = PBXGroup;
children = (
DBFEF05426A576EE006D7ED1 /* View */,
DBC6462226A1712000B0E31B /* ComposeViewModel.swift */,
DBC6461426A170AB00B0E31B /* ComposeViewController.swift */,
DBC6462226A1712000B0E31B /* ShareViewModel.swift */,
DBC3872329214121001EC0FD /* ShareViewController.swift */,
);
path = Scene;
sourceTree = "<group>";
@ -3201,7 +3154,6 @@
0F1E2D0B2615C39400C38565 /* DoubleTitleLabelNavigationBarTitleView.swift in Sources */,
DBDFF1902805543100557A48 /* DiscoveryPostsViewController.swift in Sources */,
DB697DD9278F4CED004EF2F7 /* HomeTimelineViewController+DataSourceProvider.swift in Sources */,
DB9A488A26034D40008B817C /* ComposeViewModel+PublishState.swift in Sources */,
DB45FAD725CA6C76005A8AC7 /* UIBarButtonItem.swift in Sources */,
2D8434F525FF465D00EECE90 /* HomeTimelineNavigationBarTitleViewModel.swift in Sources */,
DB938F0F2624119800E5B6C1 /* ThreadViewModel+LoadThreadState.swift in Sources */,
@ -3249,7 +3201,6 @@
DBFEEC9D279C12C1004F81DD /* ProfileFieldEditCollectionViewCell.swift in Sources */,
DB3E6FEC2806D7F100B035AE /* DiscoveryNewsViewController.swift in Sources */,
DB2FF510260B113300ADA9FE /* ComposeStatusPollExpiresOptionCollectionViewCell.swift in Sources */,
DBBC24DC26A54BCB00398BB9 /* MastodonRegex.swift in Sources */,
DBCBED1726132DB500B49291 /* UserTimelineViewModel+Diffable.swift in Sources */,
2DE0FACE2615F7AD00CDF649 /* RecommendAccountSection.swift in Sources */,
2DAC9E3E262FC2400062E1A6 /* SuggestionAccountViewModel.swift in Sources */,
@ -3304,7 +3255,6 @@
DB63F7492799126300455B82 /* FollowerListViewController+DataSourceProvider.swift in Sources */,
2D198643261BF09500F0B013 /* SearchResultItem.swift in Sources */,
2DAC9E38262FC2320062E1A6 /* SuggestionAccountViewController.swift in Sources */,
DB66728C25F9F8DC00D60309 /* ComposeViewModel+DataSource.swift in Sources */,
DB6180E02639194B0018D199 /* MediaPreviewPagingViewController.swift in Sources */,
DBE0822425CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift in Sources */,
5B90C45E262599800002E742 /* SettingsViewModel.swift in Sources */,
@ -3342,7 +3292,6 @@
DB98EB6227B215EB0082E365 /* ReportResultViewController.swift in Sources */,
DB6B74F4272FBAE700C70B6E /* FollowerListViewModel+Diffable.swift in Sources */,
DB6B74F2272FB67600C70B6E /* FollowerListViewModel.swift in Sources */,
DB44767B260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift in Sources */,
0F20222D261457EE000C64BF /* HashtagTimelineViewModel+State.swift in Sources */,
DB0009A626AEE5DC009B9D2D /* Intents.intentdefinition in Sources */,
5B90C462262599800002E742 /* SettingsSectionHeader.swift in Sources */,
@ -3356,7 +3305,6 @@
DBFEEC9B279BDDD9004F81DD /* ProfileAboutViewModel+Diffable.swift in Sources */,
DBB525562611EDCA002F1F29 /* UserTimelineViewModel.swift in Sources */,
DB0618012785732C0030EE79 /* ServerRulesTableViewCell.swift in Sources */,
DB221B16260C395900AEFE46 /* CustomEmojiPickerInputViewModel.swift in Sources */,
DB98EB5C27B10A730082E365 /* ReportSupplementaryViewModel.swift in Sources */,
DB0617EF277F12720030EE79 /* NavigationActionView.swift in Sources */,
DB1FD43625F26899004CFCFC /* MastodonPickServerViewModel+LoadIndexedServerState.swift in Sources */,
@ -3440,7 +3388,6 @@
2D35237A26256D920031AF25 /* NotificationSection.swift in Sources */,
2D4AD89C263165B500613EFC /* SuggestionAccountCollectionViewCell.swift in Sources */,
DB98EB6927B21A7C0082E365 /* ReportResultActionTableViewCell.swift in Sources */,
DB447691260B406600B66B82 /* CustomEmojiPickerItemCollectionViewCell.swift in Sources */,
DB9282B225F3222800823B15 /* PickServerEmptyStateView.swift in Sources */,
DB697DDF278F524F004EF2F7 /* DataSourceFacade+Profile.swift in Sources */,
DB1FD45025F26FA1004CFCFC /* MastodonPickServerViewModel+Diffable.swift in Sources */,
@ -3464,7 +3411,6 @@
DB63F74D27993F5B00455B82 /* SearchHistoryUserCollectionViewCell.swift in Sources */,
DB8AF54425C13647002E6C99 /* SceneCoordinator.swift in Sources */,
DB1D84382657B275000346B3 /* SegmentedControlNavigateable.swift in Sources */,
DB447697260B439000B66B82 /* CustomEmojiPickerHeaderCollectionReusableView.swift in Sources */,
0F20220726134DA4000C64BF /* HashtagTimelineViewModel+Diffable.swift in Sources */,
DB7A9F932818F33C0016AF98 /* MastodonServerRulesViewController+Debug.swift in Sources */,
2D5A3D2825CF8BC9002347D6 /* HomeTimelineViewModel+Diffable.swift in Sources */,
@ -3571,9 +3517,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DBC6462326A1712000B0E31B /* ComposeViewModel.swift in Sources */,
DBC6462326A1712000B0E31B /* ShareViewModel.swift in Sources */,
DBB3BA2B26A81D060004F2D4 /* FLAnimatedImageView.swift in Sources */,
DBC6461526A170AB00B0E31B /* ComposeViewController.swift in Sources */,
DBC3872429214121001EC0FD /* ShareViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -117,7 +117,7 @@
<key>NotificationService.xcscheme_^#shared#^_</key>
<dict>
<key>orderHint</key>
<integer>18</integer>
<integer>16</integer>
</dict>
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
<dict>

View File

@ -90,6 +90,15 @@
"version" : "2.2.5"
}
},
{
"identity" : "nextlevelsessionexporter",
"kind" : "remoteSourceControl",
"location" : "https://github.com/NextLevel/NextLevelSessionExporter.git",
"state" : {
"revision" : "b6c0cce1aa37fe1547d694f958fac3c3524b74da",
"version" : "0.4.6"
}
},
{
"identity" : "nuke",
"kind" : "remoteSourceControl",

View File

@ -23,6 +23,7 @@ extension ProfileFieldItem {
var name: CurrentValueSubject<String, Never>
var value: CurrentValueSubject<String, Never>
var verifiedAt: CurrentValueSubject<Date?, Never>
let emojiMeta: MastodonContent.Emojis
@ -30,11 +31,13 @@ extension ProfileFieldItem {
id: UUID = UUID(),
name: String,
value: String,
verifiedAt: Date?,
emojiMeta: MastodonContent.Emojis
) {
self.id = id
self.name = CurrentValueSubject(name)
self.value = CurrentValueSubject(value)
self.verifiedAt = CurrentValueSubject(verifiedAt)
self.emojiMeta = emojiMeta
}
@ -45,6 +48,7 @@ extension ProfileFieldItem {
return lhs.id == rhs.id
&& lhs.name.value == rhs.name.value
&& lhs.value.value == rhs.value.value
&& lhs.verifiedAt.value == rhs.verifiedAt.value
&& lhs.emojiMeta == rhs.emojiMeta
}

View File

@ -8,6 +8,7 @@
import os
import UIKit
import Combine
import MastodonAsset
import MastodonCore
import MastodonMeta
import MastodonLocalization
@ -48,6 +49,10 @@ extension ProfileFieldSection {
do {
let mastodonContent = MastodonContent(content: field.value.value, emojis: field.emojiMeta)
let metaContent = try MastodonMetaContent.convert(document: mastodonContent)
cell.valueMetaLabel.linkAttributes[.foregroundColor] = Asset.Colors.brand.color
if field.verifiedAt.value != nil {
cell.valueMetaLabel.linkAttributes[.foregroundColor] = Asset.Scene.Profile.About.bioAboutFieldVerifiedLink.color
}
cell.valueMetaLabel.configure(content: metaContent)
} catch {
let content = PlaintextMetaContent(string: field.value.value)
@ -57,7 +62,23 @@ extension ProfileFieldSection {
// set background
var backgroundConfiguration = UIBackgroundConfiguration.listPlainCell()
backgroundConfiguration.backgroundColor = UIColor.secondarySystemBackground
if (field.verifiedAt.value != nil) {
backgroundConfiguration.backgroundColor = Asset.Scene.Profile.About.bioAboutFieldVerifiedBackground.color
}
cell.backgroundConfiguration = backgroundConfiguration
// set checkmark and edit menu label
cell.checkmark.isHidden = true
cell.checkmarkPopoverString = nil
if let verifiedAt = field.verifiedAt.value {
cell.checkmark.isHidden = false
let formatter = DateFormatter()
formatter.dateStyle = .medium
formatter.timeStyle = .short
let dateString = formatter.string(from: verifiedAt)
cell.checkmark.accessibilityLabel = L10n.Scene.Profile.Fields.Verified.long(dateString)
cell.checkmarkPopoverString = L10n.Scene.Profile.Fields.Verified.short(dateString)
}
cell.delegate = configuration.profileFieldCollectionViewCellDelegate
}

File diff suppressed because it is too large Load Diff

View File

@ -1,490 +0,0 @@
//
// ComposeViewModel+Diffable.swift
// Mastodon
//
// Created by MainasuK Cirno on 2021-3-11.
//
import os.log
import UIKit
import Combine
import CoreDataStack
import MetaTextKit
import MastodonMeta
import MastodonAsset
import MastodonCore
import MastodonLocalization
import MastodonSDK
extension ComposeViewModel {
// func setupDataSource(
// tableView: UITableView,
// metaTextDelegate: MetaTextDelegate,
// metaTextViewDelegate: UITextViewDelegate,
// customEmojiPickerInputViewModel: CustomEmojiPickerInputViewModel,
// composeStatusAttachmentCollectionViewCellDelegate: ComposeStatusAttachmentCollectionViewCellDelegate,
// composeStatusPollOptionCollectionViewCellDelegate: ComposeStatusPollOptionCollectionViewCellDelegate,
// composeStatusPollOptionAppendEntryCollectionViewCellDelegate: ComposeStatusPollOptionAppendEntryCollectionViewCellDelegate,
// composeStatusPollExpiresOptionCollectionViewCellDelegate: ComposeStatusPollExpiresOptionCollectionViewCellDelegate
// ) {
// // UI
// bind()
//
// // content
// bind(cell: composeStatusContentTableViewCell, tableView: tableView)
// composeStatusContentTableViewCell.metaText.delegate = metaTextDelegate
// composeStatusContentTableViewCell.metaText.textView.delegate = metaTextViewDelegate
//
// // attachment
// bind(cell: composeStatusAttachmentTableViewCell, tableView: tableView)
// composeStatusAttachmentTableViewCell.composeStatusAttachmentCollectionViewCellDelegate = composeStatusAttachmentCollectionViewCellDelegate
//
// // poll
// bind(cell: composeStatusPollTableViewCell, tableView: tableView)
// composeStatusPollTableViewCell.delegate = self
// composeStatusPollTableViewCell.customEmojiPickerInputViewModel = customEmojiPickerInputViewModel
// composeStatusPollTableViewCell.composeStatusPollOptionCollectionViewCellDelegate = composeStatusPollOptionCollectionViewCellDelegate
// composeStatusPollTableViewCell.composeStatusPollOptionAppendEntryCollectionViewCellDelegate = composeStatusPollOptionAppendEntryCollectionViewCellDelegate
// composeStatusPollTableViewCell.composeStatusPollExpiresOptionCollectionViewCellDelegate = composeStatusPollExpiresOptionCollectionViewCellDelegate
//
// // setup data source
// tableView.dataSource = self
// }
//
// func setupCustomEmojiPickerDiffableDataSource(
// for collectionView: UICollectionView,
// dependency: NeedsDependency
// ) {
// let diffableDataSource = CustomEmojiPickerSection.collectionViewDiffableDataSource(
// for: collectionView,
// dependency: dependency
// )
// self.customEmojiPickerDiffableDataSource = diffableDataSource
//
// let _domain = customEmojiViewModel?.domain
// customEmojiViewModel?.emojis
// .receive(on: DispatchQueue.main)
// .sink { [weak self, weak diffableDataSource] emojis in
// guard let _ = self else { return }
// guard let diffableDataSource = diffableDataSource else { return }
//
// var snapshot = NSDiffableDataSourceSnapshot<CustomEmojiPickerSection, CustomEmojiPickerItem>()
// let domain = _domain?.uppercased() ?? " "
// let customEmojiSection = CustomEmojiPickerSection.emoji(name: domain)
// snapshot.appendSections([customEmojiSection])
// let items: [CustomEmojiPickerItem] = {
// var items = [CustomEmojiPickerItem]()
// for emoji in emojis where emoji.visibleInPicker {
// let attribute = CustomEmojiPickerItem.CustomEmojiAttribute(emoji: emoji)
// let item = CustomEmojiPickerItem.emoji(attribute: attribute)
// items.append(item)
// }
// return items
// }()
// snapshot.appendItems(items, toSection: customEmojiSection)
//
// diffableDataSource.apply(snapshot)
// }
// .store(in: &disposeBag)
// }
}
//// MARK: - UITableViewDataSource
//extension ComposeViewModel: UITableViewDataSource {
// func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// switch Section.allCases[indexPath.section] {
// case .repliedTo:
// let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ComposeRepliedToStatusContentTableViewCell.self), for: indexPath) as! ComposeRepliedToStatusContentTableViewCell
// guard case let .reply(record) = composeKind else { return cell }
//
// // bind frame publisher
// cell.framePublisher
// .receive(on: DispatchQueue.main)
// .assign(to: \.repliedToCellFrame, on: self)
// .store(in: &cell.disposeBag)
//
// // set initial width
// if cell.statusView.frame.width == .zero {
// cell.statusView.frame.size.width = tableView.frame.width
// }
//
// // configure status
// context.managedObjectContext.performAndWait {
// guard let replyTo = record.object(in: context.managedObjectContext) else { return }
// cell.statusView.configure(status: replyTo)
// }
//
// return cell
// case .status:
// return composeStatusContentTableViewCell
// case .attachment:
// return composeStatusAttachmentTableViewCell
// case .poll:
// return composeStatusPollTableViewCell
// }
// }
//}
//// MARK: - ComposeStatusPollTableViewCellDelegate
//extension ComposeViewModel: ComposeStatusPollTableViewCellDelegate {
// func composeStatusPollTableViewCell(_ cell: ComposeStatusPollTableViewCell, pollOptionAttributesDidReorder options: [ComposeStatusPollItem.PollOptionAttribute]) {
// os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
//
// self.pollOptionAttributes = options
// }
//}
//
//extension ComposeViewModel {
// private func bind() {
// $isCustomEmojiComposing
// .assign(to: \.value, on: customEmojiPickerInputViewModel.isCustomEmojiComposing)
// .store(in: &disposeBag)
//
// $isContentWarningComposing
// .assign(to: \.isContentWarningComposing, on: composeStatusAttribute)
// .store(in: &disposeBag)
//
// // bind compose toolbar UI state
// Publishers.CombineLatest(
// $isPollComposing,
// $attachmentServices
// )
// .receive(on: DispatchQueue.main)
// .sink(receiveValue: { [weak self] isPollComposing, attachmentServices in
// guard let self = self else { return }
// let shouldMediaDisable = isPollComposing || attachmentServices.count >= self.maxMediaAttachments
// let shouldPollDisable = attachmentServices.count > 0
//
// self.isMediaToolbarButtonEnabled = !shouldMediaDisable
// self.isPollToolbarButtonEnabled = !shouldPollDisable
// })
// .store(in: &disposeBag)
//
// // calculate `Idempotency-Key`
// let content = Publishers.CombineLatest3(
// composeStatusAttribute.$isContentWarningComposing,
// composeStatusAttribute.$contentWarningContent,
// composeStatusAttribute.$composeContent
// )
// .map { isContentWarningComposing, contentWarningContent, composeContent -> String in
// if isContentWarningComposing {
// return contentWarningContent + (composeContent ?? "")
// } else {
// return composeContent ?? ""
// }
// }
// let attachmentIDs = $attachmentServices.map { attachments -> String in
// let attachmentIDs = attachments.compactMap { $0.attachment.value?.id }
// return attachmentIDs.joined(separator: ",")
// }
// let pollOptionsAndDuration = Publishers.CombineLatest3(
// $isPollComposing,
// $pollOptionAttributes,
// pollExpiresOptionAttribute.expiresOption
// )
// .map { isPollComposing, pollOptionAttributes, expiresOption -> String in
// guard isPollComposing else {
// return ""
// }
//
// let pollOptions = pollOptionAttributes.map { $0.option.value }.joined(separator: ",")
// return pollOptions + expiresOption.rawValue
// }
//
// Publishers.CombineLatest4(
// content,
// attachmentIDs,
// pollOptionsAndDuration,
// $selectedStatusVisibility
// )
// .map { content, attachmentIDs, pollOptionsAndDuration, selectedStatusVisibility -> String in
// var hasher = Hasher()
// hasher.combine(content)
// hasher.combine(attachmentIDs)
// hasher.combine(pollOptionsAndDuration)
// hasher.combine(selectedStatusVisibility.visibility.rawValue)
// let hashValue = hasher.finalize()
// return "\(hashValue)"
// }
// .assign(to: \.value, on: idempotencyKey)
// .store(in: &disposeBag)
//
// // bind modal dismiss state
// composeStatusAttribute.$composeContent
// .receive(on: DispatchQueue.main)
// .map { [weak self] content in
// let content = content ?? ""
// if content.isEmpty {
// return true
// }
// // if preInsertedContent plus a space is equal to the content, simply dismiss the modal
// if let preInsertedContent = self?.preInsertedContent {
// return content == preInsertedContent
// }
// return false
// }
// .assign(to: &$shouldDismiss)
//
// // bind compose bar button item UI state
// let isComposeContentEmpty = composeStatusAttribute.$composeContent
// .map { ($0 ?? "").isEmpty }
// let isComposeContentValid = $characterCount
// .compactMap { [weak self] characterCount -> Bool in
// guard let self = self else { return characterCount <= 500 }
// return characterCount <= self.composeContentLimit
// }
// let isMediaEmpty = $attachmentServices
// .map { $0.isEmpty }
// let isMediaUploadAllSuccess = $attachmentServices
// .map { services in
// services.allSatisfy { $0.uploadStateMachineSubject.value is MastodonAttachmentService.UploadState.Finish }
// }
// let isPollAttributeAllValid = $pollOptionAttributes
// .map { pollAttributes in
// pollAttributes.allSatisfy { attribute -> Bool in
// !attribute.option.value.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
// }
// }
//
// let isPublishBarButtonItemEnabledPrecondition1 = Publishers.CombineLatest4(
// isComposeContentEmpty,
// isComposeContentValid,
// isMediaEmpty,
// isMediaUploadAllSuccess
// )
// .map { isComposeContentEmpty, isComposeContentValid, isMediaEmpty, isMediaUploadAllSuccess -> Bool in
// if isMediaEmpty {
// return isComposeContentValid && !isComposeContentEmpty
// } else {
// return isComposeContentValid && isMediaUploadAllSuccess
// }
// }
// .eraseToAnyPublisher()
//
// let isPublishBarButtonItemEnabledPrecondition2 = Publishers.CombineLatest4(
// isComposeContentEmpty,
// isComposeContentValid,
// $isPollComposing,
// isPollAttributeAllValid
// )
// .map { isComposeContentEmpty, isComposeContentValid, isPollComposing, isPollAttributeAllValid -> Bool in
// if isPollComposing {
// return isComposeContentValid && !isComposeContentEmpty && isPollAttributeAllValid
// } else {
// return isComposeContentValid && !isComposeContentEmpty
// }
// }
// .eraseToAnyPublisher()
//
// Publishers.CombineLatest(
// isPublishBarButtonItemEnabledPrecondition1,
// isPublishBarButtonItemEnabledPrecondition2
// )
// .map { $0 && $1 }
// .assign(to: &$isPublishBarButtonItemEnabled)
// }
//}
//
//extension ComposeViewModel {
// private func bind(
// cell: ComposeStatusContentTableViewCell,
// tableView: UITableView
// ) {
// // bind status content character count
// Publishers.CombineLatest3(
// composeStatusAttribute.$composeContent,
// composeStatusAttribute.$isContentWarningComposing,
// composeStatusAttribute.$contentWarningContent
// )
// .map { composeContent, isContentWarningComposing, contentWarningContent -> Int in
// let composeContent = composeContent ?? ""
// var count = composeContent.count
// if isContentWarningComposing {
// count += contentWarningContent.count
// }
// return count
// }
// .assign(to: &$characterCount)
//
// // bind content warning
// composeStatusAttribute.$isContentWarningComposing
// .receive(on: DispatchQueue.main)
// .sink { [weak cell, weak tableView] isContentWarningComposing in
// guard let cell = cell else { return }
// guard let tableView = tableView else { return }
//
// // self size input cell
// cell.statusContentWarningEditorView.isHidden = !isContentWarningComposing
// cell.statusContentWarningEditorView.alpha = 0
// UIView.animate(withDuration: 0.33, delay: 0, options: [.curveEaseOut]) {
// cell.statusContentWarningEditorView.alpha = 1
// tableView.beginUpdates()
// tableView.endUpdates()
// } completion: { _ in
// // do nothing
// }
// }
// .store(in: &disposeBag)
//
// cell.contentWarningContent
// .removeDuplicates()
// .receive(on: DispatchQueue.main)
// .sink { [weak tableView, weak self] text in
// guard let self = self else { return }
// // bind input data
// self.composeStatusAttribute.contentWarningContent = text
//
// // self size input cell
// guard let tableView = tableView else { return }
// UIView.performWithoutAnimation {
// tableView.beginUpdates()
// tableView.endUpdates()
// }
// }
// .store(in: &cell.disposeBag)
//
// // configure custom emoji picker
// ComposeStatusSection.configureCustomEmojiPicker(
// viewModel: customEmojiPickerInputViewModel,
// customEmojiReplaceableTextInput: cell.metaText.textView,
// disposeBag: &disposeBag
// )
// ComposeStatusSection.configureCustomEmojiPicker(
// viewModel: customEmojiPickerInputViewModel,
// customEmojiReplaceableTextInput: cell.statusContentWarningEditorView.textView,
// disposeBag: &disposeBag
// )
// }
//}
//
//extension ComposeViewModel {
// private func bind(
// cell: ComposeStatusPollTableViewCell,
// tableView: UITableView
// ) {
// Publishers.CombineLatest(
// $isPollComposing,
// $pollOptionAttributes
// )
// .receive(on: DispatchQueue.main)
// .sink { [weak self] isPollComposing, pollOptionAttributes in
// guard let self = self else { return }
// guard self.isViewAppeared else { return }
//
// let cell = self.composeStatusPollTableViewCell
// guard let dataSource = cell.dataSource else { return }
//
// var snapshot = NSDiffableDataSourceSnapshot<ComposeStatusPollSection, ComposeStatusPollItem>()
// snapshot.appendSections([.main])
// var items: [ComposeStatusPollItem] = []
// if isPollComposing {
// for attribute in pollOptionAttributes {
// items.append(.pollOption(attribute: attribute))
// }
// if pollOptionAttributes.count < self.maxPollOptions {
// items.append(.pollOptionAppendEntry)
// }
// items.append(.pollExpiresOption(attribute: self.pollExpiresOptionAttribute))
// }
// snapshot.appendItems(items, toSection: .main)
//
// tableView.performBatchUpdates {
// if #available(iOS 15.0, *) {
// dataSource.apply(snapshot, animatingDifferences: false)
// } else {
// dataSource.apply(snapshot, animatingDifferences: true)
// }
// }
// }
// .store(in: &disposeBag)
//
// // bind delegate
// $pollOptionAttributes
// .sink { [weak self] pollAttributes in
// guard let self = self else { return }
// pollAttributes.forEach { $0.delegate = self }
// }
// .store(in: &disposeBag)
// }
//}
//
//extension ComposeViewModel {
// private func bind(
// cell: ComposeStatusAttachmentTableViewCell,
// tableView: UITableView
// ) {
// cell.collectionViewHeightDidUpdate
// .receive(on: DispatchQueue.main)
// .sink { [weak self] _ in
// guard let _ = self else { return }
// tableView.beginUpdates()
// tableView.endUpdates()
// }
// .store(in: &disposeBag)
//
// $attachmentServices
// .removeDuplicates()
// .receive(on: DispatchQueue.main)
// .sink { [weak self] attachmentServices in
// guard let self = self else { return }
// guard self.isViewAppeared else { return }
//
// let cell = self.composeStatusAttachmentTableViewCell
// guard let dataSource = cell.dataSource else { return }
//
// var snapshot = NSDiffableDataSourceSnapshot<ComposeStatusAttachmentSection, ComposeStatusAttachmentItem>()
// snapshot.appendSections([.main])
// let items = attachmentServices.map { ComposeStatusAttachmentItem.attachment(attachmentService: $0) }
// snapshot.appendItems(items, toSection: .main)
//
// if #available(iOS 15.0, *) {
// dataSource.applySnapshotUsingReloadData(snapshot)
// } else {
// dataSource.apply(snapshot, animatingDifferences: false)
// }
// }
// .store(in: &disposeBag)
//
// // setup attribute updater
// $attachmentServices
// .receive(on: DispatchQueue.main)
// .debounce(for: 0.3, scheduler: DispatchQueue.main)
// .sink { attachmentServices in
// // drive service upload state
// // make image upload in the queue
// for attachmentService in attachmentServices {
// // skip when prefix N task when task finish OR fail OR uploading
// guard let currentState = attachmentService.uploadStateMachine.currentState else { break }
// if currentState is MastodonAttachmentService.UploadState.Fail {
// continue
// }
// if currentState is MastodonAttachmentService.UploadState.Finish {
// continue
// }
// if currentState is MastodonAttachmentService.UploadState.Processing {
// continue
// }
// if currentState is MastodonAttachmentService.UploadState.Uploading {
// break
// }
// // trigger uploading one by one
// if currentState is MastodonAttachmentService.UploadState.Initial {
// attachmentService.uploadStateMachine.enter(MastodonAttachmentService.UploadState.Uploading.self)
// break
// }
// }
// }
// .store(in: &disposeBag)
//
// // bind delegate
// $attachmentServices
// .sink { [weak self] attachmentServices in
// guard let self = self else { return }
// attachmentServices.forEach { $0.delegate = self }
// }
// .store(in: &disposeBag)
// }
//}

View File

@ -1,164 +0,0 @@
//
// ComposeViewModel+PublishState.swift
// Mastodon
//
// Created by MainasuK Cirno on 2021-3-18.
//
import os.log
import Foundation
import Combine
import CoreDataStack
import GameplayKit
import MastodonSDK
//extension ComposeViewModel {
// class PublishState: GKState {
// weak var viewModel: ComposeViewModel?
//
// init(viewModel: ComposeViewModel) {
// self.viewModel = viewModel
// }
//
// override func didEnter(from previousState: GKState?) {
// os_log("%{public}s[%{public}ld], %{public}s: enter %s, previous: %s", ((#file as NSString).lastPathComponent), #line, #function, self.debugDescription, previousState.debugDescription)
// viewModel?.publishStateMachinePublisher.value = self
// }
// }
//}
//extension ComposeViewModel.PublishState {
// class Initial: ComposeViewModel.PublishState {
// override func isValidNextState(_ stateClass: AnyClass) -> Bool {
// return stateClass == Publishing.self
// }
// }
//
// class Publishing: ComposeViewModel.PublishState {
//
// var publishingSubscription: AnyCancellable?
//
// override func isValidNextState(_ stateClass: AnyClass) -> Bool {
// return stateClass == Fail.self || stateClass == Finish.self
// }
//
// override func didEnter(from previousState: GKState?) {
// super.didEnter(from: previousState)
// guard let viewModel = viewModel, let stateMachine = stateMachine else { return }
//
// viewModel.updatePublishDate()
//
// let authenticationBox = viewModel.authenticationBox
// let domain = authenticationBox.domain
// let attachmentServices = viewModel.attachmentServices
// let mediaIDs = attachmentServices.compactMap { attachmentService in
// attachmentService.attachment.value?.id
// }
// let pollOptions: [String]? = {
// guard viewModel.isPollComposing else { return nil }
// return viewModel.pollOptionAttributes.map { attribute in attribute.option.value }
// }()
// let pollExpiresIn: Int? = {
// guard viewModel.isPollComposing else { return nil }
// return viewModel.pollExpiresOptionAttribute.expiresOption.value.seconds
// }()
// let inReplyToID: Mastodon.Entity.Status.ID? = {
// guard case let .reply(status) = viewModel.composeKind else { return nil }
// var id: Mastodon.Entity.Status.ID?
// viewModel.context.managedObjectContext.performAndWait {
// guard let replyTo = status.object(in: viewModel.context.managedObjectContext) else { return }
// id = replyTo.id
// }
// return id
// }()
// let sensitive: Bool = viewModel.isContentWarningComposing
// let spoilerText: String? = {
// let text = viewModel.composeStatusAttribute.contentWarningContent.trimmingCharacters(in: .whitespacesAndNewlines)
// guard !text.isEmpty else {
// return nil
// }
// return text
// }()
// let visibility = viewModel.selectedStatusVisibility.visibility
//
// let updateMediaQuerySubscriptions: [AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Attachment>, Error>] = {
// var subscriptions: [AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Attachment>, Error>] = []
// for attachmentService in attachmentServices {
// guard let attachmentID = attachmentService.attachment.value?.id else { continue }
// let description = attachmentService.description.value?.trimmingCharacters(in: .whitespacesAndNewlines) ?? ""
// guard !description.isEmpty else { continue }
// let query = Mastodon.API.Media.UpdateMediaQuery(
// file: nil,
// thumbnail: nil,
// description: description,
// focus: nil
// )
// let subscription = viewModel.context.apiService.updateMedia(
// domain: domain,
// attachmentID: attachmentID,
// query: query,
// mastodonAuthenticationBox: authenticationBox
// )
// subscriptions.append(subscription)
// }
// return subscriptions
// }()
//
// let idempotencyKey = viewModel.idempotencyKey.value
//
// publishingSubscription = Publishers.MergeMany(updateMediaQuerySubscriptions)
// .collect()
// .asyncMap { attachments -> Mastodon.Response.Content<Mastodon.Entity.Status> in
// let query = Mastodon.API.Statuses.PublishStatusQuery(
// status: viewModel.composeStatusAttribute.composeContent,
// mediaIDs: mediaIDs.isEmpty ? nil : mediaIDs,
// pollOptions: pollOptions,
// pollExpiresIn: pollExpiresIn,
// inReplyToID: inReplyToID,
// sensitive: sensitive,
// spoilerText: spoilerText,
// visibility: visibility
// )
// return try await viewModel.context.apiService.publishStatus(
// domain: domain,
// idempotencyKey: idempotencyKey,
// query: query,
// authenticationBox: authenticationBox
// )
// }
// .receive(on: DispatchQueue.main)
// .sink { completion in
// switch completion {
// case .failure(let error):
// os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: publish status %s", ((#file as NSString).lastPathComponent), #line, #function, error.localizedDescription)
// stateMachine.enter(Fail.self)
// case .finished:
// os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: publish status success", ((#file as NSString).lastPathComponent), #line, #function)
// stateMachine.enter(Finish.self)
// }
// } receiveValue: { response in
// os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: status %s published: %s", ((#file as NSString).lastPathComponent), #line, #function, response.value.id, response.value.uri)
// }
// }
// }
//
// class Fail: ComposeViewModel.PublishState {
// override func isValidNextState(_ stateClass: AnyClass) -> Bool {
// // allow discard publishing
// return stateClass == Publishing.self || stateClass == Discard.self
// }
// }
//
// class Discard: ComposeViewModel.PublishState {
// override func isValidNextState(_ stateClass: AnyClass) -> Bool {
// return false
// }
// }
//
// class Finish: ComposeViewModel.PublishState {
// override func isValidNextState(_ stateClass: AnyClass) -> Bool {
// return false
// }
// }
//
//}

View File

@ -18,7 +18,7 @@ import MastodonLocalization
import MastodonMeta
import MastodonUI
final class ComposeViewModel: NSObject {
final class ComposeViewModel {
let logger = Logger(subsystem: "ComposeViewModel", category: "ViewModel")
@ -30,91 +30,13 @@ final class ComposeViewModel: NSObject {
let context: AppContext
let authContext: AuthContext
let kind: ComposeContentViewModel.Kind
// var authenticationBox: MastodonAuthenticationBox {
// authContext.mastodonAuthenticationBox
// }
//
// @Published var isPollComposing = false
// @Published var isCustomEmojiComposing = false
// @Published var isContentWarningComposing = false
//
// @Published var selectedStatusVisibility: ComposeToolbarView.VisibilitySelectionType
// @Published var repliedToCellFrame: CGRect = .zero
// @Published var autoCompleteRetryLayoutTimes = 0
// @Published var autoCompleteInfo: ComposeViewController.AutoCompleteInfo? = nil
let traitCollectionDidChangePublisher = CurrentValueSubject<Void, Never>(Void()) // use CurrentValueSubject to make initial event emit
// var isViewAppeared = false
// output
// let instanceConfiguration: Mastodon.Entity.Instance.Configuration?
// var composeContentLimit: Int {
// guard let maxCharacters = instanceConfiguration?.statuses?.maxCharacters else { return 500 }
// return max(1, maxCharacters)
// }
// var maxMediaAttachments: Int {
// guard let maxMediaAttachments = instanceConfiguration?.statuses?.maxMediaAttachments else {
// return 4
// }
// // FIXME: update timeline media preview UI
// return min(4, max(1, maxMediaAttachments))
// // return max(1, maxMediaAttachments)
// }
// var maxPollOptions: Int {
// guard let maxOptions = instanceConfiguration?.polls?.maxOptions else { return 4 }
// return max(2, maxOptions)
// }
//
// let composeStatusAttribute = ComposeStatusItem.ComposeStatusAttribute()
// let composeStatusContentTableViewCell = ComposeStatusContentTableViewCell()
// let composeStatusAttachmentTableViewCell = ComposeStatusAttachmentTableViewCell()
// let composeStatusPollTableViewCell = ComposeStatusPollTableViewCell()
//
// // var dataSource: UITableViewDiffableDataSource<ComposeStatusSection, ComposeStatusItem>?
// var customEmojiPickerDiffableDataSource: UICollectionViewDiffableDataSource<CustomEmojiPickerSection, CustomEmojiPickerItem>?
// private(set) lazy var publishStateMachine: GKStateMachine = {
// // exclude timeline middle fetcher state
// let stateMachine = GKStateMachine(states: [
// PublishState.Initial(viewModel: self),
// PublishState.Publishing(viewModel: self),
// PublishState.Fail(viewModel: self),
// PublishState.Discard(viewModel: self),
// PublishState.Finish(viewModel: self),
// ])
// stateMachine.enter(PublishState.Initial.self)
// return stateMachine
// }()
// private(set) lazy var publishStateMachinePublisher = CurrentValueSubject<PublishState?, Never>(nil)
// private(set) var publishDate = Date() // update it when enter Publishing state
//
// // TODO: group post material into Hashable class
// var idempotencyKey = CurrentValueSubject<String, Never>(UUID().uuidString)
//
// // UI & UX
// @Published var title: String
// @Published var shouldDismiss = true
// @Published var isPublishBarButtonItemEnabled = false
// @Published var isMediaToolbarButtonEnabled = true
// @Published var isPollToolbarButtonEnabled = true
// @Published var characterCount = 0
// @Published var collectionViewState: CollectionViewState = .fold
//
// // for hashtag: "#<hashtag> "
// // for mention: "@<mention> "
// var preInsertedContent: String?
//
// // custom emojis
// let customEmojiViewModel: EmojiService.CustomEmojiViewModel?
// let customEmojiPickerInputViewModel = CustomEmojiPickerInputViewModel()
// @Published var isLoadingCustomEmoji = false
//
// // attachment
// @Published var attachmentServices: [MastodonAttachmentService] = []
//
// // polls
// @Published var pollOptionAttributes: [ComposeStatusPollItem.PollOptionAttribute] = []
// let pollExpiresOptionAttribute = ComposeStatusPollItem.PollExpiresOptionAttribute()
// UI & UX
@Published var title: String
init(
context: AppContext,
@ -124,63 +46,14 @@ final class ComposeViewModel: NSObject {
self.context = context
self.authContext = authContext
self.kind = kind
// end init
// self.title = {
// switch composeKind {
// case .post, .hashtag, .mention: return L10n.Scene.Compose.Title.newPost
// case .reply: return L10n.Scene.Compose.Title.newReply
// }
// }()
// self.selectedStatusVisibility = {
// // default private when user locked
// var visibility: ComposeToolbarView.VisibilitySelectionType = {
// guard let author = authContext.mastodonAuthenticationBox.authenticationRecord.object(in: context.managedObjectContext)?.user
// else {
// return .public
// }
// return author.locked ? .private : .public
// }()
// // set visibility for reply post
// switch composeKind {
// case .reply(let record):
// context.managedObjectContext.performAndWait {
// guard let status = record.object(in: context.managedObjectContext) else {
// assertionFailure()
// return
// }
// let repliedStatusVisibility = status.visibility
// switch repliedStatusVisibility {
// case .public, .unlisted:
// // keep default
// break
// case .private:
// visibility = .private
// case .direct:
// visibility = .direct
// case ._other:
// assertionFailure()
// break
// }
// }
// default:
// break
// }
// return visibility
// }()
// // set limit
// self.instanceConfiguration = {
// var configuration: Mastodon.Entity.Instance.Configuration? = nil
// context.managedObjectContext.performAndWait {
// guard let authentication = authContext.mastodonAuthenticationBox.authenticationRecord.object(in: context.managedObjectContext) else { return }
// configuration = authentication.instance?.configuration
// }
// return configuration
// }()
// self.customEmojiViewModel = context.emojiService.dequeueCustomEmojiViewModel(for: authContext.mastodonAuthenticationBox.domain)
// super.init()
// // end init
//
// setup(cell: composeStatusContentTableViewCell)
self.title = {
switch kind {
case .post, .hashtag, .mention: return L10n.Scene.Compose.Title.newPost
case .reply: return L10n.Scene.Compose.Title.newReply
}
}()
}
deinit {
@ -188,194 +61,3 @@ final class ComposeViewModel: NSObject {
}
}
extension ComposeViewModel {
// func createNewPollOptionIfPossible() {
// guard pollOptionAttributes.count < maxPollOptions else { return }
//
// let attribute = ComposeStatusPollItem.PollOptionAttribute()
// pollOptionAttributes = pollOptionAttributes + [attribute]
// }
//
// func updatePublishDate() {
// publishDate = Date()
// }
}
//extension ComposeViewModel {
//
// enum AttachmentPrecondition: Error, LocalizedError {
// case videoAttachWithPhoto
// case moreThanOneVideo
//
// var errorDescription: String? {
// return L10n.Common.Alerts.PublishPostFailure.title
// }
//
// var failureReason: String? {
// switch self {
// case .videoAttachWithPhoto:
// return L10n.Common.Alerts.PublishPostFailure.AttachmentsMessage.videoAttachWithPhoto
// case .moreThanOneVideo:
// return L10n.Common.Alerts.PublishPostFailure.AttachmentsMessage.moreThanOneVideo
// }
// }
// }
//
// // check exclusive limit:
// // - up to 1 video
// // - up to N photos
// func checkAttachmentPrecondition() throws {
// let attachmentServices = self.attachmentServices
// guard !attachmentServices.isEmpty else { return }
// var photoAttachmentServices: [MastodonAttachmentService] = []
// var videoAttachmentServices: [MastodonAttachmentService] = []
// attachmentServices.forEach { service in
// guard let file = service.file.value else {
// assertionFailure()
// return
// }
// switch file {
// case .jpeg, .png, .gif:
// photoAttachmentServices.append(service)
// case .other:
// videoAttachmentServices.append(service)
// }
// }
//
// if !videoAttachmentServices.isEmpty {
// guard videoAttachmentServices.count == 1 else {
// throw AttachmentPrecondition.moreThanOneVideo
// }
// guard photoAttachmentServices.isEmpty else {
// throw AttachmentPrecondition.videoAttachWithPhoto
// }
// }
// }
//
//}
//
//// MARK: - MastodonAttachmentServiceDelegate
//extension ComposeViewModel: MastodonAttachmentServiceDelegate {
// func mastodonAttachmentService(_ service: MastodonAttachmentService, uploadStateDidChange state: MastodonAttachmentService.UploadState?) {
// // trigger new output event
// attachmentServices = attachmentServices
// }
//}
//
//// MARK: - ComposePollAttributeDelegate
//extension ComposeViewModel: ComposePollAttributeDelegate {
// func composePollAttribute(_ attribute: ComposeStatusPollItem.PollOptionAttribute, pollOptionDidChange: String?) {
// // trigger update
// pollOptionAttributes = pollOptionAttributes
// }
//}
//
//extension ComposeViewModel {
// private func setup(
// cell: ComposeStatusContentTableViewCell
// ) {
// setupStatusHeader(cell: cell)
// setupStatusAuthor(cell: cell)
// setupStatusContent(cell: cell)
// }
//
// private func setupStatusHeader(
// cell: ComposeStatusContentTableViewCell
// ) {
// // configure header
// let managedObjectContext = context.managedObjectContext
// managedObjectContext.performAndWait {
// guard case let .reply(record) = self.composeKind,
// let replyTo = record.object(in: managedObjectContext)
// else {
// cell.statusView.viewModel.header = .none
// return
// }
//
// let info: StatusView.ViewModel.Header.ReplyInfo
// do {
// let content = MastodonContent(
// content: replyTo.author.displayNameWithFallback,
// emojis: replyTo.author.emojis.asDictionary
// )
// let metaContent = try MastodonMetaContent.convert(document: content)
// info = .init(header: metaContent)
// } catch {
// let metaContent = PlaintextMetaContent(string: replyTo.author.displayNameWithFallback)
// info = .init(header: metaContent)
// }
// cell.statusView.viewModel.header = .reply(info: info)
// }
// }
//
// private func setupStatusAuthor(
// cell: ComposeStatusContentTableViewCell
// ) {
// self.context.managedObjectContext.performAndWait {
// guard let author = authenticationBox.authenticationRecord.object(in: self.context.managedObjectContext)?.user else { return }
// cell.statusView.configureAuthor(author: author)
// }
// }
//
// private func setupStatusContent(
// cell: ComposeStatusContentTableViewCell
// ) {
// switch composeKind {
// case .reply(let record):
// context.managedObjectContext.performAndWait {
// guard let status = record.object(in: context.managedObjectContext) else { return }
// let author = self.authenticationBox.authenticationRecord.object(in: context.managedObjectContext)?.user
//
// var mentionAccts: [String] = []
// if author?.id != status.author.id {
// mentionAccts.append("@" + status.author.acct)
// }
// let mentions = status.mentions
// .filter { author?.id != $0.id }
// for mention in mentions {
// let acct = "@" + mention.acct
// guard !mentionAccts.contains(acct) else { continue }
// mentionAccts.append(acct)
// }
// for acct in mentionAccts {
// UITextChecker.learnWord(acct)
// }
// if let spoilerText = status.spoilerText, !spoilerText.isEmpty {
// self.isContentWarningComposing = true
// self.composeStatusAttribute.contentWarningContent = spoilerText
// }
//
// let initialComposeContent = mentionAccts.joined(separator: " ")
// let preInsertedContent: String? = initialComposeContent.isEmpty ? nil : initialComposeContent + " "
// self.preInsertedContent = preInsertedContent
// self.composeStatusAttribute.composeContent = preInsertedContent
// }
// case .hashtag(let hashtag):
// let initialComposeContent = "#" + hashtag
// UITextChecker.learnWord(initialComposeContent)
// let preInsertedContent = initialComposeContent + " "
// self.preInsertedContent = preInsertedContent
// self.composeStatusAttribute.composeContent = preInsertedContent
// case .mention(let record):
// context.managedObjectContext.performAndWait {
// guard let user = record.object(in: context.managedObjectContext) else { return }
// let initialComposeContent = "@" + user.acct
// UITextChecker.learnWord(initialComposeContent)
// let preInsertedContent = initialComposeContent + " "
// self.preInsertedContent = preInsertedContent
// self.composeStatusAttribute.composeContent = preInsertedContent
// }
// case .post:
// self.preInsertedContent = nil
// }
//
// // configure content warning
// if let composeContent = composeStatusAttribute.composeContent {
// cell.metaText.textView.text = composeContent
// }
//
// // configure content warning
// cell.statusContentWarningEditorView.textView.text = composeStatusAttribute.contentWarningContent
// }
//}

View File

@ -26,6 +26,16 @@ final class ProfileFieldCollectionViewCell: UICollectionViewCell {
let keyMetaLabel = MetaLabel(style: .profileFieldName)
let valueMetaLabel = MetaLabel(style: .profileFieldValue)
let checkmark = UIImageView(image: Asset.Editing.checkmark.image.withRenderingMode(.alwaysTemplate))
var checkmarkPopoverString: String? = nil;
let tapGesture = UITapGestureRecognizer();
private var _editMenuInteraction: Any? = nil
@available(iOS 16, *)
fileprivate var editMenuInteraction: UIEditMenuInteraction {
_editMenuInteraction = _editMenuInteraction ?? UIEditMenuInteraction(delegate: self)
return _editMenuInteraction as! UIEditMenuInteraction
}
override func prepareForReuse() {
super.prepareForReuse()
@ -47,6 +57,17 @@ final class ProfileFieldCollectionViewCell: UICollectionViewCell {
extension ProfileFieldCollectionViewCell {
private func _init() {
// Setup colors
checkmark.tintColor = Asset.Scene.Profile.About.bioAboutFieldVerifiedCheckmark.color;
// Setup gestures
tapGesture.addTarget(self, action: #selector(ProfileFieldCollectionViewCell.didTapCheckmark(_:)))
checkmark.addGestureRecognizer(tapGesture)
checkmark.isUserInteractionEnabled = true
if #available(iOS 16, *) {
checkmark.addInteraction(editMenuInteraction)
}
// containerStackView: V - [ metaContainer | plainContainer ]
let containerStackView = UIStackView()
containerStackView.axis = .vertical
@ -63,19 +84,62 @@ extension ProfileFieldCollectionViewCell {
bottomAnchor.constraint(equalTo: containerStackView.bottomAnchor, constant: 11),
])
// metaContainer: V - [ keyMetaLabel | valueMetaLabel ]
// metaContainer: V - [ keyMetaLabel | valueContainer ]
let metaContainer = UIStackView()
metaContainer.axis = .vertical
metaContainer.spacing = 2
containerStackView.addArrangedSubview(metaContainer)
// valueContainer: H - [ valueMetaLabel | checkmark ]
let valueContainer = UIStackView()
valueContainer.axis = .horizontal
valueContainer.spacing = 2
metaContainer.addArrangedSubview(keyMetaLabel)
metaContainer.addArrangedSubview(valueMetaLabel)
valueContainer.addArrangedSubview(valueMetaLabel)
valueContainer.addArrangedSubview(checkmark)
metaContainer.addArrangedSubview(valueContainer)
keyMetaLabel.linkDelegate = self
valueMetaLabel.linkDelegate = self
}
@objc public func didTapCheckmark(_ recognizer: UITapGestureRecognizer) {
if #available(iOS 16, *) {
editMenuInteraction.presentEditMenu(with: UIEditMenuConfiguration(identifier: nil, sourcePoint: recognizer.location(in: checkmark)))
} else {
guard let editMenuLabel = checkmarkPopoverString else { return }
self.isUserInteractionEnabled = true
self.becomeFirstResponder()
UIMenuController.shared.menuItems = [
UIMenuItem(
title: editMenuLabel,
action: #selector(dismissVerifiedMenu)
)
]
UIMenuController.shared.showMenu(from: checkmark, rect: checkmark.bounds)
}
}
}
// UIMenuController boilerplate
@available(iOS, deprecated: 16, message: "Can be removed when target version is >=16 -- boilerplate to maintain compatibility with UIMenuController")
extension ProfileFieldCollectionViewCell {
override var canBecomeFirstResponder: Bool { true }
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
if action == #selector(dismissVerifiedMenu) {
return true
}
return super.canPerformAction(action, withSender: sender)
}
@objc public func dismissVerifiedMenu() {
UIMenuController.shared.hideMenu()
}
}
// MARK: - MetaLabelDelegate
@ -85,3 +149,16 @@ extension ProfileFieldCollectionViewCell: MetaLabelDelegate {
delegate?.profileFieldCollectionViewCell(self, metaLebel: metaLabel, didSelectMeta: meta)
}
}
// MARK: UIEditMenuInteractionDelegate
@available(iOS 16.0, *)
extension ProfileFieldCollectionViewCell: UIEditMenuInteractionDelegate {
func editMenuInteraction(_ interaction: UIEditMenuInteraction, menuFor configuration: UIEditMenuConfiguration, suggestedActions: [UIMenuElement]) -> UIMenu? {
guard let editMenuLabel = checkmarkPopoverString else { return UIMenu(children: []) }
return UIMenu(children: [UIAction(title: editMenuLabel) { _ in return }])
}
func editMenuInteraction(_ interaction: UIEditMenuInteraction, targetRectFor configuration: UIEditMenuConfiguration) -> CGRect {
return checkmark.frame
}
}

View File

@ -52,7 +52,7 @@ final class ProfileAboutViewModel {
$emojiMeta
)
.map { fields, emojiMeta in
fields.map { ProfileFieldItem.FieldValue(name: $0.name, value: $0.value, emojiMeta: emojiMeta) }
fields.map { ProfileFieldItem.FieldValue(name: $0.name, value: $0.value, verifiedAt: $0.verifiedAt, emojiMeta: emojiMeta) }
}
.assign(to: &profileInfo.$fields)
@ -72,6 +72,7 @@ final class ProfileAboutViewModel {
ProfileFieldItem.FieldValue(
name: field.name,
value: field.value,
verifiedAt: field.verifiedAt,
emojiMeta: [:] // no use for editing
)
} ?? []
@ -92,7 +93,7 @@ extension ProfileAboutViewModel {
func appendFieldItem() {
var fields = profileInfoEditing.fields
guard fields.count < ProfileHeaderViewModel.maxProfileFieldCount else { return }
fields.append(ProfileFieldItem.FieldValue(name: "", value: "", emojiMeta: [:]))
fields.append(ProfileFieldItem.FieldValue(name: "", value: "", verifiedAt: nil, emojiMeta: [:]))
profileInfoEditing.fields = fields
}
@ -112,7 +113,7 @@ extension ProfileAboutViewModel: ProfileViewModelEditable {
let isFieldsEqual: Bool = {
let originalFields = self.accountForEdit?.source?.fields?.compactMap { field in
ProfileFieldItem.FieldValue(name: field.name, value: field.value, emojiMeta: [:])
ProfileFieldItem.FieldValue(name: field.name, value: field.value, verifiedAt: nil, emojiMeta: [:])
} ?? []
let editFields = profileInfoEditing.fields
guard editFields.count == originalFields.count else { return false }

View File

@ -51,6 +51,7 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi
action: #selector(ProfileViewController.settingBarButtonItemPressed(_:))
)
barButtonItem.tintColor = .white
barButtonItem.accessibilityLabel = L10n.Common.Controls.Actions.settings
return barButtonItem
}()
@ -62,6 +63,7 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi
action: #selector(ProfileViewController.shareBarButtonItemPressed(_:))
)
barButtonItem.tintColor = .white
barButtonItem.accessibilityLabel = L10n.Common.Controls.Actions.share
return barButtonItem
}()
@ -73,6 +75,7 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi
action: #selector(ProfileViewController.favoriteBarButtonItemPressed(_:))
)
barButtonItem.tintColor = .white
barButtonItem.accessibilityLabel = L10n.Scene.Favorite.title
return barButtonItem
}()
@ -84,18 +87,21 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi
action: #selector(ProfileViewController.bookmarkBarButtonItemPressed(_:))
)
barButtonItem.tintColor = .white
barButtonItem.accessibilityLabel = L10n.Scene.Bookmark.title
return barButtonItem
}()
private(set) lazy var replyBarButtonItem: UIBarButtonItem = {
let barButtonItem = UIBarButtonItem(image: UIImage(systemName: "arrowshape.turn.up.left"), style: .plain, target: self, action: #selector(ProfileViewController.replyBarButtonItemPressed(_:)))
barButtonItem.tintColor = .white
barButtonItem.accessibilityLabel = L10n.Common.Controls.Actions.reply
return barButtonItem
}()
let moreMenuBarButtonItem: UIBarButtonItem = {
let barButtonItem = UIBarButtonItem(image: UIImage(systemName: "ellipsis.circle"), style: .plain, target: nil, action: nil)
barButtonItem.tintColor = .white
barButtonItem.accessibilityLabel = L10n.Common.Controls.Actions.seeMore
return barButtonItem
}()
@ -552,6 +558,9 @@ extension ProfileViewController {
userTimelineViewController.viewModel.stateMachine.enter(UserTimelineViewModel.State.Reloading.self)
}
// trigger authenticated user account update
viewModel.context.authenticationService.updateActiveUserAccountPublisher.send()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) {
sender.endRefreshing()
}

View File

@ -312,7 +312,12 @@ extension MainTabBarController {
guard let profileTabItem = _profileTabItem else { return }
let currentUserDisplayName = user.displayNameWithFallback ?? "no user"
profileTabItem.accessibilityHint = L10n.Scene.AccountList.tabBarHint(currentUserDisplayName)
context.authenticationService.updateActiveUserAccountPublisher
.sink { [weak self] in
self?.updateUserAccount()
}
.store(in: &disposeBag)
} else {
self.avatarURLObserver = nil
}
@ -487,6 +492,26 @@ extension MainTabBarController {
avatarButton.setNeedsLayout()
}
private func updateUserAccount() {
guard let authContext = authContext else { return }
Task { @MainActor in
let profileResponse = try await context.apiService.authenticatedUserInfo(
authenticationBox: authContext.mastodonAuthenticationBox
)
if let user = authContext.mastodonAuthenticationBox.authenticationRecord.object(
in: context.managedObjectContext
)?.user {
user.update(
property: .init(
entity: profileResponse.value,
domain: authContext.mastodonAuthenticationBox.domain
)
)
}
}
}
}
extension MainTabBarController {

View File

@ -109,6 +109,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// trigger status filter update
AppContext.shared.statusFilterService.filterUpdatePublisher.send()
// trigger authenticated user account update
AppContext.shared.authenticationService.updateActiveUserAccountPublisher.send()
if let shortcutItem = savedShortCutItem {
Task {

View File

@ -25,9 +25,9 @@ let package = Package(
],
dependencies: [
.package(name: "ArkanaKeys", path: "../dependencies/ArkanaKeys"),
.package(name: "FaviconFinder", url: "https://github.com/will-lumley/FaviconFinder.git", from: "3.2.2"),
.package(name: "Introspect", url: "https://github.com/siteline/SwiftUI-Introspect.git", from: "0.1.3"),
.package(name: "UITextView+Placeholder", url: "https://github.com/MainasuK/UITextView-Placeholder.git", from: "1.4.1"),
.package(url: "https://github.com/will-lumley/FaviconFinder.git", from: "3.2.2"),
.package(url: "https://github.com/siteline/SwiftUI-Introspect.git", from: "0.1.3"),
.package(url: "https://github.com/MainasuK/UITextView-Placeholder.git", from: "1.4.1"),
.package(url: "https://github.com/Alamofire/Alamofire.git", from: "5.4.0"),
.package(url: "https://github.com/Alamofire/AlamofireImage.git", from: "4.1.0"),
.package(url: "https://github.com/apple/swift-collections.git", from: "1.0.3"),
@ -49,6 +49,7 @@ let package = Package(
.package(url: "https://github.com/SDWebImage/SDWebImage.git", from: "5.12.0"),
.package(url: "https://github.com/eneko/Stripes.git", from: "0.2.0"),
.package(url: "https://github.com/onevcat/Kingfisher.git", from: "7.4.1"),
.package(url: "https://github.com/NextLevel/NextLevelSessionExporter.git", from: "0.4.6"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
@ -112,8 +113,8 @@ let package = Package(
.product(name: "FLAnimatedImage", package: "FLAnimatedImage"),
.product(name: "FaviconFinder", package: "FaviconFinder"),
.product(name: "Nuke", package: "Nuke"),
.product(name: "Introspect", package: "Introspect"),
.product(name: "UITextView+Placeholder", package: "UITextView+Placeholder"),
.product(name: "Introspect", package: "SwiftUI-Introspect"),
.product(name: "UITextView+Placeholder", package: "UITextView-Placeholder"),
.product(name: "UIHostingConfigurationBackport", package: "UIHostingConfigurationBackport"),
.product(name: "TabBarPager", package: "TabBarPager"),
.product(name: "ThirdPartyMailer", package: "ThirdPartyMailer"),
@ -124,6 +125,7 @@ let package = Package(
.product(name: "PanModal", package: "PanModal"),
.product(name: "Stripes", package: "Stripes"),
.product(name: "Kingfisher", package: "Kingfisher"),
.product(name: "NextLevelSessionExporter", package: "NextLevelSessionExporter"),
]
),
.testTarget(

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