diff --git a/.github/scripts/setup.sh b/.github/scripts/setup.sh index 9b52d5b9e..845730f1f 100755 --- a/.github/scripts/setup.sh +++ b/.github/scripts/setup.sh @@ -1,5 +1,8 @@ #!/bin/bash +# workaround https://github.com/CocoaPods/CocoaPods/issues/11355 +sed -i '' $'1s/^/source "https:\\/\\/github.com\\/CocoaPods\\/Specs.git"\\\n\\\n/' Podfile + # Install Ruby Bundler gem install bundler:2.3.11 diff --git a/.gitignore b/.gitignore index a605c524d..6f4802cab 100644 --- a/.gitignore +++ b/.gitignore @@ -120,6 +120,6 @@ xcuserdata # End of https://www.toptal.com/developers/gitignore/api/swift,swiftpm,xcode,cocoapods -Localization/StringsConvertor/input +# Localization/StringsConvertor/input Localization/StringsConvertor/output .DS_Store \ No newline at end of file diff --git a/AppShared/Info.plist b/AppShared/Info.plist index 92f442892..bc0be73ac 100644 --- a/AppShared/Info.plist +++ b/AppShared/Info.plist @@ -15,8 +15,8 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.1 + 1.4.2 CFBundleVersion - 126 + 133 diff --git a/Localization/Localizable.stringsdict b/Localization/Localizable.stringsdict index 4b9a12762..051bb50ef 100644 --- a/Localization/Localizable.stringsdict +++ b/Localization/Localizable.stringsdict @@ -68,6 +68,37 @@ %ld characters + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + zero + Followed by %1$@ + one + Followed by %1$@, and another mutual + few + Followed by %1$@, and %ld mutuals + many + Followed by %1$@, and %ld mutuals + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -90,6 +121,28 @@ posts + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + zero + 0 media + one + 1 media + few + %ld media + many + %ld media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/Intents/input/ar_SA/Intents.strings b/Localization/StringsConvertor/Intents/input/ar.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/ar_SA/Intents.strings rename to Localization/StringsConvertor/Intents/input/ar.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/ar_SA/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/ar.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/ar_SA/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/ar.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/ca_ES/Intents.strings b/Localization/StringsConvertor/Intents/input/ca.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/ca_ES/Intents.strings rename to Localization/StringsConvertor/Intents/input/ca.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/ca_ES/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/ca.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/ca_ES/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/ca.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/ckb_IR/Intents.strings b/Localization/StringsConvertor/Intents/input/ckb.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/ckb_IR/Intents.strings rename to Localization/StringsConvertor/Intents/input/ckb.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/ckb_IR/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/ckb.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/ckb_IR/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/ckb.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/cy_GB/Intents.strings b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/cy_GB/Intents.strings rename to Localization/StringsConvertor/Intents/input/cy.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/cy_GB/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/cy_GB/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/cy.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/da_DK/Intents.strings b/Localization/StringsConvertor/Intents/input/da.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/da_DK/Intents.strings rename to Localization/StringsConvertor/Intents/input/da.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/da_DK/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/da.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/da_DK/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/da.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/de_DE/Intents.strings b/Localization/StringsConvertor/Intents/input/de.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/de_DE/Intents.strings rename to Localization/StringsConvertor/Intents/input/de.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/de_DE/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/de.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/de_DE/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/de.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/en_US/Intents.strings b/Localization/StringsConvertor/Intents/input/en-US.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/en_US/Intents.strings rename to Localization/StringsConvertor/Intents/input/en-US.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/en_US/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/en-US.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/en_US/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/en-US.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/fi_FI/Intents.strings b/Localization/StringsConvertor/Intents/input/en.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/fi_FI/Intents.strings rename to Localization/StringsConvertor/Intents/input/en.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/fi_FI/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/en.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/fi_FI/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/en.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/es_AR/Intents.strings b/Localization/StringsConvertor/Intents/input/es-AR.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/es_AR/Intents.strings rename to Localization/StringsConvertor/Intents/input/es-AR.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/es_AR/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/es-AR.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/es_AR/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/es-AR.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/es_ES/Intents.strings b/Localization/StringsConvertor/Intents/input/es.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/es_ES/Intents.strings rename to Localization/StringsConvertor/Intents/input/es.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/es_ES/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/es.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/es_ES/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/es.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/eu_ES/Intents.strings b/Localization/StringsConvertor/Intents/input/eu.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/eu_ES/Intents.strings rename to Localization/StringsConvertor/Intents/input/eu.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/eu_ES/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/eu.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/eu_ES/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/eu.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/sv_FI/Intents.strings b/Localization/StringsConvertor/Intents/input/fi.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/sv_FI/Intents.strings rename to Localization/StringsConvertor/Intents/input/fi.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/sv_FI/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/fi.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/sv_FI/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/fi.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/fr_FR/Intents.strings b/Localization/StringsConvertor/Intents/input/fr.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/fr_FR/Intents.strings rename to Localization/StringsConvertor/Intents/input/fr.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/fr_FR/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/fr.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/fr_FR/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/fr.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/gd_GB/Intents.strings b/Localization/StringsConvertor/Intents/input/gd.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/gd_GB/Intents.strings rename to Localization/StringsConvertor/Intents/input/gd.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/gd_GB/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/gd.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/gd_GB/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/gd.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/gl.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/gl.lproj/Intents.strings new file mode 100644 index 000000000..2083cc701 --- /dev/null +++ b/Localization/StringsConvertor/Intents/input/gl.lproj/Intents.strings @@ -0,0 +1,51 @@ +"16wxgf" = "Publicar en Mastodon"; + +"751xkl" = "Texto a incluír"; + +"CsR7G2" = "Publicar en Mastodon"; + +"HZSGTr" = "Cal é o contido a publicar?"; + +"HdGikU" = "Fallou a publicación"; + +"KDNTJ4" = "Razón do fallo"; + +"RHxKOw" = "Enviar Publicación con texto"; + +"RxSqsb" = "Publicación"; + +"WCIR3D" = "Publicar ${content} en Mastodon"; + +"ZKJSNu" = "Publicación"; + +"ZS1XaK" = "${content}"; + +"ZbSjzC" = "Visibilidade"; + +"Zo4jgJ" = "Visibilidade da publicación"; + +"apSxMG-dYQ5NN" = "Hai ${count} opcións que coinciden con ‘Público’."; + +"apSxMG-ehFLjY" = "Hai ${count} opcións que coinciden con 'Só seguidoras’."; + +"ayoYEb-dYQ5NN" = "${content}, Público"; + +"ayoYEb-ehFLjY" = "${content}, Só seguidoras"; + +"dUyuGg" = "Publicar en Mastodon"; + +"dYQ5NN" = "Público"; + +"ehFLjY" = "Só seguidoras"; + +"gfePDu" = "Fallou a publicación. ${failureReason}"; + +"k7dbKQ" = "Publicación correcta."; + +"oGiqmY-dYQ5NN" = "Só para confirmar, querías ’Público'?"; + +"oGiqmY-ehFLjY" = "Só para confirmar, querías ’Só para seguidoras'?"; + +"rM6dvp" = "URL"; + +"ryJLwG" = "Publicación correcta. "; diff --git a/Localization/StringsConvertor/Intents/input/gl.lproj/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/gl.lproj/Intents.stringsdict new file mode 100644 index 000000000..6e3a897f0 --- /dev/null +++ b/Localization/StringsConvertor/Intents/input/gl.lproj/Intents.stringsdict @@ -0,0 +1,38 @@ + + + + + There are ${count} options matching ‘${content}’. - 2 + + NSStringLocalizedFormatKey + Hai %#@count_option@ coincidencias con '${content}'. + count_option + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + %ld + one + 1 opción + other + %ld opcións + + + There are ${count} options matching ‘${visibility}’. + + NSStringLocalizedFormatKey + Hai %#@count_option@ coincidentes con '${visibility}'. + count_option + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + %ld + one + 1 opción + other + %ld opcións + + + + diff --git a/Localization/StringsConvertor/Intents/input/gl_ES/Intents.strings b/Localization/StringsConvertor/Intents/input/hi.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/gl_ES/Intents.strings rename to Localization/StringsConvertor/Intents/input/hi.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/gl_ES/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/hi.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/gl_ES/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/hi.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/id_ID/Intents.strings b/Localization/StringsConvertor/Intents/input/id.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/id_ID/Intents.strings rename to Localization/StringsConvertor/Intents/input/id.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/id_ID/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/id.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/id_ID/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/id.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/it_IT/Intents.strings b/Localization/StringsConvertor/Intents/input/it.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/it_IT/Intents.strings rename to Localization/StringsConvertor/Intents/input/it.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/it_IT/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/it.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/it_IT/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/it.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/ja_JP/Intents.strings b/Localization/StringsConvertor/Intents/input/ja.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/ja_JP/Intents.strings rename to Localization/StringsConvertor/Intents/input/ja.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/ja_JP/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/ja.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/ja_JP/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/ja.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/kab_KAB/Intents.strings b/Localization/StringsConvertor/Intents/input/kab.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/kab_KAB/Intents.strings rename to Localization/StringsConvertor/Intents/input/kab.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/kab_KAB/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/kab.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/kab_KAB/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/kab.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/kmr_TR/Intents.strings b/Localization/StringsConvertor/Intents/input/kmr.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/kmr_TR/Intents.strings rename to Localization/StringsConvertor/Intents/input/kmr.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/kmr_TR/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/kmr.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/kmr_TR/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/kmr.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/hi_IN/Intents.strings b/Localization/StringsConvertor/Intents/input/ko.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/hi_IN/Intents.strings rename to Localization/StringsConvertor/Intents/input/ko.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/ko_KR/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/ko.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/ko_KR/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/ko.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/nl_NL/Intents.strings b/Localization/StringsConvertor/Intents/input/nl.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/nl_NL/Intents.strings rename to Localization/StringsConvertor/Intents/input/nl.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/nl_NL/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/nl.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/nl_NL/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/nl.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/ko_KR/Intents.strings b/Localization/StringsConvertor/Intents/input/pt-BR.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/ko_KR/Intents.strings rename to Localization/StringsConvertor/Intents/input/pt-BR.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/hi_IN/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/pt-BR.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/hi_IN/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/pt-BR.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/pt_BR/Intents.strings b/Localization/StringsConvertor/Intents/input/pt.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/pt_BR/Intents.strings rename to Localization/StringsConvertor/Intents/input/pt.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/pt_BR/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/pt.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/pt_BR/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/pt.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/pt_PT/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/pt_PT/Intents.stringsdict deleted file mode 100644 index 18422c772..000000000 --- a/Localization/StringsConvertor/Intents/input/pt_PT/Intents.stringsdict +++ /dev/null @@ -1,38 +0,0 @@ - - - - - There are ${count} options matching ‘${content}’. - 2 - - NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${content}’. - count_option - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - %ld - one - 1 option - other - %ld options - - - There are ${count} options matching ‘${visibility}’. - - NSStringLocalizedFormatKey - There are %#@count_option@ matching ‘${visibility}’. - count_option - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - %ld - one - 1 option - other - %ld options - - - - diff --git a/Localization/StringsConvertor/Intents/input/pt_PT/Intents.strings b/Localization/StringsConvertor/Intents/input/ro.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/pt_PT/Intents.strings rename to Localization/StringsConvertor/Intents/input/ro.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/ro_RO/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/ro.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/ro_RO/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/ro.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/ro_RO/Intents.strings b/Localization/StringsConvertor/Intents/input/ru.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/ro_RO/Intents.strings rename to Localization/StringsConvertor/Intents/input/ru.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/ru_RU/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/ru.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/ru_RU/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/ru.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/ru_RU/Intents.strings b/Localization/StringsConvertor/Intents/input/ru_RU/Intents.strings deleted file mode 100644 index 6877490ba..000000000 --- a/Localization/StringsConvertor/Intents/input/ru_RU/Intents.strings +++ /dev/null @@ -1,51 +0,0 @@ -"16wxgf" = "Post on Mastodon"; - -"751xkl" = "Text Content"; - -"CsR7G2" = "Post on Mastodon"; - -"HZSGTr" = "What content to post?"; - -"HdGikU" = "Posting failed"; - -"KDNTJ4" = "Failure Reason"; - -"RHxKOw" = "Send Post with text content"; - -"RxSqsb" = "Post"; - -"WCIR3D" = "Post ${content} on Mastodon"; - -"ZKJSNu" = "Post"; - -"ZS1XaK" = "${content}"; - -"ZbSjzC" = "Visibility"; - -"Zo4jgJ" = "Post Visibility"; - -"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; - -"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; - -"ayoYEb-dYQ5NN" = "${content}, Public"; - -"ayoYEb-ehFLjY" = "${content}, Followers Only"; - -"dUyuGg" = "Post on Mastodon"; - -"dYQ5NN" = "Public"; - -"ehFLjY" = "Followers Only"; - -"gfePDu" = "Posting failed. ${failureReason}"; - -"k7dbKQ" = "Post was sent successfully."; - -"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; - -"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; - -"rM6dvp" = "URL"; - -"ryJLwG" = "Post was sent successfully. "; diff --git a/Localization/StringsConvertor/Intents/input/sv.lproj/Intents.strings b/Localization/StringsConvertor/Intents/input/sv.lproj/Intents.strings new file mode 100644 index 000000000..526e495d2 --- /dev/null +++ b/Localization/StringsConvertor/Intents/input/sv.lproj/Intents.strings @@ -0,0 +1,51 @@ +"16wxgf" = "Publicera på Mastodon"; + +"751xkl" = "Textinnehåll"; + +"CsR7G2" = "Publicera på Mastodon"; + +"HZSGTr" = "Vilket innehåll ska publiceras?"; + +"HdGikU" = "Publiceringen misslyckades"; + +"KDNTJ4" = "Felorsak"; + +"RHxKOw" = "Skicka inlägg med textinnehåll"; + +"RxSqsb" = "Inlägg"; + +"WCIR3D" = "Publicera ${content} på Mastodon"; + +"ZKJSNu" = "Inlägg"; + +"ZS1XaK" = "${content}"; + +"ZbSjzC" = "Synlighet"; + +"Zo4jgJ" = "Inläggssynlighet"; + +"apSxMG-dYQ5NN" = "Det finns ${count} alternativ som matchar ‘Offentligt’."; + +"apSxMG-ehFLjY" = "Det finns ${count} alternativ som matchar ‘Endast följare’."; + +"ayoYEb-dYQ5NN" = "${content}, Offentligt"; + +"ayoYEb-ehFLjY" = "${content}, Endast följare"; + +"dUyuGg" = "Publicera på Mastodon"; + +"dYQ5NN" = "Offentligt"; + +"ehFLjY" = "Endast följare"; + +"gfePDu" = "Publicering misslyckades. ${failureReason}"; + +"k7dbKQ" = "Inlägget har publicerats."; + +"oGiqmY-dYQ5NN" = "Bara för att bekräfta, ville du ha 'Offentligt'?"; + +"oGiqmY-ehFLjY" = "Bara för att bekräfta, ville du ha 'Endast följare'?"; + +"rM6dvp" = "URL"; + +"ryJLwG" = "Inlägget har publicerats. "; diff --git a/Localization/StringsConvertor/Intents/input/sv_SE/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/sv.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/sv_SE/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/sv.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/sv_SE/Intents.strings b/Localization/StringsConvertor/Intents/input/sv_SE/Intents.strings deleted file mode 100644 index 83e02871c..000000000 --- a/Localization/StringsConvertor/Intents/input/sv_SE/Intents.strings +++ /dev/null @@ -1,51 +0,0 @@ -"16wxgf" = "Posta på Mastodon"; - -"751xkl" = "Textinnehåll"; - -"CsR7G2" = "Posta på Mastodon"; - -"HZSGTr" = "Vilket innehåll ska jag posta?"; - -"HdGikU" = "Inlägget misslyckades"; - -"KDNTJ4" = "Felorsak"; - -"RHxKOw" = "Skicka inlägg med textinnehåll"; - -"RxSqsb" = "Posta"; - -"WCIR3D" = "Posta ${content} på Mastodon"; - -"ZKJSNu" = "Posta"; - -"ZS1XaK" = "${content}"; - -"ZbSjzC" = "Synlighet"; - -"Zo4jgJ" = "Inläggssynlighet"; - -"apSxMG-dYQ5NN" = "Det finns ${count} alternativ som matchar ‘Publikt’."; - -"apSxMG-ehFLjY" = "Det finns ${count} alternativ som matchar ‘Endast följare’."; - -"ayoYEb-dYQ5NN" = "${content}, Publikt"; - -"ayoYEb-ehFLjY" = "${content}, Endast följare"; - -"dUyuGg" = "Posta på Mastodon"; - -"dYQ5NN" = "Publikt"; - -"ehFLjY" = "Endast följare"; - -"gfePDu" = "Inlägget misslyckades. ${failureReason}"; - -"k7dbKQ" = "Inlägget har postats."; - -"oGiqmY-dYQ5NN" = "Bara för att bekräfta, ville du ha 'Publikt'?"; - -"oGiqmY-ehFLjY" = "Bara för att bekräfta, ville du ha 'Endast följare'?"; - -"rM6dvp" = "URL"; - -"ryJLwG" = "Inlägget har postats. "; diff --git a/Localization/StringsConvertor/Intents/input/th_TH/Intents.strings b/Localization/StringsConvertor/Intents/input/th.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/th_TH/Intents.strings rename to Localization/StringsConvertor/Intents/input/th.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/th_TH/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/th.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/th_TH/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/th.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/tr_TR/Intents.strings b/Localization/StringsConvertor/Intents/input/tr.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/tr_TR/Intents.strings rename to Localization/StringsConvertor/Intents/input/tr.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/tr_TR/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/tr.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/tr_TR/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/tr.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/vi_VN/Intents.strings b/Localization/StringsConvertor/Intents/input/vi.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/vi_VN/Intents.strings rename to Localization/StringsConvertor/Intents/input/vi.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/vi_VN/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/vi.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/vi_VN/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/vi.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/zh_CN/Intents.strings b/Localization/StringsConvertor/Intents/input/zh-Hans.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/zh_CN/Intents.strings rename to Localization/StringsConvertor/Intents/input/zh-Hans.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/zh_CN/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/zh-Hans.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/zh_CN/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/zh-Hans.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Intents/input/zh_TW/Intents.strings b/Localization/StringsConvertor/Intents/input/zh-Hant.lproj/Intents.strings similarity index 100% rename from Localization/StringsConvertor/Intents/input/zh_TW/Intents.strings rename to Localization/StringsConvertor/Intents/input/zh-Hant.lproj/Intents.strings diff --git a/Localization/StringsConvertor/Intents/input/zh_TW/Intents.stringsdict b/Localization/StringsConvertor/Intents/input/zh-Hant.lproj/Intents.stringsdict similarity index 100% rename from Localization/StringsConvertor/Intents/input/zh_TW/Intents.stringsdict rename to Localization/StringsConvertor/Intents/input/zh-Hant.lproj/Intents.stringsdict diff --git a/Localization/StringsConvertor/Sources/StringsConvertor/main.swift b/Localization/StringsConvertor/Sources/StringsConvertor/main.swift index e30cf56a5..76dc722f6 100644 --- a/Localization/StringsConvertor/Sources/StringsConvertor/main.swift +++ b/Localization/StringsConvertor/Sources/StringsConvertor/main.swift @@ -47,31 +47,31 @@ private func convert(from inputDirectoryURL: URL, to outputDirectory: URL) { private func map(language: String) -> String? { switch language { - case "ar_SA": return "ar" // Arabic (Saudi Arabia) - case "eu_ES": return "eu-ES" // Basque - case "ca_ES": return "ca" // Catalan - case "zh_CN": return "zh-Hans" // Chinese Simplified - case "zh_TW": return "zh-Hant" // Chinese Traditional - case "nl_NL": return "nl" // Dutch - case "en_US": return "en" - case "fr_FR": return "fr" // French - case "gl_ES": return "gl" // Galician - case "de_DE": return "de" // German - case "it_IT": return "it" // Italian - case "ja_JP": return "ja" // Japanese - case "kab_KAB": return "kab" // Kabyle - case "kmr_TR": return "ku" // Kurmanji (Kurdish) - case "ru_RU": return "ru" // Russian - case "gd_GB": return "gd-GB" // Scottish Gaelic - case "ckb_IR": return "ckb" // Sorani (Kurdish) - case "es_ES": return "es" // Spanish - case "es_AR": return "es-419" // Spanish, Argentina - case "sv-SE": return "sv" // Swedish - case "sv_FI": return "sv_FI" // Swedish, Finland - case "th_TH": return "th" // Thai - case "tr_TR": return "tr" // Turkish - case "vi_VN": return "vi" // Vietnamese - default: return nil + case "ar.lproj": return "ar" // Arabic + case "eu.lproj": return "eu" // Basque + case "ca.lproj": return "ca" // Catalan + case "zh-Hans.lproj": return "zh-Hans" // Chinese Simplified + case "zh-Hant.lproj": return "zh-Hant" // Chinese Traditional + case "nl.lproj": return "nl" // Dutch + case "en.lproj": return "en" + case "fi.lproj": return "fi" // Finnish + case "fr.lproj": return "fr" // French + case "gl.lproj": return "gl" // Galician + case "de.lproj": return "de" // German + case "it.lproj": return "it" // Italian + case "ja.lproj": return "ja" // Japanese + case "kab.lproj": return "kab" // Kabyle + case "kmr.lproj": return "ku" // Kurmanji (Kurdish) [intent mapping] + case "ru.lproj": return "ru" // Russian + case "gd.lproj": return "gd" // Scottish Gaelic + case "ckb.lproj": return "ckb" // Sorani (Kurdish) + case "es.lproj": return "es" // Spanish + case "es_AR.lproj": return "es-AR" // Spanish, Argentina + case "sv.lproj": return "sv" // Swedish + case "th.lproj": return "th" // Thai + case "tr.lproj": return "tr" // Turkish + case "vi.lproj": return "vi" // Vietnamese + default: return nil } } diff --git a/Localization/StringsConvertor/input/ar_SA/Localizable.stringsdict b/Localization/StringsConvertor/input/ar.lproj/Localizable.stringsdict similarity index 88% rename from Localization/StringsConvertor/input/ar_SA/Localizable.stringsdict rename to Localization/StringsConvertor/input/ar.lproj/Localizable.stringsdict index c2f641720..197897e8e 100644 --- a/Localization/StringsConvertor/input/ar_SA/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/ar.lproj/Localizable.stringsdict @@ -74,6 +74,49 @@ %ld حَرف + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + zero + + one + + two + + few + + many + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + zero + مُتابَعٌ مِن قِبَلِ لَا أحَد + one + مُتابَعٌ مِن قِبَلِ %1$@، وشَخصٌ آخَرُ مُتبادَل + two + مُتابَعٌ مِن قِبَلِ %1$@، وشَخصانِ آخَرَانِ مُتبادَلَان + few + مُتابَعٌ مِن قِبَلِ %1$@، و%ld آخَرينَ مُتبادَلين + many + مُتابَعٌ مِن قِبَلِ %1$@، و%ld آخَرينَ مُتبادَلين + other + مُتابَعٌ مِن قِبَلِ %1$@، و%ld آخَرَ مُتبادَل + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -98,6 +141,30 @@ منشور + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + zero + لا وسيطة + one + وسيطةٌ واحِدَة + two + وسيطتانِ اِثنتان + few + %ld أوساط + many + %ld وَسَطًا + other + %ld وَسَط + + plural.count.post NSStringLocalizedFormatKey @@ -109,7 +176,7 @@ NSStringFormatValueTypeKey ld zero - لا منشور + لا مَنشورات one منشورٌ واحِد two @@ -447,13 +514,13 @@ zero تتبقى لَحظة one - تتبقى ثانية + تتبقى ثانية واحِدة two - تتبقى ثانيتين + تتبقى ثانيتان few تتبقى %ld ثوان many - تتبقى %ld ثانيةً + تتبقى %ld ثانية other تتبقى %ld ثانية diff --git a/Localization/StringsConvertor/input/ar_SA/app.json b/Localization/StringsConvertor/input/ar.lproj/app.json similarity index 84% rename from Localization/StringsConvertor/input/ar_SA/app.json rename to Localization/StringsConvertor/input/ar.lproj/app.json index 4b28b011a..6fce051fb 100644 --- a/Localization/StringsConvertor/input/ar_SA/app.json +++ b/Localization/StringsConvertor/input/ar.lproj/app.json @@ -71,7 +71,7 @@ "cancel": "إلغاء", "discard": "تجاهُل", "try_again": "المُحاولة مرة أُخرى", - "take_photo": "التقاط صورة", + "take_photo": "اِلتِقاطُ صُورَة", "save_photo": "حفظ الصورة", "copy_photo": "نسخ الصورة", "sign_in": "تسجيل الدخول", @@ -240,7 +240,8 @@ "category": "الفئة" }, "input": { - "placeholder": "اِبحَث عن خادِم أو انضم إلى آخر خاص بك..." + "placeholder": "اِبحَث عن خادِم أو انضم إلى آخر خاص بك...", + "search_servers_or_enter_url": "اِبحَث فِي الخَوادِم أو أدخِل رابِط" }, "empty_state": { "finding_servers": "يجري إيجاد خوادم متوفِّرَة...", @@ -250,6 +251,7 @@ }, "register": { "title": "أخبرنا عن نفسك.", + "lets_get_you_set_up_on_domain": "دَعنا نَبدَأُ بِإعدادِكَ عَلَى %s", "input": { "avatar": { "delete": "حذف" @@ -319,7 +321,8 @@ }, "confirm_email": { "title": "شيءٌ أخير.", - "subtitle": "لقد أرسلنا للتو بريد إلكتروني إلى %s،\nانقر على الرابط لتأكيد حسابك.", + "subtitle": "أنقر على الرابط المرسل إليك لاستيثاق حسابك.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "اُنقُر عَلَى الرَّابِطِ الَّذي أرسَلناهُ إليكَ عَبرَ البَريدِ الإلِكتُرُونيّ لِلتَّحَقُقِ مِن حِسابِك", "button": { "open_email_app": "فتح تطبيق البريد الإلكتروني", "resend": "إعادَةُ الإرسال" @@ -342,7 +345,11 @@ "offline": "غَير مُتَّصِل", "new_posts": "إظهار منشورات جديدة", "published": "تمَّ النَّشر!", - "Publishing": "يَجري نَشر المُشارَكَة..." + "Publishing": "يَجري نَشر المُشارَكَة...", + "accessibility": { + "logo_label": "ُّزِرُّ الشِّعار", + "logo_hint": "اُنقُر لِلتمريرِ لأعلى واُنقُر مَرّةً أُخرَى لِلذَّهابِ إلَى المَوقِعِ السَّابِق" + } } }, "suggestion_account": { @@ -355,11 +362,11 @@ "new_reply": "رَدٌّ جديد" }, "media_selection": { - "camera": "إلتقاط صورة", - "photo_library": "مكتبة الصور", - "browse": "تصفح" + "camera": "اِلتِقاطُ صُورَة", + "photo_library": "مَكتَبَةُ الصُّوَر", + "browse": "تَصَفَّح" }, - "content_input_placeholder": "أخبِرنا بِما يَجُولُ فِي ذِهنَك", + "content_input_placeholder": "عَبِّر عَمَّ يَجُولُ فِي ذِهنِك", "compose_action": "نَشر", "replying_to_user": "رَدًا على %s", "attachment": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "مُتابِعِين", "footer": "لا يُمكِن عَرض المُتابِعين مِنَ الخوادم الأُخرى." }, "following": { + "title": "مُتابَعُون", "footer": "لا يُمكِن عَرض المُتابَعات مِنَ الخوادم الأُخرى." }, + "familiarFollowers": { + "title": "مُتابِعُونَ مَألُوفُونَ بِالنِّسبَةِ لَك", + "followed_by_names": "مُتابَعٌ مِن قِبَلِ %s" + }, + "favorited_by": { + "title": "مُفَضَّلٌ مِن قِبَلِ" + }, + "reblogged_by": { + "title": "اُعيدَ تَدوينَهُ بِواسِطَةِ" + }, "search": { "title": "البَحث", "search_bar": { @@ -588,15 +607,57 @@ "report": { "title_report": "إبلاغ", "title": "الإبلاغ عن %s", - "step1": "الخطوة الأولى مِن أصل اثنتين", - "step2": "الخطوة الثانية والأخيرة", + "step1": "الخطوة 1 مِن أصل 2", + "step2": "الخطوة 2 مِن أصل 2", "content1": "هل ترغب في إضافة أي منشورات أُخرى إلى البلاغ؟", "content2": "هل هناك أي شيء يجب أن يعرفه المُراقبين حول هذا البلاغ؟", "report_sent_title": "شُكرًا لَكَ على الإبلاغ، سَوفَ نَنظُرُ فِي هَذَا الأمر.", "send": "إرسال البلاغ", "skip_to_send": "إرسال بدون تعليق", "text_placeholder": "اكتب أو الصق تعليقات إضافيَّة", - "reported": "مُبْلَغٌ عَنه" + "reported": "مُبْلَغٌ عَنه", + "step_one": { + "step_1_of_4": "الخطوة 1 مِن أصل 4", + "whats_wrong_with_this_post": "ما المُشكِلَةُ فِي هَذَا المَنشُور؟", + "whats_wrong_with_this_account": "ما المُشكِلَةُ فِي هَذَا الحِساب؟", + "whats_wrong_with_this_username": "ما المُشكِلَة مَعَ %s؟", + "select_the_best_match": "اِختَر أفضلَ تَطابُق", + "i_dont_like_it": "لا يُعجِبُني", + "it_is_not_something_you_want_to_see": "إنَّهُ ليسَ شيئًا تُريدُ رُؤيَتَه", + "its_spam": "إنَّهُ غَيرٌ مَرغوبٍ فيه", + "malicious_links_fake_engagement_or_repetetive_replies": "رَوابِطٌ ضَارَّة، اِرتِباطاتٌ مُزيَّفَة أو رُدودٌ مُتَكَرِّرَة", + "it_violates_server_rules": "يَنتَهِكُ قَواعِدَ الخادِم", + "you_are_aware_that_it_breaks_specific_rules": "أنتَ مُدِركٌ لِانتِهاكِهِ قَواعِدًا مُحَدَّدَة", + "its_something_else": "إنَّهُ شَيءٌ آخَر", + "the_issue_does_not_fit_into_other_categories": "المُشكِلَةُ لَا تَتَناسَبُ مَعَ الفِئاتِ الأُخرَى" + }, + "step_two": { + "step_2_of_4": "الخطوة 2 مِن أصل 4", + "which_rules_are_being_violated": "مَا هِيَ القَواعِدُ الَّتي تُنتَهَك؟", + "select_all_that_apply": "اِختَر كُلَّ ما يَنطَبِق", + "i_just_don’t_like_it": "أنا فَقَط لا يُعجِبُني" + }, + "step_three": { + "step_3_of_4": "الخطوة 3 مِن أصل 4", + "are_there_any_posts_that_back_up_this_report": "هَل هُناكَ أيُّ مَنشُوراتٍ أُخرَى تَتَوافَقُ مَعَ هَذَا التَّقرير؟", + "select_all_that_apply": "اِختَر كُلَّ ما يَنطَبِق" + }, + "step_four": { + "step_4_of_4": "الخطوة 4 مِن أصل 4", + "is_there_anything_else_we_should_know": "هَل هُناكَ شَيءٌ آخَرَ يَجِبُ أن نَعلَمَ بِه؟" + }, + "step_final": { + "dont_want_to_see_this": "ألَا تُريدُ رُؤيَةَ هَذَا؟", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "عِندما تَرى شيئًا لَا يُعجِبُكَ عَلَى مَاستودُون، يُمكِنُكَ إزالَةُ الشَّخصِ مِن تَجرِبَتِك.", + "unfollow": "إلغاءُ المُتابَعَة", + "unfollowed": "أُلغِيَت المُتابَعَة", + "unfollow_user": "إلغاءُ مُتابَعَةِ %s", + "mute_user": "كَتمُ %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "لَن تَرى مُشارَكاتِهِ أو إعادَاتِ تَدوينَهِ فِي تغذيَتِكَ الرَّئيسَة. لَن يَعرِفَ أنَّهُ قَد كُتِمَ أيضًا.", + "block_user": "حَظرُ %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "لَن يَتمكَّنَ بَعدَ الآنِ مِن مُتابَعَةِ مَنشوراتِكَ أو رُؤيَتِها، وَلكِن يُمكِنَهُ مَعرِفَةُ مَا إذا حُظَرِت عَنه.", + "while_we_review_this_you_can_take_action_against_user": "أثناءُ مُراجَعَتِنا لِذلِك، يُمكِنُكَ اِتِّخاذُ إجراءٍ ضِدَّ %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/ar_SA/ios-infoPlist.json b/Localization/StringsConvertor/input/ar.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/ar_SA/ios-infoPlist.json rename to Localization/StringsConvertor/input/ar.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/ca_ES/Localizable.stringsdict b/Localization/StringsConvertor/input/ca.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/ca_ES/Localizable.stringsdict rename to Localization/StringsConvertor/input/ca.lproj/Localizable.stringsdict index dfbd38c0b..cc28edbc6 100644 --- a/Localization/StringsConvertor/input/ca_ES/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/ca.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld caràcters + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Seguit per %1$@, i un altre mutu + other + Seguit per %1$@, i %ld mutus + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ publicacions + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 mèdia + other + %ld mèdia + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/ca_ES/app.json b/Localization/StringsConvertor/input/ca.lproj/app.json similarity index 85% rename from Localization/StringsConvertor/input/ca_ES/app.json rename to Localization/StringsConvertor/input/ca.lproj/app.json index 7789c6169..2f300fd3d 100644 --- a/Localization/StringsConvertor/input/ca_ES/app.json +++ b/Localization/StringsConvertor/input/ca.lproj/app.json @@ -240,16 +240,18 @@ "category": "CATEGORIA" }, "input": { - "placeholder": "Troba un servidor o uneix-te al teu..." + "placeholder": "Cerca servidors", + "search_servers_or_enter_url": "Cerca servidors o introdueix l'enllaç" }, "empty_state": { "finding_servers": "Cercant els servidors disponibles...", - "bad_network": "S'ha produït un error en carregar les dades. Comprova la teva connexió a Internet.", + "bad_network": "Alguna cosa no ha anat bé en carregar les dades. Comprova la teva connexió a Internet.", "no_results": "No hi ha resultats" } }, "register": { - "title": "Parla'ns de tu.", + "title": "Anem a configurar-te a %s", + "lets_get_you_set_up_on_domain": "Anem a configurar-te a %s", "input": { "avatar": { "delete": "Suprimeix" @@ -309,7 +311,7 @@ }, "server_rules": { "title": "Algunes regles bàsiques.", - "subtitle": "Aquestes regles estan establertes per els administradors de %s.", + "subtitle": "Aquestes regles estan establertes i aplicades per els moderadors de %s.", "prompt": "Al continuar, estàs subjecte als termes de servei i a la política de privacitat de %s.", "terms_of_service": "termes del servei", "privacy_policy": "política de privadesa", @@ -320,6 +322,7 @@ "confirm_email": { "title": "Una última cosa.", "subtitle": "Toca l'enllaç del correu electrònic que t'hem enviat per a confirmar el teu compte.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Toca l'enllaç del correu electrònic que t'hem enviat per a confirmar el teu compte", "button": { "open_email_app": "Obre l'aplicació de correu", "resend": "Reenvia" @@ -342,11 +345,15 @@ "offline": "Fora de línia", "new_posts": "Veure noves publicacions", "published": "Publicat!", - "Publishing": "S'està publicant..." + "Publishing": "S'està publicant...", + "accessibility": { + "logo_label": "Botó de logotip", + "logo_hint": "Toca per desplaçar-te cap a dalt i torna a toca de nou per tornar a la ubicació anterior" + } } }, "suggestion_account": { - "title": "Cerca Persones per Seguir", + "title": "Cerca Persones a Seguir", "follow_explain": "Quan segueixes algú, veuràs les seves publicacions a Inici." }, "compose": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "seguidor", "footer": "Els seguidors d'altres servidors no son mostrats." }, "following": { + "title": "seguint", "footer": "Els seguits d'altres servidors no son mostrats." }, + "familiarFollowers": { + "title": "Seguidors coneguts", + "followed_by_names": "Seguit per %s" + }, + "favorited_by": { + "title": "Preferit per" + }, + "reblogged_by": { + "title": "Impulsat per" + }, "search": { "title": "Cerca", "search_bar": { @@ -596,7 +615,49 @@ "send": "Envia Informe", "skip_to_send": "Envia sense comentaris", "text_placeholder": "Escriu o enganxa comentaris addicionals", - "reported": "REPORTAT" + "reported": "REPORTAT", + "step_one": { + "step_1_of_4": "Pas 1 de 4", + "whats_wrong_with_this_post": "Quin és el problema amb aquesta publicació?", + "whats_wrong_with_this_account": "Quin és el problema amb aquest compte?", + "whats_wrong_with_this_username": "Quin és el problema amb %s?", + "select_the_best_match": "Selecciona la millor coincidència", + "i_dont_like_it": "No m'agrada", + "it_is_not_something_you_want_to_see": "No és una cosa que vulguis veure", + "its_spam": "És contingut brossa", + "malicious_links_fake_engagement_or_repetetive_replies": "Enllaços maliciosos, compromís falç o respostes repetitives", + "it_violates_server_rules": "Infringeix les normes del servidor", + "you_are_aware_that_it_breaks_specific_rules": "Ets conscient que incompleix normes específiques", + "its_something_else": "És una altra cosa", + "the_issue_does_not_fit_into_other_categories": "El problema no encaixa en altres categories" + }, + "step_two": { + "step_2_of_4": "Pas 2 de 4", + "which_rules_are_being_violated": "Quines normes s'estan infringint?", + "select_all_that_apply": "Selecciona tot el que correspongui", + "i_just_don’t_like_it": "Simplement no m'agrada" + }, + "step_three": { + "step_3_of_4": "Pas 3 de 4", + "are_there_any_posts_that_back_up_this_report": "Hi ha alguna publicació que recolzi aquest informe?", + "select_all_that_apply": "Selecciona tot el que correspongui" + }, + "step_four": { + "step_4_of_4": "Pas 4 de 4", + "is_there_anything_else_we_should_know": "Hi ha res més que hauríem de saber?" + }, + "step_final": { + "dont_want_to_see_this": "No vols veure això?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Quan veus alguna cosa que no t'agrada a Mastodon, pots eliminar la persona de la vostra experiència.", + "unfollow": "Deixa de seguir", + "unfollowed": "S'ha deixat de seguir", + "unfollow_user": "Deixa de seguir %s", + "mute_user": "Silencia %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "No veuràs les seves publicacions o impulsos a la teva línia de temps personal. No sabran que han estat silenciats.", + "block_user": "Bloca %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Ja no podran seguir ni veure les teves publicacions, però poden veure si han estat bloquejats.", + "while_we_review_this_you_can_take_action_against_user": "Mentre ho revisem, pots prendre mesures contra %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/ca_ES/ios-infoPlist.json b/Localization/StringsConvertor/input/ca.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/ca_ES/ios-infoPlist.json rename to Localization/StringsConvertor/input/ca.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/ckb_IR/Localizable.stringsdict b/Localization/StringsConvertor/input/ckb.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/ckb_IR/Localizable.stringsdict rename to Localization/StringsConvertor/input/ckb.lproj/Localizable.stringsdict index e744a4bd5..001a8a608 100644 --- a/Localization/StringsConvertor/input/ckb_IR/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/ckb.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld نووسە + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ پۆست + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/ckb_IR/app.json b/Localization/StringsConvertor/input/ckb.lproj/app.json similarity index 89% rename from Localization/StringsConvertor/input/ckb_IR/app.json rename to Localization/StringsConvertor/input/ckb.lproj/app.json index de4aab374..7b6596235 100644 --- a/Localization/StringsConvertor/input/ckb_IR/app.json +++ b/Localization/StringsConvertor/input/ckb.lproj/app.json @@ -240,7 +240,8 @@ "category": "بەش" }, "input": { - "placeholder": "بگەڕێ" + "placeholder": "بگەڕێ", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "ڕاژەکار دەدۆزرێتەوە...", @@ -250,6 +251,7 @@ }, "register": { "title": "خۆت تۆمار بکە لە %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "بیسڕەوە" @@ -320,6 +322,7 @@ "confirm_email": { "title": "کۆتا شت.", "subtitle": "بۆ پشتڕاستکردنەوەی هەژمارەکەت ئەو بەستەرە بکەوە کە بە ئیمێڵ بۆمان ناردوویت.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", "button": { "open_email_app": "بەرنامەی ئیمێڵەکەت بکەوە", "resend": "بینێرەوە" @@ -342,7 +345,11 @@ "offline": "دەرهێڵ", "new_posts": "پۆستە نوێکان ببینە", "published": "بڵاوکرایەوە!", - "Publishing": "پۆستەکە بڵاو دەکرێتەوە..." + "Publishing": "پۆستەکە بڵاو دەکرێتەوە...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "شوێنکەوتووەکانی لە ڕاژەکارەکانی ترەوە نیشان نادرێت." }, "following": { + "title": "following", "footer": "شوێنکەوتنەکانی بۆ هەژماری ڕاژەکارەکانی تر نیشان نادرێت." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "بگەڕێ", "search_bar": { @@ -596,7 +615,49 @@ "send": "سکاڵاکە بنێرە", "skip_to_send": "بەبێ لێدوان بینێرە", "text_placeholder": "ڕوونکردنەوەی زۆرتر بدە", - "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/ckb_IR/ios-infoPlist.json b/Localization/StringsConvertor/input/ckb.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/ckb_IR/ios-infoPlist.json rename to Localization/StringsConvertor/input/ckb.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/cy_GB/Localizable.stringsdict b/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict similarity index 89% rename from Localization/StringsConvertor/input/cy_GB/Localizable.stringsdict rename to Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict index e0f1e0f2c..038eaffda 100644 --- a/Localization/StringsConvertor/input/cy_GB/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/cy.lproj/Localizable.stringsdict @@ -47,7 +47,7 @@ many %ld characters other - %ld characters + %ld nodau a11y.plural.count.input_limit_remains @@ -74,6 +74,49 @@ %ld characters + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + zero + + one + + two + + few + + many + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + zero + Followed by %1$@, and %ld mutuals + one + Followed by %1$@, and another mutual + two + Followed by %1$@, and %ld mutuals + few + Followed by %1$@, and %ld mutuals + many + Followed by %1$@, and %ld mutuals + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -85,17 +128,41 @@ NSStringFormatValueTypeKey ld zero - posts + post one post two - posts + postiau few posts many posts other - posts + postiau + + + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + zero + %ld media + one + 1 media + two + %ld media + few + %ld media + many + %ld media + other + %ld media plural.count.post diff --git a/Localization/StringsConvertor/input/cy.lproj/app.json b/Localization/StringsConvertor/input/cy.lproj/app.json new file mode 100644 index 000000000..99eb2784a --- /dev/null +++ b/Localization/StringsConvertor/input/cy.lproj/app.json @@ -0,0 +1,680 @@ +{ + "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" + }, + "actions": { + "reply": "Reply", + "reblog": "Hybwch", + "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" + }, + "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 can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", + "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", + "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", + "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", + "suspended_warning": "This user has been suspended.", + "user_suspended_warning": "%s’s 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": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s 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 (can’t 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, you’re 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 haven’t.", + "resend_email": "Resend Email" + }, + "open_email_app": { + "title": "Check your inbox.", + "description": "We just sent you an email. Check your junk folder if you haven’t.", + "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, you’ll 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 what’s on your mind", + "compose_action": "Publish", + "replying_to_user": "replying to %s", + "attachment": { + "photo": "photo", + "video": "video", + "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", + "description_photo": "Describe the photo for the visually-impaired...", + "description_video": "Describe the video for the visually-impaired..." + }, + "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" + }, + "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" + }, + "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": { + "dashboard": { + "posts": "postiadau", + "following": "following", + "followers": "followers" + }, + "fields": { + "add_row": "Add Row", + "placeholder": { + "label": "Label", + "content": "Content" + } + }, + "segmented_control": { + "posts": "Postiadau", + "replies": "Replies", + "posts_and_replies": "Postiadau ac Atebion", + "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" + } + }, + "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": "Postiadau" + }, + "empty_state": { + "no_results": "No results" + }, + "recent_search": "Recent searches", + "clear": "Clear" + } + }, + "discovery": { + "tabs": { + "posts": "Postiadau", + "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" + } + }, + "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 you’d like to add to the report?", + "content2": "Is there anything the moderators should know about this report?", + "report_sent_title": "Thanks for reporting, we’ll 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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve 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" + } + } +} \ No newline at end of file diff --git a/Localization/StringsConvertor/input/cy.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/cy.lproj/ios-infoPlist.json new file mode 100644 index 000000000..ee0c5bfee --- /dev/null +++ b/Localization/StringsConvertor/input/cy.lproj/ios-infoPlist.json @@ -0,0 +1,6 @@ +{ + "NSCameraUsageDescription": "Used to take photo for post status", + "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", + "NewPostShortcutItemTitle": "Post Newydd", + "SearchShortcutItemTitle": "Chwilio" +} diff --git a/Localization/StringsConvertor/input/da_DK/Localizable.stringsdict b/Localization/StringsConvertor/input/da.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/da_DK/Localizable.stringsdict rename to Localization/StringsConvertor/input/da.lproj/Localizable.stringsdict index 503ff9dbd..bdcae6ac9 100644 --- a/Localization/StringsConvertor/input/da_DK/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/da.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld characters + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ posts + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/cy_GB/app.json b/Localization/StringsConvertor/input/da.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/cy_GB/app.json rename to Localization/StringsConvertor/input/da.lproj/app.json index 50512250d..2a8634a67 100644 --- a/Localization/StringsConvertor/input/cy_GB/app.json +++ b/Localization/StringsConvertor/input/da.lproj/app.json @@ -240,7 +240,8 @@ "category": "CATEGORY" }, "input": { - "placeholder": "Search servers" + "placeholder": "Search servers", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Finding available servers...", @@ -250,6 +251,7 @@ }, "register": { "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Delete" @@ -320,6 +322,7 @@ "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" @@ -342,7 +345,11 @@ "offline": "Offline", "new_posts": "See new posts", "published": "Published!", - "Publishing": "Publishing post..." + "Publishing": "Publishing post...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Followers from other servers are not displayed." }, "following": { + "title": "following", "footer": "Follows from other servers are not displayed." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Search", "search_bar": { @@ -596,7 +615,49 @@ "send": "Send Report", "skip_to_send": "Send without comment", "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/cy_GB/ios-infoPlist.json b/Localization/StringsConvertor/input/da.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/cy_GB/ios-infoPlist.json rename to Localization/StringsConvertor/input/da.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/de_DE/Localizable.stringsdict b/Localization/StringsConvertor/input/de.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/de_DE/Localizable.stringsdict rename to Localization/StringsConvertor/input/de.lproj/Localizable.stringsdict index 20e8b615e..3ea0fd0e3 100644 --- a/Localization/StringsConvertor/input/de_DE/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/de.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld Zeichen + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ Beiträge + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/de_DE/app.json b/Localization/StringsConvertor/input/de.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/de_DE/app.json rename to Localization/StringsConvertor/input/de.lproj/app.json index 75b01afd3..d0c61847c 100644 --- a/Localization/StringsConvertor/input/de_DE/app.json +++ b/Localization/StringsConvertor/input/de.lproj/app.json @@ -129,7 +129,7 @@ "show_post": "Beitrag anzeigen", "show_user_profile": "Benutzerprofil anzeigen", "content_warning": "Inhaltswarnung", - "sensitive_content": "Sensitive Content", + "sensitive_content": "NSFW-Inhalt", "media_content_warning": "Tippe irgendwo zum Anzeigen", "tap_to_reveal": "Zum Anzeigen tippen", "poll": { @@ -207,7 +207,7 @@ "scene": { "welcome": { "slogan": "Soziale Netzwerke wieder in deinen Händen.", - "get_started": "Erste Schritte", + "get_started": "Registrieren", "log_in": "Anmelden" }, "server_picker": { @@ -240,7 +240,8 @@ "category": "KATEGORIE" }, "input": { - "placeholder": "Finde einen Server oder trete deinem eigenen bei..." + "placeholder": "Nach Server suchen oder URL eingeben", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Verfügbare Server werden gesucht...", @@ -250,6 +251,7 @@ }, "register": { "title": "Erzähle uns von dir.", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Löschen" @@ -319,7 +321,8 @@ }, "confirm_email": { "title": "Noch eine letzte Sache.", - "subtitle": "Wir haben gerade eine E-Mail an %s gesendet,\ntippe darin auf den Link, um Dein Konto zu bestätigen.", + "subtitle": "Schaue kurz in dein E-Mail-Postfach und tippe den Link an, den wir dir gesendet haben.", + "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": "E-Mail-App öffnen", "resend": "Erneut senden" @@ -342,7 +345,11 @@ "offline": "Offline", "new_posts": "Neue Beiträge anzeigen", "published": "Veröffentlicht!", - "Publishing": "Beitrag wird veröffentlicht..." + "Publishing": "Beitrag wird veröffentlicht...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Follower von anderen Servern werden nicht angezeigt." }, "following": { + "title": "following", "footer": "Wem das Konto folgt wird von anderen Servern werden nicht angezeigt." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Suche", "search_bar": { @@ -501,7 +520,7 @@ "community": "Community", "for_you": "Für dich" }, - "intro": "These are the posts gaining traction in your corner of Mastodon." + "intro": "Dies sind die Beiträge, die in deiner Umgebung auf Mastodon beliebter werden." }, "favorite": { "title": "Deine Favoriten" @@ -596,7 +615,49 @@ "send": "Meldung abschicken", "skip_to_send": "Ohne Kommentar abschicken", "text_placeholder": "Zusätzliche Kommentare eingeben oder einfügen", - "reported": "GEMELDET" + "reported": "GEMELDET", + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { @@ -612,7 +673,7 @@ }, "wizard": { "new_in_mastodon": "Neu in Mastodon", - "multiple_account_switch_intro_description": "Wechsel zwischen mehreren Konten durch drücken der Profil-Schaltfläche.", + "multiple_account_switch_intro_description": "Wechsel zwischen mehreren Konten durch Drücken der Profil-Schaltfläche.", "accessibility_hint": "Doppeltippen, um diesen Assistenten zu schließen" } } diff --git a/Localization/StringsConvertor/input/de_DE/ios-infoPlist.json b/Localization/StringsConvertor/input/de.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/de_DE/ios-infoPlist.json rename to Localization/StringsConvertor/input/de.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/fi_FI/Localizable.stringsdict b/Localization/StringsConvertor/input/en-US.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/fi_FI/Localizable.stringsdict rename to Localization/StringsConvertor/input/en-US.lproj/Localizable.stringsdict index 503ff9dbd..bdcae6ac9 100644 --- a/Localization/StringsConvertor/input/fi_FI/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/en-US.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld characters + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ posts + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/da_DK/app.json b/Localization/StringsConvertor/input/en-US.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/da_DK/app.json rename to Localization/StringsConvertor/input/en-US.lproj/app.json index 50512250d..2a8634a67 100644 --- a/Localization/StringsConvertor/input/da_DK/app.json +++ b/Localization/StringsConvertor/input/en-US.lproj/app.json @@ -240,7 +240,8 @@ "category": "CATEGORY" }, "input": { - "placeholder": "Search servers" + "placeholder": "Search servers", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Finding available servers...", @@ -250,6 +251,7 @@ }, "register": { "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Delete" @@ -320,6 +322,7 @@ "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" @@ -342,7 +345,11 @@ "offline": "Offline", "new_posts": "See new posts", "published": "Published!", - "Publishing": "Publishing post..." + "Publishing": "Publishing post...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Followers from other servers are not displayed." }, "following": { + "title": "following", "footer": "Follows from other servers are not displayed." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Search", "search_bar": { @@ -596,7 +615,49 @@ "send": "Send Report", "skip_to_send": "Send without comment", "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/da_DK/ios-infoPlist.json b/Localization/StringsConvertor/input/en-US.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/da_DK/ios-infoPlist.json rename to Localization/StringsConvertor/input/en-US.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/en_US/Localizable.stringsdict b/Localization/StringsConvertor/input/en.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/en_US/Localizable.stringsdict rename to Localization/StringsConvertor/input/en.lproj/Localizable.stringsdict index 503ff9dbd..bdcae6ac9 100644 --- a/Localization/StringsConvertor/input/en_US/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/en.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld characters + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ posts + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/en_US/app.json b/Localization/StringsConvertor/input/en.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/en_US/app.json rename to Localization/StringsConvertor/input/en.lproj/app.json index 50512250d..2a8634a67 100644 --- a/Localization/StringsConvertor/input/en_US/app.json +++ b/Localization/StringsConvertor/input/en.lproj/app.json @@ -240,7 +240,8 @@ "category": "CATEGORY" }, "input": { - "placeholder": "Search servers" + "placeholder": "Search servers", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Finding available servers...", @@ -250,6 +251,7 @@ }, "register": { "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Delete" @@ -320,6 +322,7 @@ "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" @@ -342,7 +345,11 @@ "offline": "Offline", "new_posts": "See new posts", "published": "Published!", - "Publishing": "Publishing post..." + "Publishing": "Publishing post...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Followers from other servers are not displayed." }, "following": { + "title": "following", "footer": "Follows from other servers are not displayed." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Search", "search_bar": { @@ -596,7 +615,49 @@ "send": "Send Report", "skip_to_send": "Send without comment", "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/en_US/ios-infoPlist.json b/Localization/StringsConvertor/input/en.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/en_US/ios-infoPlist.json rename to Localization/StringsConvertor/input/en.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/es_AR/Localizable.stringsdict b/Localization/StringsConvertor/input/es-AR.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/es_AR/Localizable.stringsdict rename to Localization/StringsConvertor/input/es-AR.lproj/Localizable.stringsdict index 9d1fdadb6..2bd66395a 100644 --- a/Localization/StringsConvertor/input/es_AR/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/es-AR.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld caracteres + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@: "%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Seguido por %1$@ y otra cuenta mutua + other + Seguido por %1$@ y otras %ld cuentas mutuas + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ mensajes + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 medio + other + %ld medios + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/es_AR/app.json b/Localization/StringsConvertor/input/es-AR.lproj/app.json similarity index 82% rename from Localization/StringsConvertor/input/es_AR/app.json rename to Localization/StringsConvertor/input/es-AR.lproj/app.json index 8ef75d107..9ccf1f998 100644 --- a/Localization/StringsConvertor/input/es_AR/app.json +++ b/Localization/StringsConvertor/input/es-AR.lproj/app.json @@ -180,7 +180,7 @@ "unmute": "Dejar de silenciar", "unmute_user": "Dejar de silenciar a %s", "muted": "Silenciado", - "edit_info": "Editar información" + "edit_info": "Editar" }, "timeline": { "filtered": "Filtrado", @@ -194,11 +194,11 @@ }, "header": { "no_status_found": "Mensaje no encontrado", - "blocking_warning": "No podés ver el perfil de este usuario\n hasta que lo desbloquees.\nTu perfil le aparece así a este usuario.", - "user_blocking_warning": "No podés ver el perfil de %s\n hasta que lo desbloquees.\nTu perfil le aparece así a este usuario.", - "blocked_warning": "No podés ver el perfil de este usuario\n hasta que dicho usuario te desbloquee.", - "user_blocked_warning": "No podés ver el perfil de %s\n hasta que dicho usuario te desbloquee.", - "suspended_warning": "Este usuario está suspendido.", + "blocking_warning": "No podés ver el perfil de este usuario\nhasta que lo desbloquees.\nTu perfil le aparece así a este usuario.", + "user_blocking_warning": "No podés ver el perfil de %s\nhasta que lo desbloquees.\nTu perfil le aparece así a este usuario.", + "blocked_warning": "No podés ver el perfil de este usuario\nhasta que dicho usuario te desbloquee.", + "user_blocked_warning": "No podés ver el perfil de %s\nhasta que dicho usuario te desbloquee.", + "suspended_warning": "Esta cuenta está suspendida.", "user_suspended_warning": "La cuenta de %s está suspendida." } } @@ -211,16 +211,16 @@ "log_in": "Iniciar sesión" }, "server_picker": { - "title": "Elegí un servidor,\nel que quieras.", - "subtitle": "Elegí una comunidad basada en tus intereses, región o una de propósitos generales.", - "subtitle_extend": "Elegí una comunidad basada en tus intereses, región o una de propósitos generales. Cada comunidad es operada por una organización o individuo totalmente independiente.", + "title": "Mastodon está compuesto de cuentas en diferentes servidores.", + "subtitle": "Elegí un servidor basado en tus intereses, región, o de propósitos generales.", + "subtitle_extend": "Elegí un servidor basado en tus intereses, región, o de propósitos generales. Cada servidor es operado por una organización o individuo totalmente independientes.", "button": { "category": { "all": "Todas", "all_accessiblity_description": "Categoría: Todas", "academia": "académico", "activism": "activismo", - "food": "comida", + "food": "alimentación", "furry": "furry", "games": "juegos", "general": "general", @@ -240,7 +240,8 @@ "category": "CATEGORÍA" }, "input": { - "placeholder": "Encontrá un servidor o unite al tuyo…" + "placeholder": "Buscar servidores", + "search_servers_or_enter_url": "Buscar servidores o introducir dirección web" }, "empty_state": { "finding_servers": "Buscando servidores disponibles…", @@ -249,7 +250,8 @@ } }, "register": { - "title": "Contanos sobre vos.", + "title": "Vamos a prepararte en %s", + "lets_get_you_set_up_on_domain": "Vamos a prepararte en %s", "input": { "avatar": { "delete": "Eliminar" @@ -284,7 +286,7 @@ "email": "Correo electrónico", "password": "Contraseña", "agreement": "Acuerdo", - "locale": "Idioma de la interface", + "locale": "Interno", "reason": "Motivo" }, "reason": { @@ -319,7 +321,8 @@ }, "confirm_email": { "title": "Una última cosa.", - "subtitle": "Acabamos de enviar un correo electrónico a %s,\npulsá en el enlace para confirmar tu cuenta.", + "subtitle": "Tocá el enlace que te enviamos por correo electrónico para verificar tu cuenta.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tocá el enlace que te enviamos por correo electrónico para verificar tu cuenta", "button": { "open_email_app": "Abrir aplicación de correo electrónico", "resend": "Reenviar" @@ -340,14 +343,18 @@ "title": "Principal", "navigation_bar_state": { "offline": "Desconectado", - "new_posts": "Ver nuevos mensajes", + "new_posts": "Ver nuevos msjs", "published": "¡Enviado!", - "Publishing": "Enviando mensaje…" + "Publishing": "Enviando mensaje…", + "accessibility": { + "logo_label": "Botón de logo", + "logo_hint": "Tocá para desplazarte hacia arriba y tocá de nuevo para ir a la ubicación anterior" + } } }, "suggestion_account": { "title": "Encontrá cuentas para seguir", - "follow_explain": "Cuando sigás a alguien, verás sus mensajes en tu línea temporal principal." + "follow_explain": "Cuando sigás una cuenta, verás sus mensajes en tu línea temporal principal." }, "compose": { "title": { @@ -363,10 +370,10 @@ "compose_action": "Enviar", "replying_to_user": "respondiendo a %s", "attachment": { - "photo": "foto", + "photo": "imagen", "video": "video", "attachment_broken": "Este archivo de %s está roto\ny no se puede subir a Mastodon.", - "description_photo": "Describí la foto para personas con dificultades visuales…", + "description_photo": "Describí la imagen para personas con dificultades visuales…", "description_video": "Describí el video para personas con dificultades visuales…" }, "poll": { @@ -389,7 +396,7 @@ "direct": "Sólo a las cuentas que menciono" }, "auto_complete": { - "space_to_add": "Espacio para agregar" + "space_to_add": "Tocá la tecla «Espacio» para agregar" }, "accessibility": { "append_attachment": "Agregar archivo adjunto", @@ -455,11 +462,23 @@ } }, "follower": { + "title": "seguidor", "footer": "No se muestran los seguidores de otros servidores." }, "following": { + "title": "siguiendo", "footer": "No se muestran las cuentas de otros servidores que seguís." }, + "familiarFollowers": { + "title": "Seguidores conocidos", + "followed_by_names": "Seguido por %s" + }, + "favorited_by": { + "title": "Marcado como favorito por" + }, + "reblogged_by": { + "title": "Adherido por" + }, "search": { "title": "Buscar", "search_bar": { @@ -498,7 +517,7 @@ "posts": "Mensajes", "hashtags": "Etiquetas", "news": "Novedades", - "community": "Community", + "community": "Comunidad", "for_you": "Para vos" }, "intro": "Estos son los mensajes que están ganando tracción en tu rincón de Mastodon." @@ -596,7 +615,49 @@ "send": "Enviar denuncia", "skip_to_send": "Enviar sin comentarios", "text_placeholder": "Escribí o pegá comentarios adicionales", - "reported": "DENUNCIADA" + "reported": "DENUNCIADA", + "step_one": { + "step_1_of_4": "Paso 1 de 4", + "whats_wrong_with_this_post": "¿Cuál es el problema con este mensaje?", + "whats_wrong_with_this_account": "¿Cuál es el problema con esta cuenta?", + "whats_wrong_with_this_username": "¿Cuál es el problema con %s?", + "select_the_best_match": "Seleccioná la mejor coincidencia", + "i_dont_like_it": "No te gusta", + "it_is_not_something_you_want_to_see": "Es algo que no querés ver", + "its_spam": "Es spam", + "malicious_links_fake_engagement_or_repetetive_replies": "Enlaces maliciosos, interacciones falsas o respuestas repetitivas", + "it_violates_server_rules": "Viola las reglas del servidor", + "you_are_aware_that_it_breaks_specific_rules": "Sos consciente de que infringe normas específicas", + "its_something_else": "Es otra cosa", + "the_issue_does_not_fit_into_other_categories": "El problema no aplica en otras categorías" + }, + "step_two": { + "step_2_of_4": "Paso 2 de 4", + "which_rules_are_being_violated": "¿Qué reglas se están violando?", + "select_all_that_apply": "Seleccioná todo lo que corresponda", + "i_just_don’t_like_it": "Simplemente no te gusta" + }, + "step_three": { + "step_3_of_4": "Paso 3 de 4", + "are_there_any_posts_that_back_up_this_report": "¿Hay algún mensaje que respalde esta denuncia?", + "select_all_that_apply": "Seleccioná todo lo que corresponda" + }, + "step_four": { + "step_4_of_4": "Paso 4 de 4", + "is_there_anything_else_we_should_know": "¿Hay algo más que deberíamos saber?" + }, + "step_final": { + "dont_want_to_see_this": "¿No querés ver esto?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Cuando veas algo que no te gusta en Mastodon, podés quitar a esa cuenta de tu experiencia.", + "unfollow": "Dejar de seguir", + "unfollowed": "Dejaste de seguir a esta cuenta", + "unfollow_user": "Dejar de seguir a %s", + "mute_user": "Silenciar a %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "No verás sus publicaciones ni sus adhesiones en tu línea temporal. El usuario de esta cuenta no sabrá que fue silenciado.", + "block_user": "Bloquear a %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "El usuario de esta cuenta ya no podrá seguirte o leer tus mensajes, pero podrá fijarse si fue bloqueado.", + "while_we_review_this_you_can_take_action_against_user": "Mientras revisamos esto, podés tomar medidas contra %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/es_AR/ios-infoPlist.json b/Localization/StringsConvertor/input/es-AR.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/es_AR/ios-infoPlist.json rename to Localization/StringsConvertor/input/es-AR.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/es_ES/Localizable.stringsdict b/Localization/StringsConvertor/input/es.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/es_ES/Localizable.stringsdict rename to Localization/StringsConvertor/input/es.lproj/Localizable.stringsdict index 8f3e94f6b..05bcff142 100644 --- a/Localization/StringsConvertor/input/es_ES/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/es.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld caracteres + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ publicaciones + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/es_ES/app.json b/Localization/StringsConvertor/input/es.lproj/app.json similarity index 87% rename from Localization/StringsConvertor/input/es_ES/app.json rename to Localization/StringsConvertor/input/es.lproj/app.json index b74b8e5eb..9c11e365d 100644 --- a/Localization/StringsConvertor/input/es_ES/app.json +++ b/Localization/StringsConvertor/input/es.lproj/app.json @@ -240,7 +240,8 @@ "category": "CATEGORÍA" }, "input": { - "placeholder": "Encuentra un servidor o únete al tuyo propio..." + "placeholder": "Encuentra un servidor o únete al tuyo propio...", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Encontrando servidores disponibles...", @@ -250,6 +251,7 @@ }, "register": { "title": "Háblanos de ti.", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Borrar" @@ -320,6 +322,7 @@ "confirm_email": { "title": "Una última cosa.", "subtitle": "Te acabamos de enviar un correo a %s,\npulsa en el enlace para confirmar tu cuenta.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", "button": { "open_email_app": "Abrir Aplicación de Correo Electrónico", "resend": "Reenviar" @@ -342,7 +345,11 @@ "offline": "Sin Conexión", "new_posts": "Ver nuevas publicaciones", "published": "¡Publicado!", - "Publishing": "Publicación en curso..." + "Publishing": "Publicación en curso...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "No se muestran los seguidores de otros servidores." }, "following": { + "title": "following", "footer": "No se muestran los seguidos de otros servidores." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Buscar", "search_bar": { @@ -596,7 +615,49 @@ "send": "Enviar Reporte", "skip_to_send": "Enviar sin comentarios", "text_placeholder": "Escribe o pega comentarios adicionales", - "reported": "REPORTADO" + "reported": "REPORTADO", + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/es_ES/ios-infoPlist.json b/Localization/StringsConvertor/input/es.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/es_ES/ios-infoPlist.json rename to Localization/StringsConvertor/input/es.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/eu_ES/Localizable.stringsdict b/Localization/StringsConvertor/input/eu.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/eu_ES/Localizable.stringsdict rename to Localization/StringsConvertor/input/eu.lproj/Localizable.stringsdict index 871fb10bc..0159a7da9 100644 --- a/Localization/StringsConvertor/input/eu_ES/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/eu.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld karaktere + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ bidalketa + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/eu_ES/app.json b/Localization/StringsConvertor/input/eu.lproj/app.json similarity index 87% rename from Localization/StringsConvertor/input/eu_ES/app.json rename to Localization/StringsConvertor/input/eu.lproj/app.json index 6905c37a9..96978f3d4 100644 --- a/Localization/StringsConvertor/input/eu_ES/app.json +++ b/Localization/StringsConvertor/input/eu.lproj/app.json @@ -240,7 +240,8 @@ "category": "KATEGORIA" }, "input": { - "placeholder": "Bilatu zerbitzari bat edo sortu zurea..." + "placeholder": "Bilatu zerbitzari bat edo sortu zurea...", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Erabilgarri dauden zerbitzariak bilatzen...", @@ -250,6 +251,7 @@ }, "register": { "title": "Hitz egin iezaguzu zuri buruz.", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Ezabatu" @@ -319,7 +321,8 @@ }, "confirm_email": { "title": "Eta azkenik...", - "subtitle": "Eposta bat bidali dizugu %s helbidera,\nsakatu kontua berresteko esteka.", + "subtitle": "Sakatu epostaz bidali dizugun loturan zure kontua egiaztatzeko.", + "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": "Ireki eposta aplikazioa", "resend": "Berbidali" @@ -342,7 +345,11 @@ "offline": "Konexio gabe", "new_posts": "Ikusi bidal. berriak", "published": "Argitaratua!", - "Publishing": "Bidalketa argitaratzen..." + "Publishing": "Bidalketa argitaratzen...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Beste zerbitzarietako jarraitzaileak ez dira bistaratzen." }, "following": { + "title": "following", "footer": "Beste zerbitzarietan jarraitutakoak ez dira bistaratzen." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Bilatu", "search_bar": { @@ -596,7 +615,49 @@ "send": "Bidali salaketa", "skip_to_send": "Bidali iruzkinik gabe", "text_placeholder": "Idatzi edo itsatsi iruzkin gehigarriak", - "reported": "SALATUA" + "reported": "SALATUA", + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/eu_ES/ios-infoPlist.json b/Localization/StringsConvertor/input/eu.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/eu_ES/ios-infoPlist.json rename to Localization/StringsConvertor/input/eu.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/sv_FI/Localizable.stringsdict b/Localization/StringsConvertor/input/fi.lproj/Localizable.stringsdict similarity index 89% rename from Localization/StringsConvertor/input/sv_FI/Localizable.stringsdict rename to Localization/StringsConvertor/input/fi.lproj/Localizable.stringsdict index 091c8555e..8048edf2d 100644 --- a/Localization/StringsConvertor/input/sv_FI/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/fi.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld merkkiä + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ julkaisut + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey @@ -125,9 +168,9 @@ NSStringFormatValueTypeKey ld one - 1 svar + 1 reply other - %ld svar + %ld replies plural.count.vote diff --git a/Localization/StringsConvertor/input/sv_FI/app.json b/Localization/StringsConvertor/input/fi.lproj/app.json similarity index 72% rename from Localization/StringsConvertor/input/sv_FI/app.json rename to Localization/StringsConvertor/input/fi.lproj/app.json index 5712e4c06..7dc8f17c4 100644 --- a/Localization/StringsConvertor/input/sv_FI/app.json +++ b/Localization/StringsConvertor/input/fi.lproj/app.json @@ -12,18 +12,18 @@ "title": "Palvelinvirhe" }, "vote_failure": { - "title": "Röstning misslyckades", + "title": "Vote Failure", "poll_ended": "Kysely on päättynyt" }, "discard_post_content": { "title": "Hylkää luonnos", - "message": "Bekräfta för att slänga inläggsutkast." + "message": "Confirm to discard composed post content." }, "publish_post_failure": { "title": "Julkaiseminen epäonnistui", "message": "Julkaisun julkaiseminen epäonnistui.\nTarkista internet-yhteytesi.", "attachments_message": { - "video_attach_with_photo": "Det går inte att bifoga en video till en status som redan innehåller bilder.", + "video_attach_with_photo": "Cannot attach a video to a post that already contains images.", "more_than_one_video": "Ei voi liittä yhtä videota enempää." } }, @@ -37,16 +37,16 @@ "confirm": "Kirjaudu ulos" }, "block_domain": { - "title": "Är du verkligen, verkligen säker på att du vill blockera hela %s? I de flesta fall är några riktade blockeringar eller nedtystade konton tillräckligt och att föredra. Du kommer inte se innehåll från den domänen och dina följare från den domänen kommer att tas bort.", + "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": "Estä verkkotunnus" }, "save_photo_failure": { "title": "Kuvan tallentaminen epäonnistui", - "message": "Aktivera åtkomst till Bilder för att spara bilden." + "message": "Please enable the photo library access permission to save the photo." }, "delete_post": { "title": "Haluatko varmasti poistaa tämän julkaisun?", - "message": "Är du säker på att du vill radera detta inlägg?" + "message": "Are you sure you want to delete this post?" }, "clean_cache": { "title": "Puhdista välimuisti", @@ -82,9 +82,9 @@ "share_user": "Jaa %s", "share_post": "Jaa julkaisu", "open_in_safari": "Avaa Safarissa", - "open_in_browser": "Öppna i webbläsare", + "open_in_browser": "Open in Browser", "find_people": "Löydä tilejä seurattavaksi", - "manually_search": "Sök manuellt istället", + "manually_search": "Manually search instead", "skip": "Ohita", "reply": "Vastaa", "report_user": "Ilmianna %s", @@ -113,13 +113,13 @@ "open_author_profile": "Avaa tekijän profiili", "open_reblogger_profile": "Avaa edelleen jakajan profiili", "reply_status": "Vastaa julkaisuun", - "toggle_reblog": "Växla ompostning på inlägg", - "toggle_favorite": "Växla favorit på inlägg", + "toggle_reblog": "Toggle Reblog on Post", + "toggle_favorite": "Toggle Favorite on Post", "toggle_content_warning": "Vaihda sisältövaroitus", - "preview_image": "Förhandsgranska bild" + "preview_image": "Preview Image" }, "segmented_control": { - "previous_section": "Föregående avsnitt", + "previous_section": "Previous Section", "next_section": "Seuraava lohko" } }, @@ -129,39 +129,39 @@ "show_post": "Näytä julkaisu", "show_user_profile": "Näytä tili", "content_warning": "Sisältövaroitus", - "sensitive_content": "Känsligt innehåll", + "sensitive_content": "Sensitive Content", "media_content_warning": "Napauta mistä tahansa paljastaaksesi", - "tap_to_reveal": "Tryck för att visa", + "tap_to_reveal": "Tap to reveal", "poll": { - "vote": "Rösta", + "vote": "Vote", "closed": "Suljettu" }, "actions": { "reply": "Vastaa", "reblog": "Jaa edelleen", "unreblog": "Peru edelleen jako", - "favorite": "Favorit", - "unfavorite": "Ta bort favorit", + "favorite": "Favorite", + "unfavorite": "Unfavorite", "menu": "Valikko", - "hide": "Dölj", - "show_image": "Visa bild", - "show_gif": "Visa GIF", - "show_video_player": "Visa videospelare", - "tap_then_hold_to_show_menu": "Tryck och håll ned för att visa menyn" + "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": "Nämn", + "mention": "Mention", "link": "Linkki", "hashtag": "Hashtagi", "email": "Sähköposti", "emoji": "Emoji" }, "visibility": { - "unlisted": "Alla kan se detta inlägg men det visas inte i den offentliga tidslinjen.", - "private": "Endast deras följare kan se detta inlägg.", - "private_from_me": "Bara mina följare kan se det här inlägget.", - "direct": "Endast nämnda användare kan se detta inlägg." + "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": { @@ -173,7 +173,7 @@ "block_user": "Estä %s", "block_domain": "Estä %s", "unblock": "Poista esto", - "unblock_user": "Avblockera %s", + "unblock_user": "Unblock %s", "blocked": "Estetty", "mute": "Mykistä", "mute_user": "Mykistä %s", @@ -207,13 +207,13 @@ "scene": { "welcome": { "slogan": "Sosiaalinen verkostoituminen\ntakaisin käsissäsi.", - "get_started": "Kom igång", - "log_in": "Logga in" + "get_started": "Get Started", + "log_in": "Log In" }, "server_picker": { "title": "Valitse palvelin,\nmikä tahansa palvelin.", - "subtitle": "Välj en gemenskap baserad på dina intressen, region eller ett allmänt syfte.", - "subtitle_extend": "Välj en gemenskap baserad på dina intressen, region eller ett allmänt syfte. Varje gemenskap drivs av en helt oberoende organisation eller individ.", + "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": "Kaikki", @@ -240,7 +240,8 @@ "category": "KATEGORIA" }, "input": { - "placeholder": "Etsi palvelin tai liity omaan..." + "placeholder": "Etsi palvelin tai liity omaan...", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Etsistään saatavilla olevia palvelimia...", @@ -250,6 +251,7 @@ }, "register": { "title": "Kerro meille sinusta.", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Poista" @@ -266,11 +268,11 @@ }, "password": { "placeholder": "salasana", - "require": "Ditt lösenord behöver minst:", - "character_limit": "8 tecken", + "require": "Your password needs at least:", + "character_limit": "8 characters", "accessibility": { - "checked": "markerad", - "unchecked": "avmarkerad" + "checked": "checked", + "unchecked": "unchecked" }, "hint": "Salasanassasi on oltava vähintään kahdeksan merkkiä" }, @@ -284,14 +286,14 @@ "email": "Sähköposti", "password": "Salasana", "agreement": "Hyväksy", - "locale": "Språk", + "locale": "Locale", "reason": "Syy" }, "reason": { "blocked": "%s sisältää estetyn sähköpostipalveluntarjoajan", "unreachable": "%s ei näytä olevan olemassa", "taken": "%s on jo käytössä", - "reserved": "%s är ett reserverat nyckelord", + "reserved": "%s is a reserved keyword", "accepted": "%s täytyy hyväksyä", "blank": "%s vaaditaan", "invalid": "%s on virheellinen", @@ -320,9 +322,10 @@ "confirm_email": { "title": "Viimeinen asia.", "subtitle": "Lähetimme juuri sähköpostin osoitteeseen %s, napauta siinä olevaa linkkiä vahvistaaksesi tilisi.", + "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": "Avaa sähköpostisovellus", - "resend": "Skicka igen" + "resend": "Resend" }, "dont_receive_email": { "title": "Tarkista sähköpostisi", @@ -342,7 +345,11 @@ "offline": "Yhteydetön", "new_posts": "Uusia julkaisuja", "published": "Julkaistu!", - "Publishing": "Julkaistaan julkaisua..." + "Publishing": "Julkaistaan julkaisua...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -365,7 +372,7 @@ "attachment": { "photo": "kuva", "video": "video", - "attachment_broken": "Denna %s är trasig och kan inte\nladdas upp till Mastodon.", + "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", "description_photo": "Kuvaile kuva näkövammaisille...", "description_video": "Kuvaile video näkövammaisille..." }, @@ -389,7 +396,7 @@ "direct": "Vain mainitsemani tilit" }, "auto_complete": { - "space_to_add": "Mellanslag att lägga till" + "space_to_add": "Space to add" }, "accessibility": { "append_attachment": "Lisää liite", @@ -425,41 +432,53 @@ "segmented_control": { "posts": "Julkaisut", "replies": "Vastaukset", - "posts_and_replies": "Inlägg och svar", + "posts_and_replies": "Posts and Replies", "media": "Media", - "about": "Om" + "about": "About" }, "relationship_action_alert": { "confirm_mute_user": { - "title": "Tysta konto", - "message": "Bekräfta för att tysta %s" + "title": "Mute Account", + "message": "Confirm to mute %s" }, "confirm_unmute_user": { "title": "Poista tilin mykistys", "message": "Vahvista, että haluat poistaa mykistyksen tililtä %s" }, "confirm_block_user": { - "title": "Blockera konto", - "message": "Bekräfta för att blockera %s" + "title": "Block Account", + "message": "Confirm to block %s" }, "confirm_unblock_user": { - "title": "Avblockera konto", - "message": "Bekräfta för att avblockera %s" + "title": "Unblock Account", + "message": "Confirm to unblock %s" } }, "accessibility": { - "show_avatar_image": "Visa profilbild", - "edit_avatar_image": "Redigera profilbild", - "show_banner_image": "Visa banner", - "double_tap_to_open_the_list": "Dubbeltryck för att öppna listan" + "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": "Seuraajia muilta palvelimilta ei näytetä." }, "following": { + "title": "following", "footer": "Seurauksia muilta palvelimilta ei näytetä." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Haku", "search_bar": { @@ -495,13 +514,13 @@ }, "discovery": { "tabs": { - "posts": "Inlägg", - "hashtags": "Hashtaggar", - "news": "Nyheter", + "posts": "Posts", + "hashtags": "Hashtags", + "news": "News", "community": "Community", - "for_you": "För dig" + "for_you": "For You" }, - "intro": "Detta är de inlägg som engagerar i ditt hörn av Mastodon." + "intro": "These are the posts gaining traction in your corner of Mastodon." }, "favorite": { "title": "Omat suosikit" @@ -512,12 +531,12 @@ "Mentions": "Maininnat" }, "notification_description": { - "followed_you": "följde dig", - "favorited_your_post": "favoriserade ditt inlägg", - "reblogged_your_post": "ompostade 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" + "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": "Näytä kaikki", @@ -538,15 +557,15 @@ "dark": "Tumma" }, "look_and_feel": { - "title": "Utseende och känsla", - "use_system": "Följ systeminställningarna", - "really_dark": "Verkligen mörk", - "sorta_dark": "Ganska mörk", - "light": "Ljust" + "title": "Look and Feel", + "use_system": "Use System", + "really_dark": "Really Dark", + "sorta_dark": "Sorta Dark", + "light": "Light" }, "notifications": { "title": "Ilmoitukset", - "favorites": "Favoriserar mitt inlägg", + "favorites": "Favorites my post", "follows": "Seuraa minua", "boosts": "Omien julkaisujen edelleen jaot", "mentions": "Mainitsee minut", @@ -564,7 +583,7 @@ "disable_avatar_animation": "Poista käytöstä animoidut avatarit", "disable_emoji_animation": "Poista käytöstä animoidut emojit", "using_default_browser": "Käytä oletusselainta linkkien avaamiseen", - "open_links_in_mastodon": "Öppna länkar i Mastodon" + "open_links_in_mastodon": "Open links in Mastodon" }, "boring_zone": { "title": "Tylsä alue", @@ -586,17 +605,59 @@ } }, "report": { - "title_report": "Rapportera", + "title_report": "Report", "title": "Ilmianna %s", "step1": "Vaihe 1/2", "step2": "Vaihe 2/2", "content1": "Onko julkaisuja, joita haluaisit lisätä ilmiantoon?", "content2": "Onko valvojien syytä tietää tästä ilmiannosta?", - "report_sent_title": "Tack för din rapport, vi ska titta på det.", + "report_sent_title": "Thanks for reporting, we’ll look into this.", "send": "Lähetä ilmianto", "skip_to_send": "Lähetä ilman kommentteja", "text_placeholder": "Kirjoita tai liitä lisäkommentteja", - "reported": "RAPPORTERAD" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/sv_FI/ios-infoPlist.json b/Localization/StringsConvertor/input/fi.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/sv_FI/ios-infoPlist.json rename to Localization/StringsConvertor/input/fi.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/fr_FR/Localizable.stringsdict b/Localization/StringsConvertor/input/fr.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/fr_FR/Localizable.stringsdict rename to Localization/StringsConvertor/input/fr.lproj/Localizable.stringsdict index 5c2b14978..d9d860a47 100644 --- a/Localization/StringsConvertor/input/fr_FR/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/fr.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld caractères + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Suivi·e par %1$@ et un·e autre en commun + other + Suivi·e par %1$@ et %ld autres en commun + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ publications + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 média + other + %ld médias + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/fr_FR/app.json b/Localization/StringsConvertor/input/fr.lproj/app.json similarity index 85% rename from Localization/StringsConvertor/input/fr_FR/app.json rename to Localization/StringsConvertor/input/fr.lproj/app.json index a3aa9802a..97a8566e9 100644 --- a/Localization/StringsConvertor/input/fr_FR/app.json +++ b/Localization/StringsConvertor/input/fr.lproj/app.json @@ -129,7 +129,7 @@ "show_post": "Montrer la publication", "show_user_profile": "Montrer le profil de l’utilisateur·rice", "content_warning": "Avertissement de contenu", - "sensitive_content": "Sensitive Content", + "sensitive_content": "Contenu sensible", "media_content_warning": "Tapotez n’importe où pour révéler la publication", "tap_to_reveal": "Appuyer pour afficher", "poll": { @@ -147,7 +147,7 @@ "show_image": "Afficher l’image", "show_gif": "Afficher le GIF", "show_video_player": "Afficher le lecteur vidéo", - "tap_then_hold_to_show_menu": "Tap then hold to show menu" + "tap_then_hold_to_show_menu": "Appuyez et maintenez pour afficher le menu" }, "tag": { "url": "URL", @@ -240,7 +240,8 @@ "category": "CATÉGORIE" }, "input": { - "placeholder": "Trouvez un serveur ou rejoignez le vôtre..." + "placeholder": "Trouvez un serveur ou rejoignez le vôtre...", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Recherche des serveurs disponibles...", @@ -250,6 +251,7 @@ }, "register": { "title": "Parlez-nous de vous.", + "lets_get_you_set_up_on_domain": "Mettons les choses en place pour %s", "input": { "avatar": { "delete": "Supprimer" @@ -319,7 +321,8 @@ }, "confirm_email": { "title": "Une dernière chose.", - "subtitle": "Nous venons d’envoyer un courriel à %s,\ntapotez le lien pour confirmer votre compte.", + "subtitle": "Appuyez sur le lien que nous vous avons envoyé par courriel pour vérifier votre compte.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Appuyez sur le lien que nous vous avons envoyé par courriel pour vérifier votre compte", "button": { "open_email_app": "Ouvrir l’application de courriel", "resend": "Renvoyer" @@ -342,7 +345,11 @@ "offline": "Hors ligne", "new_posts": "Voir les nouvelles publications", "published": "Publié!", - "Publishing": "Publication en cours ..." + "Publishing": "Publication en cours ...", + "accessibility": { + "logo_label": "Bouton logo", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "abonné·e", "footer": "Les abonné·e·s issus des autres serveurs ne sont pas affiché·e·s." }, "following": { + "title": "following", "footer": "Les abonnés issus des autres serveurs ne sont pas affichés." }, + "familiarFollowers": { + "title": "Abonné·e·s que vous connaissez", + "followed_by_names": "Suivi·e par %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Rechercher", "search_bar": { @@ -498,10 +517,10 @@ "posts": "Messages", "hashtags": "Hashtags", "news": "Actualité", - "community": "Community", + "community": "Communauté", "for_you": "Pour vous" }, - "intro": "These are the posts gaining traction in your corner of Mastodon." + "intro": "Ce sont les messages qui gagnent en popularité sur votre serveur Mastodon." }, "favorite": { "title": "Vos favoris" @@ -596,7 +615,49 @@ "send": "Envoyer le rapport", "skip_to_send": "Envoyer sans commentaire", "text_placeholder": "Tapez ou collez des informations supplémentaires", - "reported": "SIGNALÉ" + "reported": "SIGNALÉ", + "step_one": { + "step_1_of_4": "Étape 1 sur 4", + "whats_wrong_with_this_post": "Qu’est-ce qui ne va pas avec ce message ?", + "whats_wrong_with_this_account": "Qu’est-ce qui ne va pas avec ce compte ?", + "whats_wrong_with_this_username": "Qu’est-ce qui ne va pas avec %s ?", + "select_the_best_match": "Select the best match", + "i_dont_like_it": "Je n’aime pas", + "it_is_not_something_you_want_to_see": "C’est quelque chose que vous ne souhaitez pas voir", + "its_spam": "C’est du spam", + "malicious_links_fake_engagement_or_repetetive_replies": "Liens malveillants, engagement mensonger ou réponses répétitives", + "it_violates_server_rules": "Enfreint les règles du serveur", + "you_are_aware_that_it_breaks_specific_rules": "Vous savez qu’il enfreint des règles spécifiques", + "its_something_else": "Pour une autre raison", + "the_issue_does_not_fit_into_other_categories": "Le problème ne correspond à aucune des catégories" + }, + "step_two": { + "step_2_of_4": "Étape 2 sur 4", + "which_rules_are_being_violated": "Quelles règles sont enfreintes ?", + "select_all_that_apply": "Sélectionnez toutes les réponses appropriées", + "i_just_don’t_like_it": "Ça ne me plaît tout simplement pas" + }, + "step_three": { + "step_3_of_4": "Étape 3 sur 4", + "are_there_any_posts_that_back_up_this_report": "Existe-t-il des messages pour étayer ce rapport ?", + "select_all_that_apply": "Sélectionnez toutes les réponses qui s’appliquent" + }, + "step_four": { + "step_4_of_4": "Étape 4 sur 4", + "is_there_anything_else_we_should_know": "Y a-t-il autre chose que nous devrions savoir ?" + }, + "step_final": { + "dont_want_to_see_this": "Vous ne voulez pas voir cela ?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Quand vous voyez quelque chose que vous n’aimez pas sur Mastodon, vous pouvez retirer la personne de votre expérience.", + "unfollow": "Se désabonner", + "unfollowed": "Unfollowed", + "unfollow_user": "Ne plus suivre %s", + "mute_user": "Masquer %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Vous ne verrez plus leurs messages ou leurs partages dans votre flux personnel. Iels ne sauront pas qu’iels ont été mis en sourdine.", + "block_user": "Bloquer %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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/fr_FR/ios-infoPlist.json b/Localization/StringsConvertor/input/fr.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/fr_FR/ios-infoPlist.json rename to Localization/StringsConvertor/input/fr.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/gd_GB/Localizable.stringsdict b/Localization/StringsConvertor/input/gd.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/gd_GB/Localizable.stringsdict rename to Localization/StringsConvertor/input/gd.lproj/Localizable.stringsdict index b149323eb..f041677fa 100644 --- a/Localization/StringsConvertor/input/gd_GB/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/gd.lproj/Localizable.stringsdict @@ -62,6 +62,41 @@ %ld caractar + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + two + + few + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + two + Followed by %1$@, and %ld mutuals + few + Followed by %1$@, and %ld mutuals + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -82,6 +117,26 @@ post + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + two + %ld media + few + %ld media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/gd_GB/app.json b/Localization/StringsConvertor/input/gd.lproj/app.json similarity index 87% rename from Localization/StringsConvertor/input/gd_GB/app.json rename to Localization/StringsConvertor/input/gd.lproj/app.json index fc9270c58..c3364c6e9 100644 --- a/Localization/StringsConvertor/input/gd_GB/app.json +++ b/Localization/StringsConvertor/input/gd.lproj/app.json @@ -240,7 +240,8 @@ "category": "ROINN-SEÒRSA" }, "input": { - "placeholder": "Lorg frithealaiche no gabh pàirt san fhear agad fhèin…" + "placeholder": "Lorg frithealaiche no gabh pàirt san fhear agad fhèin…", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "A’ lorg nam frithealaichean ri am faighinn…", @@ -250,6 +251,7 @@ }, "register": { "title": "Innis dhuinn mu do dhèidhinn.", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Sguab às" @@ -320,6 +322,7 @@ "confirm_email": { "title": "Aon rud eile.", "subtitle": "Tha sinn air post-d a chur gu %s,\nthoir gnogag air a’ chunntas a dhearbhadh a’ chunntais agad.", + "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": "Fosgail aplacaid a’ phuist-d", "resend": "Ath-chuir" @@ -342,7 +345,11 @@ "offline": "Far loidhne", "new_posts": "Seall na postaichean ùra", "published": "Chaidh fhoillseachadh!", - "Publishing": "A’ foillseachadh a’ phuist…" + "Publishing": "A’ foillseachadh a’ phuist…", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Cha dèid luchd-leantainn o fhrithealaichean eile a shealltainn." }, "following": { + "title": "following", "footer": "Cha dèid cò air a leanas tu air frithealaichean eile a shealltainn." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Lorg", "search_bar": { @@ -498,7 +517,7 @@ "posts": "Postaichean", "hashtags": "Tagaichean hais", "news": "Naidheachdan", - "community": "Community", + "community": "Coimhearsnachd", "for_you": "Dhut-sa" }, "intro": "Seo na postaichean fèillmhor ’nad cheàrnaidh de Mhastodon." @@ -513,7 +532,7 @@ }, "notification_description": { "followed_you": "– ’s iad ’gad leantainn a-nis", - "favorited_your_post": "– ’s iad air am post agad a chur ris na h-annsachdan aca", + "favorited_your_post": "– is annsa leotha am post agad", "reblogged_your_post": "– ’s iad air am post agad a bhrosnachadh", "mentioned_you": "– ’s iad air iomradh a thoirt ort", "request_to_follow_you": "iarrtas leantainn ort", @@ -596,7 +615,49 @@ "send": "Cuir an gearan", "skip_to_send": "Cuir gun bheachd ris", "text_placeholder": "Sgrìobh no cuir ann beachdan a bharrachd", - "reported": "CHAIDH GEARAN A DHÈANAMH" + "reported": "CHAIDH GEARAN A DHÈANAMH", + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/gd_GB/ios-infoPlist.json b/Localization/StringsConvertor/input/gd.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/gd_GB/ios-infoPlist.json rename to Localization/StringsConvertor/input/gd.lproj/ios-infoPlist.json diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/es-419.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/gl.lproj/Localizable.stringsdict similarity index 78% rename from MastodonSDK/Sources/MastodonLocalization/Resources/es-419.lproj/Localizable.stringsdict rename to Localization/StringsConvertor/input/gl.lproj/Localizable.stringsdict index 9d1fdadb6..ff9d87c18 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/es-419.lproj/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/gl.lproj/Localizable.stringsdict @@ -13,15 +13,15 @@ NSStringFormatValueTypeKey ld one - 1 notificación sin leer + 1 notificación non lida other - %ld notificaciones sin leer + %ld notificacións non lidas a11y.plural.count.input_limit_exceeds NSStringLocalizedFormatKey - El límite de entrada excede %#@character_count@ caracteres + O límite supera %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -37,7 +37,7 @@ a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - El límite de entrada permite %#@character_count@ caracteres + O límite de entrada mantense en %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -50,6 +50,33 @@ %ld caracteres + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Seguida por %1$@, e outro común + other + Seguida por %1$@, e %ld comúns + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -61,9 +88,25 @@ NSStringFormatValueTypeKey ld one - mensaje + publicación other - mensajes + publicacións + + + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 mutlimedia + other + %ld multimedias plural.count.post @@ -77,9 +120,9 @@ NSStringFormatValueTypeKey ld one - 1 mensaje + 1 publicación other - %ld mensajes + %ld publicacións plural.count.favorite @@ -109,9 +152,9 @@ NSStringFormatValueTypeKey ld one - 1 adhesión + 1 promoción other - %ld adhesiones + %ld promocións plural.count.reply @@ -125,9 +168,9 @@ NSStringFormatValueTypeKey ld one - 1 respuesta + 1 resposta other - %ld respuestas + %ld respostas plural.count.vote @@ -173,9 +216,9 @@ NSStringFormatValueTypeKey ld one - 1 cuenta hablando + 1 persoa comentando other - %ld cuentas hablando + %ld persoas comentando plural.count.following @@ -189,9 +232,9 @@ NSStringFormatValueTypeKey ld one - siguiendo a 1 + 1 seguimento other - siguiendo a %ld + %ld seguimentos plural.count.follower @@ -205,9 +248,9 @@ NSStringFormatValueTypeKey ld one - 1 seguidor + 1 seguidora other - %ld seguidores + %ld seguidoras date.year.left @@ -221,9 +264,9 @@ NSStringFormatValueTypeKey ld one - 1 año restante + Queda 1 ano other - %ld años restantes + Quedan %ld anos date.month.left @@ -237,9 +280,9 @@ NSStringFormatValueTypeKey ld one - 1 mes restante + Queda 1 mes other - %ld meses restantes + Quedan %ld meses date.day.left @@ -253,9 +296,9 @@ NSStringFormatValueTypeKey ld one - 1 día restante + Queda 1 día other - %ld días restantes + Quedan %ld días date.hour.left @@ -269,9 +312,9 @@ NSStringFormatValueTypeKey ld one - 1 hora restante + Queda 1 hora other - %ld horas restantes + Quedan %ld horas date.minute.left @@ -285,9 +328,9 @@ NSStringFormatValueTypeKey ld one - 1 minuto restante + Queda 1 minuto other - %ld minutos restantes + Quedan %ld minutos date.second.left @@ -301,9 +344,9 @@ NSStringFormatValueTypeKey ld one - 1 segundo restante + Queda 1 segundo other - %ld segundos restantes + Quedan %ld segundos date.year.ago.abbr @@ -317,9 +360,9 @@ NSStringFormatValueTypeKey ld one - hace 1 año + hai 1 ano other - hace %ld años + hai %ld anos date.month.ago.abbr @@ -333,9 +376,9 @@ NSStringFormatValueTypeKey ld one - hace 1 mes + hai 1 mes other - hace %ld meses + hai %ld meses date.day.ago.abbr @@ -349,9 +392,9 @@ NSStringFormatValueTypeKey ld one - hace 1 día + hai 1 día other - hace %ld días + hai %ld días date.hour.ago.abbr @@ -365,9 +408,9 @@ NSStringFormatValueTypeKey ld one - hace 1 hora + fai 1 hora other - hace %ld horas + fai %ld horas date.minute.ago.abbr @@ -381,9 +424,9 @@ NSStringFormatValueTypeKey ld one - hace 1 minuto + fai 1 minuto other - hace %ld minutos + fai %ld minutos date.second.ago.abbr @@ -397,9 +440,9 @@ NSStringFormatValueTypeKey ld one - hace 1 segundo + fai 1 seg. other - hace %ld segundos + fai %ld seg. diff --git a/Localization/StringsConvertor/input/gl_ES/app.json b/Localization/StringsConvertor/input/gl.lproj/app.json similarity index 65% rename from Localization/StringsConvertor/input/gl_ES/app.json rename to Localization/StringsConvertor/input/gl.lproj/app.json index 0c5cbc038..af5ee5d50 100644 --- a/Localization/StringsConvertor/input/gl_ES/app.json +++ b/Localization/StringsConvertor/input/gl.lproj/app.json @@ -195,19 +195,19 @@ "header": { "no_status_found": "Non se atopa a publicación", "blocking_warning": "Non podes ver o perfil da usuaria\nata que a desbloquees.\nAsí ven outras o teu perfil.", - "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", - "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", - "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", - "suspended_warning": "This user has been suspended.", - "user_suspended_warning": "%s’s account has been suspended." + "user_blocking_warning": "Non podes ver o perfil de %s\nata que o desbloquees.\nAsí se ve o teu perfil.", + "blocked_warning": "Non podes ver o perfil desta usuaria\nata que te desbloquee.", + "user_blocked_warning": "Non podes ver o perfil de %s\nata que te desbloquee.", + "suspended_warning": "Esta usuaria foi suspendida.", + "user_suspended_warning": "A conta de %s foi suspendida." } } } }, "scene": { "welcome": { - "slogan": "Social networking\nback in your hands.", - "get_started": "Comezar", + "slogan": "Comunicación social\nde volta ás túas mans.", + "get_started": "Crear conta", "log_in": "Acceder" }, "server_picker": { @@ -240,7 +240,8 @@ "category": "CATEGORÍA" }, "input": { - "placeholder": "Buscar comunidades" + "placeholder": "Buscar comunidades", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Buscando servidores dispoñibles...", @@ -250,6 +251,7 @@ }, "register": { "title": "Imos crear a túa conta en %s", + "lets_get_you_set_up_on_domain": "Imos crear a túa conta en %s", "input": { "avatar": { "delete": "Eliminar" @@ -301,79 +303,84 @@ }, "special": { "username_invalid": "O nome de usuaria só pode ter caracteres alfanuméricos e trazos baixos", - "username_too_long": "Username is too long (can’t 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)" + "username_too_long": "O nome de usuaria é demasiado longo (maior de 30 caracteres)", + "email_invalid": "Este non é un enderezo válido de email", + "password_too_short": "O contrasinal é demasiado curto (debe ter 8 caracteres como mínimo)" } } }, "server_rules": { - "title": "Some ground rules.", - "subtitle": "These are set and enforced by the %s moderators.", - "prompt": "By continuing, you’re subject to the terms of service and privacy policy for %s.", - "terms_of_service": "terms of service", - "privacy_policy": "privacy policy", + "title": "Algunhas regras básicas.", + "subtitle": "Son establecidas e aplicadas pola moderación de %s.", + "prompt": "Ao continuar, acatas os termos do servizo e a política de privacidade para %s.", + "terms_of_service": "termos do servizo", + "privacy_policy": "polícica de privacidade", "button": { - "confirm": "I Agree" + "confirm": "Acepto" } }, "confirm_email": { - "title": "One last thing.", - "subtitle": "Tap the link we emailed to you to verify your account.", + "title": "O último detalle.", + "subtitle": "Preme na ligazón que che enviamos ao email para verificar a conta.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Preme na ligazón que che enviamos ao email para verificar a conta", "button": { - "open_email_app": "Open Email App", - "resend": "Resend" + "open_email_app": "Abrir app de email", + "resend": "Reenviar" }, "dont_receive_email": { - "title": "Check your email", - "description": "Check if your email address is correct as well as your junk folder if you haven’t.", - "resend_email": "Resend Email" + "title": "Revisa o teu correo", + "description": "Comproba que o enderezo de email é correcto e que non vaia directo ao cartafol de spam.", + "resend_email": "Volver enviar o correo" }, "open_email_app": { - "title": "Check your inbox.", - "description": "We just sent you an email. Check your junk folder if you haven’t.", - "mail": "Mail", - "open_email_client": "Open Email Client" + "title": "Mira na caixa de correo.", + "description": "Enviámosche un email. Se non aparece, mira no cartafol do lixo.", + "mail": "Correo", + "open_email_client": "Abrir cliente de email" } }, "home_timeline": { - "title": "Home", + "title": "Inicio", "navigation_bar_state": { - "offline": "Offline", - "new_posts": "See new posts", - "published": "Published!", - "Publishing": "Publishing post..." + "offline": "Sen conexión", + "new_posts": "Novas publicacións", + "published": "Publicado!", + "Publishing": "Publicando...", + "accessibility": { + "logo_label": "Botón do logo", + "logo_hint": "Toca para ir arriba e toca outra vez para volver ao mesmo lugar" + } } }, "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll see their posts in your home feed." + "title": "Atopar persoas para seguir", + "follow_explain": "Cando sigas a alguén verás as súas publicacións na cronoloxía de inicio." }, "compose": { "title": { - "new_post": "New Post", - "new_reply": "New Reply" + "new_post": "Nova publicación", + "new_reply": "Nova resposta" }, "media_selection": { - "camera": "Take Photo", - "photo_library": "Photo Library", - "browse": "Browse" + "camera": "Facer foto", + "photo_library": "Biblioteca de fotos", + "browse": "Explorar" }, - "content_input_placeholder": "Type or paste what’s on your mind", - "compose_action": "Publish", - "replying_to_user": "replying to %s", + "content_input_placeholder": "Escribe o que che apeteza", + "compose_action": "Publicar", + "replying_to_user": "en resposta a %s", "attachment": { - "photo": "photo", - "video": "video", - "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", - "description_photo": "Describe the photo for the visually-impaired...", - "description_video": "Describe the video for the visually-impaired..." + "photo": "foto", + "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..." }, "poll": { - "duration_time": "Duration: %s", - "thirty_minutes": "30 minutes", - "one_hour": "1 Hour", - "six_hours": "6 Hours", + "duration_time": "Duración: %s", + "thirty_minutes": "30 minutos", + "one_hour": "1 Hora", + "six_hours": "6 Horas", "one_day": "1 Día", "three_days": "3 Días", "seven_days": "7 Días", @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Non se mostran seguidoras desde outros servidores." }, "following": { + "title": "following", "footer": "Non se mostran os seguimentos desde outros servidores." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Procurar", "search_bar": { @@ -499,90 +518,90 @@ "hashtags": "Cancelos", "news": "Novas", "community": "Comunidade", - "for_you": "For You" + "for_you": "Para ti" }, - "intro": "These are the posts gaining traction in your corner of Mastodon." + "intro": "Estas son as publicacións en voga no teu recuncho de Mastodon." }, "favorite": { - "title": "Your Favorites" + "title": "Publicacións Favoritas" }, "notification": { "title": { - "Everything": "Everything", - "Mentions": "Mentions" + "Everything": "Todo", + "Mentions": "Mencións" }, "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": "séguete", + "favorited_your_post": "marcou a túa publicación como favorita", + "reblogged_your_post": "compartiu a túa publicación", + "mentioned_you": "mencionoute", + "request_to_follow_you": "solicitou seguirte", + "poll_has_ended": "a enquisa rematou" }, "keyobard": { - "show_everything": "Show Everything", - "show_mentions": "Show Mentions" + "show_everything": "Mostrar Todo", + "show_mentions": "Mostrar mencións" } }, "thread": { - "back_title": "Post", - "title": "Post from %s" + "back_title": "Publicación", + "title": "Publicación de %s" }, "settings": { - "title": "Settings", + "title": "Axustes", "section": { "appearance": { - "title": "Appearance", - "automatic": "Automatic", - "light": "Always Light", - "dark": "Always Dark" + "title": "Aparencia", + "automatic": "Automático", + "light": "Sempre claro", + "dark": "Sempre escuro" }, "look_and_feel": { - "title": "Look and Feel", - "use_system": "Use System", - "really_dark": "Really Dark", - "sorta_dark": "Sorta Dark", - "light": "Light" + "title": "Aparencia", + "use_system": "Seguir o sistema", + "really_dark": "Realmente escuro", + "sorta_dark": "Algo escuro", + "light": "Claro" }, "notifications": { - "title": "Notifications", - "favorites": "Favorites my post", - "follows": "Follows me", - "boosts": "Reblogs my post", - "mentions": "Mentions me", + "title": "Notificacións", + "favorites": "Favorece a miña publicación", + "follows": "Me segue", + "boosts": "Promove a miña publicación", + "mentions": "Me menciona", "trigger": { - "anyone": "anyone", - "follower": "a follower", - "follow": "anyone I follow", - "noone": "no one", - "title": "Notify me when" + "anyone": "calquera", + "follower": "unha seguidora", + "follow": "alguén a quen sigo", + "noone": "ninguén", + "title": "Avisarme cando" } }, "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": "Preferencias", + "true_black_dark_mode": "Modo negro verdadeiro", + "disable_avatar_animation": "Desactivar avatares animados", + "disable_emoji_animation": "Desactivar emojis animados", + "using_default_browser": "Usar navegador por defecto para as ligazóns", + "open_links_in_mastodon": "Abrir ligazóns en Mastodon" }, "boring_zone": { - "title": "The Boring Zone", - "account_settings": "Account Settings", - "terms": "Terms of Service", - "privacy": "Privacy Policy" + "title": "A zona aburrida", + "account_settings": "Axustes da conta", + "terms": "Termos do Servizo", + "privacy": "Política de Privacidade" }, "spicy_zone": { - "title": "The Spicy Zone", - "clear": "Clear Media Cache", - "signout": "Sign Out" + "title": "A zona picante", + "clear": "Limpar caché multimedia", + "signout": "Pechar sesión" } }, "footer": { - "mastodon_description": "Mastodon is open source software. You can report issues on GitHub at %s (%s)" + "mastodon_description": "Mastodon é software de código aberto. Podes informar de fallos en GitHub en %s (%s)" }, "keyboard": { - "close_settings_window": "Close Settings Window" + "close_settings_window": "Pechar ventá de axustes" } }, "report": { @@ -596,7 +615,49 @@ "send": "Enviar Denuncia", "skip_to_send": "Enviar sen comentarios", "text_placeholder": "Escribe ou pega comentarios adicionais", - "reported": "DENUNCIADO" + "reported": "DENUNCIADO", + "step_one": { + "step_1_of_4": "Paso 1 de 4", + "whats_wrong_with_this_post": "Cal é o problema con esta publicación?", + "whats_wrong_with_this_account": "Cal é o problema con esta conta?", + "whats_wrong_with_this_username": "Cal é o problema con %s?", + "select_the_best_match": "Elixe a mellor coincidencia", + "i_dont_like_it": "Non me gusta", + "it_is_not_something_you_want_to_see": "Non é algo que queiras ver", + "its_spam": "É spam", + "malicious_links_fake_engagement_or_repetetive_replies": "Ligazóns perigosas, relacións falsas, ou respostas repetitivas", + "it_violates_server_rules": "Viola as regras do servidor", + "you_are_aware_that_it_breaks_specific_rules": "Décheste conta de que quebra unhas normas en concreto", + "its_something_else": "É outra cousa", + "the_issue_does_not_fit_into_other_categories": "O problema non cae dentro de outras categorías" + }, + "step_two": { + "step_2_of_4": "Paso 2 de 4", + "which_rules_are_being_violated": "Que regras foron incumpridas?", + "select_all_that_apply": "Elixe todo o que sexa de aplicación", + "i_just_don’t_like_it": "Non me gusta" + }, + "step_three": { + "step_3_of_4": "Paso 3 de 4", + "are_there_any_posts_that_back_up_this_report": "Hai algunha publicación que apoie esta denuncia?", + "select_all_that_apply": "Elixe todo o que sexa de aplicación" + }, + "step_four": { + "step_4_of_4": "Paso 4 de 4", + "is_there_anything_else_we_should_know": "Hai algo máis que creas debamos saber?" + }, + "step_final": { + "dont_want_to_see_this": "Non queres ver esto?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Cando ves en Mastodon algo que non che gusta podes retirar a esa persoa da túa experiencia como usuaria.", + "unfollow": "Deixar de seguir", + "unfollowed": "Deixaches de seguir", + "unfollow_user": "Deixar de seguir a %s", + "mute_user": "Acalar a %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Non verás as súas publicacións ou repeticións na túa cronoloxía. Non saberá que foi acalada.", + "block_user": "Bloquear a %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Non poderá seguirte nin ver o que publicas, pero pode ver se foi bloqueada.", + "while_we_review_this_you_can_take_action_against_user": "Mentras revisamos esto, podes tomar accións contra %s" + } }, "preview": { "keyboard": { @@ -606,14 +667,14 @@ } }, "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": "Perfil seleccionado: %s. Dobre toque e manter para mostrar o intercambiador de contas", + "dismiss_account_switcher": "Desbotar intercambiador de contas", + "add_account": "Engadir conta" }, "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": "Novidade en Mastodon", + "multiple_account_switch_intro_description": "Cambia dunha conta a outra mantendo preso o botón do perfil.", + "accessibility_hint": "Dobre toque para desbotar este asistente" } } } \ No newline at end of file diff --git a/Localization/StringsConvertor/input/gl.lproj/ios-infoPlist.json b/Localization/StringsConvertor/input/gl.lproj/ios-infoPlist.json new file mode 100644 index 000000000..e3ec3fb73 --- /dev/null +++ b/Localization/StringsConvertor/input/gl.lproj/ios-infoPlist.json @@ -0,0 +1,6 @@ +{ + "NSCameraUsageDescription": "Utilizado para facer foto e publicar estado", + "NSPhotoLibraryAddUsageDescription": "Utilizado para gardar a foto na Biblioteca", + "NewPostShortcutItemTitle": "Nova publicación", + "SearchShortcutItemTitle": "Buscar" +} diff --git a/Localization/StringsConvertor/input/gl_ES/Localizable.stringsdict b/Localization/StringsConvertor/input/hi.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/gl_ES/Localizable.stringsdict rename to Localization/StringsConvertor/input/hi.lproj/Localizable.stringsdict index 503ff9dbd..bdcae6ac9 100644 --- a/Localization/StringsConvertor/input/gl_ES/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/hi.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld characters + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ posts + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/hi_IN/app.json b/Localization/StringsConvertor/input/hi.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/hi_IN/app.json rename to Localization/StringsConvertor/input/hi.lproj/app.json index b9f992774..04b8fa021 100644 --- a/Localization/StringsConvertor/input/hi_IN/app.json +++ b/Localization/StringsConvertor/input/hi.lproj/app.json @@ -240,7 +240,8 @@ "category": "CATEGORY" }, "input": { - "placeholder": "Search servers" + "placeholder": "Search servers", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Finding available servers...", @@ -250,6 +251,7 @@ }, "register": { "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Delete" @@ -320,6 +322,7 @@ "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" @@ -342,7 +345,11 @@ "offline": "Offline", "new_posts": "See new posts", "published": "Published!", - "Publishing": "Publishing post..." + "Publishing": "Publishing post...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Followers from other servers are not displayed." }, "following": { + "title": "following", "footer": "Follows from other servers are not displayed." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Search", "search_bar": { @@ -596,7 +615,49 @@ "send": "Send Report", "skip_to_send": "Send without comment", "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/fi_FI/ios-infoPlist.json b/Localization/StringsConvertor/input/hi.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/fi_FI/ios-infoPlist.json rename to Localization/StringsConvertor/input/hi.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/hi_IN/Localizable.stringsdict b/Localization/StringsConvertor/input/hi_IN/Localizable.stringsdict deleted file mode 100644 index 503ff9dbd..000000000 --- a/Localization/StringsConvertor/input/hi_IN/Localizable.stringsdict +++ /dev/null @@ -1,406 +0,0 @@ - - - - - a11y.plural.count.unread.notification - - NSStringLocalizedFormatKey - %#@notification_count_unread_notification@ - notification_count_unread_notification - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 unread notification - other - %ld unread notification - - - a11y.plural.count.input_limit_exceeds - - NSStringLocalizedFormatKey - Input limit exceeds %#@character_count@ - character_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 character - other - %ld characters - - - a11y.plural.count.input_limit_remains - - NSStringLocalizedFormatKey - Input limit remains %#@character_count@ - character_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 character - other - %ld characters - - - plural.count.metric_formatted.post - - NSStringLocalizedFormatKey - %@ %#@post_count@ - post_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - post - other - posts - - - plural.count.post - - NSStringLocalizedFormatKey - %#@post_count@ - post_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 post - other - %ld posts - - - plural.count.favorite - - NSStringLocalizedFormatKey - %#@favorite_count@ - favorite_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 favorite - other - %ld favorites - - - plural.count.reblog - - NSStringLocalizedFormatKey - %#@reblog_count@ - reblog_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 reblog - other - %ld reblogs - - - plural.count.reply - - NSStringLocalizedFormatKey - %#@reply_count@ - reply_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 reply - other - %ld replies - - - plural.count.vote - - NSStringLocalizedFormatKey - %#@vote_count@ - vote_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 vote - other - %ld votes - - - plural.count.voter - - NSStringLocalizedFormatKey - %#@voter_count@ - voter_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 voter - other - %ld voters - - - plural.people_talking - - NSStringLocalizedFormatKey - %#@count_people_talking@ - count_people_talking - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 people talking - other - %ld people talking - - - plural.count.following - - NSStringLocalizedFormatKey - %#@count_following@ - count_following - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 following - other - %ld following - - - plural.count.follower - - NSStringLocalizedFormatKey - %#@count_follower@ - count_follower - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 follower - other - %ld followers - - - date.year.left - - NSStringLocalizedFormatKey - %#@count_year_left@ - count_year_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 year left - other - %ld years left - - - date.month.left - - NSStringLocalizedFormatKey - %#@count_month_left@ - count_month_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 months left - other - %ld months left - - - date.day.left - - NSStringLocalizedFormatKey - %#@count_day_left@ - count_day_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 day left - other - %ld days left - - - date.hour.left - - NSStringLocalizedFormatKey - %#@count_hour_left@ - count_hour_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 hour left - other - %ld hours left - - - date.minute.left - - NSStringLocalizedFormatKey - %#@count_minute_left@ - count_minute_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 minute left - other - %ld minutes left - - - date.second.left - - NSStringLocalizedFormatKey - %#@count_second_left@ - count_second_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 second left - other - %ld seconds left - - - date.year.ago.abbr - - NSStringLocalizedFormatKey - %#@count_year_ago_abbr@ - count_year_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1y ago - other - %ldy ago - - - date.month.ago.abbr - - NSStringLocalizedFormatKey - %#@count_month_ago_abbr@ - count_month_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1M ago - other - %ldM ago - - - date.day.ago.abbr - - NSStringLocalizedFormatKey - %#@count_day_ago_abbr@ - count_day_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1d ago - other - %ldd ago - - - date.hour.ago.abbr - - NSStringLocalizedFormatKey - %#@count_hour_ago_abbr@ - count_hour_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1h ago - other - %ldh ago - - - date.minute.ago.abbr - - NSStringLocalizedFormatKey - %#@count_minute_ago_abbr@ - count_minute_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1m ago - other - %ldm ago - - - date.second.ago.abbr - - NSStringLocalizedFormatKey - %#@count_second_ago_abbr@ - count_second_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1s ago - other - %lds ago - - - - diff --git a/Localization/StringsConvertor/input/id_ID/Localizable.stringsdict b/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/id_ID/Localizable.stringsdict rename to Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict index a4a0f4936..2635defb8 100644 --- a/Localization/StringsConvertor/input/id_ID/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/id.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld karakter + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ postingan + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/id_ID/app.json b/Localization/StringsConvertor/input/id.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/id_ID/app.json rename to Localization/StringsConvertor/input/id.lproj/app.json index 4e75ce926..c3f987d98 100644 --- a/Localization/StringsConvertor/input/id_ID/app.json +++ b/Localization/StringsConvertor/input/id.lproj/app.json @@ -240,7 +240,8 @@ "category": "KATEGORI" }, "input": { - "placeholder": "Search servers" + "placeholder": "Search servers", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Mencari server yang tersedia...", @@ -250,6 +251,7 @@ }, "register": { "title": "Beritahu kami tentang diri Anda.", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Hapus" @@ -320,6 +322,7 @@ "confirm_email": { "title": "Satu hal lagi.", "subtitle": "Kami baru saja mengirim sebuah surel ke %s,\nketuk tautannya untuk mengkonfirmasi akun Anda.", + "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": "Buka Aplikasi Surel", "resend": "Resend" @@ -342,7 +345,11 @@ "offline": "Luring", "new_posts": "Lihat postingan baru", "published": "Dipublikasikan!", - "Publishing": "Mempublikasikan postingan..." + "Publishing": "Mempublikasikan postingan...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Followers from other servers are not displayed." }, "following": { + "title": "following", "footer": "Follows from other servers are not displayed." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Cari", "search_bar": { @@ -596,7 +615,49 @@ "send": "Kirim Laporan", "skip_to_send": "Kirim tanpa komentar", "text_placeholder": "Ketik atau tempel komentar tambahan", - "reported": "REPORTED" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/id_ID/ios-infoPlist.json b/Localization/StringsConvertor/input/id.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/id_ID/ios-infoPlist.json rename to Localization/StringsConvertor/input/id.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/it_IT/Localizable.stringsdict b/Localization/StringsConvertor/input/it.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/it_IT/Localizable.stringsdict rename to Localization/StringsConvertor/input/it.lproj/Localizable.stringsdict index 710980608..38f986521 100644 --- a/Localization/StringsConvertor/input/it_IT/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/it.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld caratteri + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Seguito da %1$@ e un altro amico in comune + other + Seguito da %1$@ e %ld amici in comune + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ post + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 contenuto multimediale + other + %ld contenuti multimediali + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/it_IT/app.json b/Localization/StringsConvertor/input/it.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/it_IT/app.json rename to Localization/StringsConvertor/input/it.lproj/app.json index 9ba5de28c..9543837b5 100644 --- a/Localization/StringsConvertor/input/it_IT/app.json +++ b/Localization/StringsConvertor/input/it.lproj/app.json @@ -240,7 +240,8 @@ "category": "CATEGORIA" }, "input": { - "placeholder": "Cerca comunità" + "placeholder": "Cerca comunità", + "search_servers_or_enter_url": "Cerca i server o inserisci l'URL" }, "empty_state": { "finding_servers": "Ricerca server disponibili...", @@ -250,6 +251,7 @@ }, "register": { "title": "Facciamo in modo che sia configurato il %s", + "lets_get_you_set_up_on_domain": "Facciamo in modo che sia configurato su %s", "input": { "avatar": { "delete": "Elimina" @@ -320,6 +322,7 @@ "confirm_email": { "title": "Un'ultima cosa.", "subtitle": "Tocca il link che ti abbiamo inviato per verificare il tuo account.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tocca sul collegamento che ti abbiamo inviato, per verificare il tuo account", "button": { "open_email_app": "Apri l'app Email", "resend": "Invia di nuovo" @@ -342,7 +345,11 @@ "offline": "Non in linea", "new_posts": "Vedi nuovi post", "published": "Pubblicato!", - "Publishing": "Pubblicazione post..." + "Publishing": "Pubblicazione post...", + "accessibility": { + "logo_label": "Pulsante Logo", + "logo_hint": "Tocca per scorrere verso l'alto e tocca di nuovo verso la posizione precedente" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "seguace", "footer": "I seguaci da altri server non vengono visualizzati." }, "following": { + "title": "seguendo", "footer": "I follow da altri server non vengono visualizzati." }, + "familiarFollowers": { + "title": "Seguaci che conosci", + "followed_by_names": "Seguito da %s" + }, + "favorited_by": { + "title": "Preferito Da" + }, + "reblogged_by": { + "title": "Condiviso Da" + }, "search": { "title": "Cerca", "search_bar": { @@ -596,7 +615,49 @@ "send": "Invia segnalazione", "skip_to_send": "Invia senza commento", "text_placeholder": "Digita o incolla commenti aggiuntivi", - "reported": "SEGNALATO" + "reported": "SEGNALATO", + "step_one": { + "step_1_of_4": "Fase 1 di 4", + "whats_wrong_with_this_post": "Cosa c'è che non va con questo post?", + "whats_wrong_with_this_account": "Cosa c'è che non va con questo account?", + "whats_wrong_with_this_username": "Cosa c'è che non va con %s?", + "select_the_best_match": "Scegli la migliore corrispondenza", + "i_dont_like_it": "Non mi piace", + "it_is_not_something_you_want_to_see": "È qualcosa che non vuoi vedere", + "its_spam": "È spam", + "malicious_links_fake_engagement_or_repetetive_replies": "Collegamenti malevoli, false interazioni o risposte ripetitive", + "it_violates_server_rules": "Viola le regole del server", + "you_are_aware_that_it_breaks_specific_rules": "Sei consapevole che violi regole specifiche", + "its_something_else": "È qualcos'altro", + "the_issue_does_not_fit_into_other_categories": "Il problema non rientra in altre categorie" + }, + "step_two": { + "step_2_of_4": "Fase 2 di 4", + "which_rules_are_being_violated": "Quali regole vengono violate?", + "select_all_that_apply": "Seleziona tutte le risposte pertinenti", + "i_just_don’t_like_it": "Non mi piace" + }, + "step_three": { + "step_3_of_4": "Fase 3 di 4", + "are_there_any_posts_that_back_up_this_report": "Ci sono post a sostegno di questa segnalazione?", + "select_all_that_apply": "Seleziona tutte le risposte pertinenti" + }, + "step_four": { + "step_4_of_4": "Fase 4 di 4", + "is_there_anything_else_we_should_know": "C'è altro che dovremmo sapere?" + }, + "step_final": { + "dont_want_to_see_this": "Non vuoi vedere questo?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Quando vedi qualcosa che non ti piace su Mastodon, puoi rimuovere la persona dalla tua esperienza.", + "unfollow": "Smetti di seguire", + "unfollowed": "Non seguito", + "unfollow_user": "Smetti di seguire %s", + "mute_user": "Silenzia %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Non vedrai i loro post o le condivisioni nel tuo feed. Non sapranno di essere stati silenziati.", + "block_user": "Blocca %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Non saranno più in grado di seguire o vedere i tuoi post, ma possono vedere se sono stati bloccati.", + "while_we_review_this_you_can_take_action_against_user": "Mentre controlliamo, puoi agire contro %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/it_IT/ios-infoPlist.json b/Localization/StringsConvertor/input/it.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/it_IT/ios-infoPlist.json rename to Localization/StringsConvertor/input/it.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/ja_JP/Localizable.stringsdict b/Localization/StringsConvertor/input/ja.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/ja_JP/Localizable.stringsdict rename to Localization/StringsConvertor/input/ja.lproj/Localizable.stringsdict index 8dfc95079..054b8cded 100644 --- a/Localization/StringsConvertor/input/ja_JP/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/ja.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld 文字 + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ 投稿 + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld media + + plural.count.post NSStringLocalizedFormatKey @@ -153,7 +190,7 @@ NSStringFormatValueTypeKey ld other - %ld people talking + %ld人が投稿 plural.count.following diff --git a/Localization/StringsConvertor/input/ja_JP/app.json b/Localization/StringsConvertor/input/ja.lproj/app.json similarity index 83% rename from Localization/StringsConvertor/input/ja_JP/app.json rename to Localization/StringsConvertor/input/ja.lproj/app.json index f0b759d14..a4e55aae5 100644 --- a/Localization/StringsConvertor/input/ja_JP/app.json +++ b/Localization/StringsConvertor/input/ja.lproj/app.json @@ -45,8 +45,8 @@ "message": "写真を保存するには、フォトライブラリへのアクセス許可を有効にしてください。" }, "delete_post": { - "title": "この投稿を消去しますか?", - "message": "本当に削除しますか?" + "title": "投稿を削除", + "message": "本当にこの投稿を削除しますか?" }, "clean_cache": { "title": "キャッシュを消去", @@ -56,7 +56,7 @@ "controls": { "actions": { "back": "戻る", - "next": "次", + "next": "次へ", "previous": "前", "open": "開く", "add": "追加", @@ -91,7 +91,7 @@ "block_domain": "%sをブロック", "unblock_domain": "%sのブロックを解除", "settings": "設定", - "delete": "消去" + "delete": "削除" }, "tabs": { "home": "ホーム", @@ -131,7 +131,7 @@ "content_warning": "コンテンツ警告", "sensitive_content": "Sensitive Content", "media_content_warning": "どこかをタップして表示", - "tap_to_reveal": "Tap to reveal", + "tap_to_reveal": "タップして表示", "poll": { "vote": "投票", "closed": "クローズド" @@ -144,8 +144,8 @@ "unfavorite": "お気に入り登録を取り消す", "menu": "メニュー", "hide": "非表示", - "show_image": "Show image", - "show_gif": "Show GIF", + "show_image": "画像を表示", + "show_gif": "GIFを表示", "show_video_player": "Show video player", "tap_then_hold_to_show_menu": "Tap then hold to show menu" }, @@ -207,7 +207,7 @@ "scene": { "welcome": { "slogan": "ソーシャルネットワーキングを、あなたの手の中に.", - "get_started": "Get Started", + "get_started": "はじめる", "log_in": "ログイン" }, "server_picker": { @@ -240,7 +240,8 @@ "category": "カテゴリー" }, "input": { - "placeholder": "サーバーを探す" + "placeholder": "サーバーを探す", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "利用可能なサーバーの検索...", @@ -250,9 +251,10 @@ }, "register": { "title": "あなたのことを教えてください", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { - "delete": "消去" + "delete": "削除" }, "username": { "placeholder": "ユーザー名", @@ -320,6 +322,7 @@ "confirm_email": { "title": "さいごにもうひとつ。", "subtitle": "先程 %s にメールを送信しました。リンクをタップしてアカウントを確認してください。", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", "button": { "open_email_app": "メールアプリを開く", "resend": "Resend" @@ -342,7 +345,11 @@ "offline": "オフライン", "new_posts": "新しい投稿を見る", "published": "投稿しました!", - "Publishing": "投稿中..." + "Publishing": "投稿中...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "他のサーバーからのフォロワーは表示されません。" }, "following": { + "title": "following", "footer": "他のサーバーにいるフォローは表示されません。" }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "検索", "search_bar": { @@ -498,10 +517,10 @@ "posts": "投稿", "hashtags": "ハッシュタグ", "news": "ニュース", - "community": "Community", - "for_you": "For You" + "community": "コミュニティ", + "for_you": "おすすめ" }, - "intro": "These are the posts gaining traction in your corner of Mastodon." + "intro": "あなたのMastodonサーバーで注目を集めている投稿がここに表示されます。" }, "favorite": { "title": "お気に入り" @@ -512,12 +531,12 @@ "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" + "followed_you": "さんにフォローされました", + "favorited_your_post": "さんがあなたの投稿をお気に入りに登録しました", + "reblogged_your_post": "さんがあなたの投稿をブーストしました", + "mentioned_you": "さんがあなたに返信しました", + "request_to_follow_you": "さんがあなたにフォローリクエストしました", + "poll_has_ended": "アンケートが終了しました" }, "keyobard": { "show_everything": "すべて見る", @@ -538,11 +557,11 @@ "dark": "ダーク" }, "look_and_feel": { - "title": "Look and Feel", - "use_system": "Use System", - "really_dark": "Really Dark", - "sorta_dark": "Sorta Dark", - "light": "Light" + "title": "テーマ", + "use_system": "端末の設定を使う", + "really_dark": "ブラック", + "sorta_dark": "ダーク", + "light": "ライト" }, "notifications": { "title": "通知", @@ -564,7 +583,7 @@ "disable_avatar_animation": "アバターのアニメーションを無効化する", "disable_emoji_animation": "絵文字のアニメーションを無効化する", "using_default_browser": "既定のブラウザでリンクを開く", - "open_links_in_mastodon": "Open links in Mastodon" + "open_links_in_mastodon": "Mastodonでリンクを開く" }, "boring_zone": { "title": "アプリについて", @@ -596,7 +615,49 @@ "send": "通報を送信", "skip_to_send": "コメントなしで送信", "text_placeholder": "追加コメントを入力", - "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/ja_JP/ios-infoPlist.json b/Localization/StringsConvertor/input/ja.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/ja_JP/ios-infoPlist.json rename to Localization/StringsConvertor/input/ja.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/kab_KAB/Localizable.stringsdict b/Localization/StringsConvertor/input/kab.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/kab_KAB/Localizable.stringsdict rename to Localization/StringsConvertor/input/kab.lproj/Localizable.stringsdict index 4ccb271fa..09e3645f3 100644 --- a/Localization/StringsConvertor/input/kab_KAB/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/kab.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld yisekkilen + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ tisuffaɣ + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/kab_KAB/app.json b/Localization/StringsConvertor/input/kab.lproj/app.json similarity index 87% rename from Localization/StringsConvertor/input/kab_KAB/app.json rename to Localization/StringsConvertor/input/kab.lproj/app.json index 1c73686be..8987669c0 100644 --- a/Localization/StringsConvertor/input/kab_KAB/app.json +++ b/Localization/StringsConvertor/input/kab.lproj/app.json @@ -240,7 +240,8 @@ "category": "TAGGAYT" }, "input": { - "placeholder": "Nadi timɣiwnin" + "placeholder": "Nadi timɣiwnin", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Tifin n yiqeddacen yellan...", @@ -250,6 +251,7 @@ }, "register": { "title": "Aha ad nebdu asbadu ɣef %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Kkes" @@ -320,6 +322,7 @@ "confirm_email": { "title": "Taɣawsa taneggarut.", "subtitle": "Sit ɣef useɣwen i ak-n-uznen i wakken ad tesneqdeḍ amiḍan-ik.", + "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": "Ldi asnas n yimayl", "resend": "Ales tuzna" @@ -342,7 +345,11 @@ "offline": "Beṛṛa n tuqqna", "new_posts": "Tissufaɣ timaynutin", "published": "Yettwasuffeɣ!", - "Publishing": "Asuffeɣ tasuffeɣt..." + "Publishing": "Asuffeɣ tasuffeɣt...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Ineḍfaren seg yiqeddacen-nniḍen ur d-ttwaskanen ara." }, "following": { + "title": "following", "footer": "Ineḍfaren seg yiqeddacen-nniḍen ur d-ttwaskanen ara." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Nadi", "search_bar": { @@ -596,7 +615,49 @@ "send": "Azen aneqis", "skip_to_send": "Azen s war awennit", "text_placeholder": "Aru neɣ senteḍ iwenniten-nniḍen", - "reported": "YETTWAMMEL" + "reported": "YETTWAMMEL", + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/kab_KAB/ios-infoPlist.json b/Localization/StringsConvertor/input/kab.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/kab_KAB/ios-infoPlist.json rename to Localization/StringsConvertor/input/kab.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/kmr_TR/Localizable.stringsdict b/Localization/StringsConvertor/input/kmr.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/kmr_TR/Localizable.stringsdict rename to Localization/StringsConvertor/input/kmr.lproj/Localizable.stringsdict index 0fa7d8214..77571439f 100644 --- a/Localization/StringsConvertor/input/kmr_TR/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/kmr.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld tîp + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Ji aliyê %1$@, û hevaleke hevpar tê şopandin + other + Ji aliyê %1$@, û %ld hevalên hevpar tê şopandin + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ şandî + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 medya + other + %ld medya + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/kmr_TR/app.json b/Localization/StringsConvertor/input/kmr.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/kmr_TR/app.json rename to Localization/StringsConvertor/input/kmr.lproj/app.json index fcd6d0220..65f891f93 100644 --- a/Localization/StringsConvertor/input/kmr_TR/app.json +++ b/Localization/StringsConvertor/input/kmr.lproj/app.json @@ -211,7 +211,7 @@ "log_in": "Têkeve" }, "server_picker": { - "title": "Rajekarekê hilbijêre,\nHer kîjan rajekar be.", + "title": "Mastodon ji bikarhênerên di civakên cuda de pêk tê.", "subtitle": "Li gorî berjewendî, herêm, an jî armancek gelemperî civakekê hilbijêre.", "subtitle_extend": "Li gorî berjewendî, herêm, an jî armancek gelemperî civakekê hilbijêre. Her civakek ji hêla rêxistinek an kesek bi tevahî serbixwe ve tê xebitandin.", "button": { @@ -240,7 +240,8 @@ "category": "BEŞ" }, "input": { - "placeholder": "Rajekarekî bibîne an jî beşdarî ya xwe bibe..." + "placeholder": "Li rajekaran bigere", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Peydakirina rajekarên berdest...", @@ -250,6 +251,7 @@ }, "register": { "title": "Ji me re hinekî qala xwe bike %s", + "lets_get_you_set_up_on_domain": "Ka em te bi rê bixin li ser %s", "input": { "avatar": { "delete": "Jê bibe" @@ -320,6 +322,7 @@ "confirm_email": { "title": "Tiştekî dawî.", "subtitle": "Me tenê e-nameyek ji %s re şand,\ngirêdanê bitikne da ku ajimêra xwe bidî piştrastkirin.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Girêdana e-nameyê ku me ji te re şand bitikîne da ku ajimêra xwe bidî piştrastkirin", "button": { "open_email_app": "Sepana e-nameyê veke", "resend": "Ji nû ve bişîne" @@ -342,7 +345,11 @@ "offline": "Derhêl", "new_posts": "Şandiyên nû bibîne", "published": "Hate weşandin!", - "Publishing": "Şandî tê weşandin..." + "Publishing": "Şandî tê weşandin...", + "accessibility": { + "logo_label": "Bişkoka Logo", + "logo_hint": "Ji bo şemitandina jor û dîsa li cihê berê vegerî bitikîne" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "şopîner", "footer": "Şopîner ji rajekerên din nayê dîtin." }, "following": { + "title": "dişopîne", "footer": "Şopandin ji rajekerên din nayê dîtin." }, + "familiarFollowers": { + "title": "Şopînerên ku tu wan nas dikî", + "followed_by_names": "Ji aliyêm%s hatiye şopandin" + }, + "favorited_by": { + "title": "Hatiye hezkirin ji aliyê" + }, + "reblogged_by": { + "title": "Ji nû ve hatiye nivîsandin ji aliyê" + }, "search": { "title": "Bigere", "search_bar": { @@ -596,7 +615,49 @@ "send": "Ragihandinê bişîne", "skip_to_send": "Bêyî şirove bişîne", "text_placeholder": "Şiroveyên daxwazkirê binivîsine an jî pê ve bike", - "reported": "HATE RAGIHANDIN" + "reported": "HATE RAGIHANDIN", + "step_one": { + "step_1_of_4": "Gav 1 ji 4", + "whats_wrong_with_this_post": "Çi çewt e di vê şandiyê de?", + "whats_wrong_with_this_account": "Çi çewt e di vê ajimêrê de?", + "whats_wrong_with_this_username": "Çi çewt e bi %s re?", + "select_the_best_match": "Baştirîn lihevhatina hilbijêre", + "i_dont_like_it": "Ez jê hez nakim", + "it_is_not_something_you_want_to_see": "Ew ne tiştek e ku tu dixwazî bibînî", + "its_spam": "Ew spam e", + "malicious_links_fake_engagement_or_repetetive_replies": "Girêdanên xerab, tevlêbûna sexte, an jî bersivên dubarekirî", + "it_violates_server_rules": "Ew rêzikên rajekar binpê dike", + "you_are_aware_that_it_breaks_specific_rules": "Tu dizanî ku ew rêzikên taybetiyê binpê dike", + "its_something_else": "Tiştekî din e", + "the_issue_does_not_fit_into_other_categories": "Pirsgirêk di kategoriyên din de cih nagire" + }, + "step_two": { + "step_2_of_4": "Gav 2 ji 4", + "which_rules_are_being_violated": "Kîjan rêzik têne binpêkirin?", + "select_all_that_apply": "Hemûyên ku têne sepandin hilbijêre", + "i_just_don’t_like_it": "Tenê ez jê hez nakim" + }, + "step_three": { + "step_3_of_4": "Gav 3 ji 4", + "are_there_any_posts_that_back_up_this_report": "Tu şandiyên ku vê ragihandinê piştgirî dikin hene?", + "select_all_that_apply": "Hemûyên ku têne sepandin hilbijêre" + }, + "step_four": { + "step_4_of_4": "Gav 4 ji 4", + "is_there_anything_else_we_should_know": "Tiştek din heye ku tu difikirî ku divê em zanibin?" + }, + "step_final": { + "dont_want_to_see_this": "Tu naxwazî vê bibînî?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Dema li ser Mastodonê tiştekî ku tu jê hez nakî bibînî, tu dikarî ew kes ji navrûya xwe derxî.", + "unfollow": "Neşopîne", + "unfollowed": "Ji şopê hate derketin", + "unfollow_user": "%s neşopîne", + "mute_user": "%s bêdeng bike", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Tu yê şandî an jî bilindkirinên wan di rojeva xwe de nebînî. Ew ê nizanibin ku hatine bêdengkirin.", + "block_user": "%s asteng bike", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Êdî nikarin şandiyên te bişopînin an jî bibînin, lê ew dikarin bibînin ka hatine astengkirin an na.", + "while_we_review_this_you_can_take_action_against_user": "Dema ku em vê yekê dinirxînin, tu dikarî li dijî %s tedbîran bigirî" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/kmr_TR/ios-infoPlist.json b/Localization/StringsConvertor/input/kmr.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/kmr_TR/ios-infoPlist.json rename to Localization/StringsConvertor/input/kmr.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/ko_KR/Localizable.stringsdict b/Localization/StringsConvertor/input/ko.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/ko_KR/Localizable.stringsdict rename to Localization/StringsConvertor/input/ko.lproj/Localizable.stringsdict index 2af4c9ce9..d03431fa0 100644 --- a/Localization/StringsConvertor/input/ko_KR/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/ko.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld characters + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ 게시물 + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + 미디어 %ld개 + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/ko_KR/app.json b/Localization/StringsConvertor/input/ko.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/ko_KR/app.json rename to Localization/StringsConvertor/input/ko.lproj/app.json index 294a53bb5..ea42eaa71 100644 --- a/Localization/StringsConvertor/input/ko_KR/app.json +++ b/Localization/StringsConvertor/input/ko.lproj/app.json @@ -67,7 +67,7 @@ "done": "완료", "confirm": "확인", "continue": "계속", - "compose": "Compose", + "compose": "작성", "cancel": "취소", "discard": "버리기", "try_again": "다시 시도", @@ -82,7 +82,7 @@ "share_user": "%s를 공유", "share_post": "게시물 공유", "open_in_safari": "사파리에서 열기", - "open_in_browser": "Open in Browser", + "open_in_browser": "브라우저에서 열기", "find_people": "팔로우 할 사람들 찾기", "manually_search": "대신 수동으로 검색하기", "skip": "건너뛰기", @@ -131,7 +131,7 @@ "content_warning": "열람 주의", "sensitive_content": "Sensitive Content", "media_content_warning": "Tap anywhere to reveal", - "tap_to_reveal": "Tap to reveal", + "tap_to_reveal": "눌러서 확인", "poll": { "vote": "투표", "closed": "마감" @@ -143,8 +143,8 @@ "favorite": "즐겨찾기", "unfavorite": "즐겨찾기 해제", "menu": "메뉴", - "hide": "Hide", - "show_image": "Show image", + "hide": "숨기기", + "show_image": "이미지 표시", "show_gif": "Show GIF", "show_video_player": "Show video player", "tap_then_hold_to_show_menu": "Tap then hold to show menu" @@ -240,7 +240,8 @@ "category": "분류" }, "input": { - "placeholder": "Search servers" + "placeholder": "Search servers", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Finding available servers...", @@ -250,6 +251,7 @@ }, "register": { "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "삭제" @@ -320,6 +322,7 @@ "confirm_email": { "title": "마지막으로.", "subtitle": "Tap the link we emailed to you to verify your account.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", "button": { "open_email_app": "Open Email App", "resend": "Resend" @@ -342,7 +345,11 @@ "offline": "오프라인", "new_posts": "새 글 보기", "published": "게시됨!", - "Publishing": "Publishing post..." + "Publishing": "Publishing post...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Followers from other servers are not displayed." }, "following": { + "title": "following", "footer": "Follows from other servers are not displayed." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "검색", "search_bar": { @@ -596,7 +615,49 @@ "send": "신고 전송", "skip_to_send": "추가설명 없이 보내기", "text_placeholder": "추가 설명을 적거나 붙여넣으세요", - "reported": "REPORTED" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "서버의 중재자들이 이것을 심사하는 동안, 당신은 %s에 대한 행동을 취할 수 있습니다" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/ko_KR/ios-infoPlist.json b/Localization/StringsConvertor/input/ko.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/ko_KR/ios-infoPlist.json rename to Localization/StringsConvertor/input/ko.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/nl_NL/Localizable.stringsdict b/Localization/StringsConvertor/input/nl.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/nl_NL/Localizable.stringsdict rename to Localization/StringsConvertor/input/nl.lproj/Localizable.stringsdict index 5ae33cbef..314600ff7 100644 --- a/Localization/StringsConvertor/input/nl_NL/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/nl.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld tekens + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ berichten + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/nl_NL/app.json b/Localization/StringsConvertor/input/nl.lproj/app.json similarity index 87% rename from Localization/StringsConvertor/input/nl_NL/app.json rename to Localization/StringsConvertor/input/nl.lproj/app.json index aa43e8490..883b6a0ed 100644 --- a/Localization/StringsConvertor/input/nl_NL/app.json +++ b/Localization/StringsConvertor/input/nl.lproj/app.json @@ -240,7 +240,8 @@ "category": "CATEGORIE" }, "input": { - "placeholder": "Zoek uw server of sluit u bij een nieuwe server aan..." + "placeholder": "Zoek uw server of sluit u bij een nieuwe server aan...", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Beschikbare servers zoeken...", @@ -250,6 +251,7 @@ }, "register": { "title": "Vertel ons over uzelf.", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Verwijderen" @@ -320,6 +322,7 @@ "confirm_email": { "title": "Nog één ding.", "subtitle": "We hebben een e-mail gestuurd naar %s,\nklik op de link om uw account te bevestigen.", + "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": "Email Openen", "resend": "Verstuur opnieuw" @@ -342,7 +345,11 @@ "offline": "Offline", "new_posts": "Bekijk nieuwe berichten", "published": "Gepubliceerd!", - "Publishing": "Bericht publiceren..." + "Publishing": "Bericht publiceren...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Volgers van andere servers worden niet weergegeven." }, "following": { + "title": "following", "footer": "Volgers van andere servers worden niet weergegeven." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Zoeken", "search_bar": { @@ -596,7 +615,49 @@ "send": "Stuur rapport", "skip_to_send": "Verstuur zonder opmerkingen", "text_placeholder": "Schrijf of plak aanvullende opmerkingen", - "reported": "Gerapporteerd" + "reported": "Gerapporteerd", + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/nl_NL/ios-infoPlist.json b/Localization/StringsConvertor/input/nl.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/nl_NL/ios-infoPlist.json rename to Localization/StringsConvertor/input/nl.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/pt_BR/Localizable.stringsdict b/Localization/StringsConvertor/input/pt-BR.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/pt_BR/Localizable.stringsdict rename to Localization/StringsConvertor/input/pt-BR.lproj/Localizable.stringsdict index da8ea084c..ba1532740 100644 --- a/Localization/StringsConvertor/input/pt_BR/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/pt-BR.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld caracteres + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ posts + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/pt_BR/app.json b/Localization/StringsConvertor/input/pt-BR.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/pt_BR/app.json rename to Localization/StringsConvertor/input/pt-BR.lproj/app.json index 778669999..cbb5b319e 100644 --- a/Localization/StringsConvertor/input/pt_BR/app.json +++ b/Localization/StringsConvertor/input/pt-BR.lproj/app.json @@ -240,7 +240,8 @@ "category": "CATEGORY" }, "input": { - "placeholder": "Search servers" + "placeholder": "Search servers", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Finding available servers...", @@ -250,6 +251,7 @@ }, "register": { "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Delete" @@ -320,6 +322,7 @@ "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" @@ -342,7 +345,11 @@ "offline": "Offline", "new_posts": "See new posts", "published": "Published!", - "Publishing": "Publishing post..." + "Publishing": "Publishing post...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Followers from other servers are not displayed." }, "following": { + "title": "following", "footer": "Follows from other servers are not displayed." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Search", "search_bar": { @@ -596,7 +615,49 @@ "send": "Send Report", "skip_to_send": "Send without comment", "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/gl_ES/ios-infoPlist.json b/Localization/StringsConvertor/input/pt-BR.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/gl_ES/ios-infoPlist.json rename to Localization/StringsConvertor/input/pt-BR.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/pt.lproj/Localizable.stringsdict b/Localization/StringsConvertor/input/pt.lproj/Localizable.stringsdict new file mode 100644 index 000000000..bdcae6ac9 --- /dev/null +++ b/Localization/StringsConvertor/input/pt.lproj/Localizable.stringsdict @@ -0,0 +1,449 @@ + + + + + a11y.plural.count.unread.notification + + NSStringLocalizedFormatKey + %#@notification_count_unread_notification@ + notification_count_unread_notification + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 unread notification + other + %ld unread notification + + + a11y.plural.count.input_limit_exceeds + + NSStringLocalizedFormatKey + Input limit exceeds %#@character_count@ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 character + other + %ld characters + + + a11y.plural.count.input_limit_remains + + NSStringLocalizedFormatKey + Input limit remains %#@character_count@ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 character + other + %ld characters + + + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + + plural.count.metric_formatted.post + + NSStringLocalizedFormatKey + %@ %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + post + other + posts + + + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + + plural.count.post + + NSStringLocalizedFormatKey + %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 post + other + %ld posts + + + plural.count.favorite + + NSStringLocalizedFormatKey + %#@favorite_count@ + favorite_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 favorite + other + %ld favorites + + + plural.count.reblog + + NSStringLocalizedFormatKey + %#@reblog_count@ + reblog_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 reblog + other + %ld reblogs + + + plural.count.reply + + NSStringLocalizedFormatKey + %#@reply_count@ + reply_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 reply + other + %ld replies + + + plural.count.vote + + NSStringLocalizedFormatKey + %#@vote_count@ + vote_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 vote + other + %ld votes + + + plural.count.voter + + NSStringLocalizedFormatKey + %#@voter_count@ + voter_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 voter + other + %ld voters + + + plural.people_talking + + NSStringLocalizedFormatKey + %#@count_people_talking@ + count_people_talking + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 people talking + other + %ld people talking + + + plural.count.following + + NSStringLocalizedFormatKey + %#@count_following@ + count_following + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 following + other + %ld following + + + plural.count.follower + + NSStringLocalizedFormatKey + %#@count_follower@ + count_follower + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 follower + other + %ld followers + + + date.year.left + + NSStringLocalizedFormatKey + %#@count_year_left@ + count_year_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 year left + other + %ld years left + + + date.month.left + + NSStringLocalizedFormatKey + %#@count_month_left@ + count_month_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 months left + other + %ld months left + + + date.day.left + + NSStringLocalizedFormatKey + %#@count_day_left@ + count_day_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 day left + other + %ld days left + + + date.hour.left + + NSStringLocalizedFormatKey + %#@count_hour_left@ + count_hour_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 hour left + other + %ld hours left + + + date.minute.left + + NSStringLocalizedFormatKey + %#@count_minute_left@ + count_minute_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 minute left + other + %ld minutes left + + + date.second.left + + NSStringLocalizedFormatKey + %#@count_second_left@ + count_second_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 second left + other + %ld seconds left + + + date.year.ago.abbr + + NSStringLocalizedFormatKey + %#@count_year_ago_abbr@ + count_year_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1y ago + other + %ldy ago + + + date.month.ago.abbr + + NSStringLocalizedFormatKey + %#@count_month_ago_abbr@ + count_month_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1M ago + other + %ldM ago + + + date.day.ago.abbr + + NSStringLocalizedFormatKey + %#@count_day_ago_abbr@ + count_day_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1d ago + other + %ldd ago + + + date.hour.ago.abbr + + NSStringLocalizedFormatKey + %#@count_hour_ago_abbr@ + count_hour_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1h ago + other + %ldh ago + + + date.minute.ago.abbr + + NSStringLocalizedFormatKey + %#@count_minute_ago_abbr@ + count_minute_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1m ago + other + %ldm ago + + + date.second.ago.abbr + + NSStringLocalizedFormatKey + %#@count_second_ago_abbr@ + count_second_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1s ago + other + %lds ago + + + + diff --git a/Localization/StringsConvertor/input/fi_FI/app.json b/Localization/StringsConvertor/input/pt.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/fi_FI/app.json rename to Localization/StringsConvertor/input/pt.lproj/app.json index 50512250d..2a8634a67 100644 --- a/Localization/StringsConvertor/input/fi_FI/app.json +++ b/Localization/StringsConvertor/input/pt.lproj/app.json @@ -240,7 +240,8 @@ "category": "CATEGORY" }, "input": { - "placeholder": "Search servers" + "placeholder": "Search servers", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Finding available servers...", @@ -250,6 +251,7 @@ }, "register": { "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Delete" @@ -320,6 +322,7 @@ "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" @@ -342,7 +345,11 @@ "offline": "Offline", "new_posts": "See new posts", "published": "Published!", - "Publishing": "Publishing post..." + "Publishing": "Publishing post...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Followers from other servers are not displayed." }, "following": { + "title": "following", "footer": "Follows from other servers are not displayed." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Search", "search_bar": { @@ -596,7 +615,49 @@ "send": "Send Report", "skip_to_send": "Send without comment", "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/hi_IN/ios-infoPlist.json b/Localization/StringsConvertor/input/pt.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/hi_IN/ios-infoPlist.json rename to Localization/StringsConvertor/input/pt.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/pt_PT/Localizable.stringsdict b/Localization/StringsConvertor/input/pt_PT/Localizable.stringsdict deleted file mode 100644 index 503ff9dbd..000000000 --- a/Localization/StringsConvertor/input/pt_PT/Localizable.stringsdict +++ /dev/null @@ -1,406 +0,0 @@ - - - - - a11y.plural.count.unread.notification - - NSStringLocalizedFormatKey - %#@notification_count_unread_notification@ - notification_count_unread_notification - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 unread notification - other - %ld unread notification - - - a11y.plural.count.input_limit_exceeds - - NSStringLocalizedFormatKey - Input limit exceeds %#@character_count@ - character_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 character - other - %ld characters - - - a11y.plural.count.input_limit_remains - - NSStringLocalizedFormatKey - Input limit remains %#@character_count@ - character_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 character - other - %ld characters - - - plural.count.metric_formatted.post - - NSStringLocalizedFormatKey - %@ %#@post_count@ - post_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - post - other - posts - - - plural.count.post - - NSStringLocalizedFormatKey - %#@post_count@ - post_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 post - other - %ld posts - - - plural.count.favorite - - NSStringLocalizedFormatKey - %#@favorite_count@ - favorite_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 favorite - other - %ld favorites - - - plural.count.reblog - - NSStringLocalizedFormatKey - %#@reblog_count@ - reblog_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 reblog - other - %ld reblogs - - - plural.count.reply - - NSStringLocalizedFormatKey - %#@reply_count@ - reply_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 reply - other - %ld replies - - - plural.count.vote - - NSStringLocalizedFormatKey - %#@vote_count@ - vote_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 vote - other - %ld votes - - - plural.count.voter - - NSStringLocalizedFormatKey - %#@voter_count@ - voter_count - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 voter - other - %ld voters - - - plural.people_talking - - NSStringLocalizedFormatKey - %#@count_people_talking@ - count_people_talking - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 people talking - other - %ld people talking - - - plural.count.following - - NSStringLocalizedFormatKey - %#@count_following@ - count_following - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 following - other - %ld following - - - plural.count.follower - - NSStringLocalizedFormatKey - %#@count_follower@ - count_follower - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 follower - other - %ld followers - - - date.year.left - - NSStringLocalizedFormatKey - %#@count_year_left@ - count_year_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 year left - other - %ld years left - - - date.month.left - - NSStringLocalizedFormatKey - %#@count_month_left@ - count_month_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 months left - other - %ld months left - - - date.day.left - - NSStringLocalizedFormatKey - %#@count_day_left@ - count_day_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 day left - other - %ld days left - - - date.hour.left - - NSStringLocalizedFormatKey - %#@count_hour_left@ - count_hour_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 hour left - other - %ld hours left - - - date.minute.left - - NSStringLocalizedFormatKey - %#@count_minute_left@ - count_minute_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 minute left - other - %ld minutes left - - - date.second.left - - NSStringLocalizedFormatKey - %#@count_second_left@ - count_second_left - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1 second left - other - %ld seconds left - - - date.year.ago.abbr - - NSStringLocalizedFormatKey - %#@count_year_ago_abbr@ - count_year_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1y ago - other - %ldy ago - - - date.month.ago.abbr - - NSStringLocalizedFormatKey - %#@count_month_ago_abbr@ - count_month_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1M ago - other - %ldM ago - - - date.day.ago.abbr - - NSStringLocalizedFormatKey - %#@count_day_ago_abbr@ - count_day_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1d ago - other - %ldd ago - - - date.hour.ago.abbr - - NSStringLocalizedFormatKey - %#@count_hour_ago_abbr@ - count_hour_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1h ago - other - %ldh ago - - - date.minute.ago.abbr - - NSStringLocalizedFormatKey - %#@count_minute_ago_abbr@ - count_minute_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1m ago - other - %ldm ago - - - date.second.ago.abbr - - NSStringLocalizedFormatKey - %#@count_second_ago_abbr@ - count_second_ago_abbr - - NSStringFormatSpecTypeKey - NSStringPluralRuleType - NSStringFormatValueTypeKey - ld - one - 1s ago - other - %lds ago - - - - diff --git a/Localization/StringsConvertor/input/pt_PT/app.json b/Localization/StringsConvertor/input/pt_PT/app.json deleted file mode 100644 index 50512250d..000000000 --- a/Localization/StringsConvertor/input/pt_PT/app.json +++ /dev/null @@ -1,619 +0,0 @@ -{ - "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" - }, - "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" - }, - "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 can’t view this user's profile\nuntil you unblock them.\nYour profile looks like this to them.", - "user_blocking_warning": "You can’t view %s’s profile\nuntil you unblock them.\nYour profile looks like this to them.", - "blocked_warning": "You can’t view this user’s profile\nuntil they unblock you.", - "user_blocked_warning": "You can’t view %s’s profile\nuntil they unblock you.", - "suspended_warning": "This user has been suspended.", - "user_suspended_warning": "%s’s 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" - }, - "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": "Let’s 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 (can’t 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, you’re 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.", - "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 haven’t.", - "resend_email": "Resend Email" - }, - "open_email_app": { - "title": "Check your inbox.", - "description": "We just sent you an email. Check your junk folder if you haven’t.", - "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..." - } - }, - "suggestion_account": { - "title": "Find People to Follow", - "follow_explain": "When you follow someone, you’ll 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 what’s on your mind", - "compose_action": "Publish", - "replying_to_user": "replying to %s", - "attachment": { - "photo": "photo", - "video": "video", - "attachment_broken": "This %s is broken and can’t be\nuploaded to Mastodon.", - "description_photo": "Describe the photo for the visually-impaired...", - "description_video": "Describe the video for the visually-impaired..." - }, - "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" - }, - "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" - }, - "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": { - "dashboard": { - "posts": "posts", - "following": "following", - "followers": "followers" - }, - "fields": { - "add_row": "Add Row", - "placeholder": { - "label": "Label", - "content": "Content" - } - }, - "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" - } - }, - "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": { - "footer": "Followers from other servers are not displayed." - }, - "following": { - "footer": "Follows from other servers are not displayed." - }, - "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" - } - }, - "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 you’d like to add to the report?", - "content2": "Is there anything the moderators should know about this report?", - "report_sent_title": "Thanks for reporting, we’ll look into this.", - "send": "Send Report", - "skip_to_send": "Send without comment", - "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED" - }, - "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" - } - } -} \ No newline at end of file diff --git a/Localization/StringsConvertor/input/pt_PT/ios-infoPlist.json b/Localization/StringsConvertor/input/pt_PT/ios-infoPlist.json deleted file mode 100644 index c6db73de0..000000000 --- a/Localization/StringsConvertor/input/pt_PT/ios-infoPlist.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "NSCameraUsageDescription": "Used to take photo for post status", - "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", - "NewPostShortcutItemTitle": "New Post", - "SearchShortcutItemTitle": "Search" -} diff --git a/Localization/StringsConvertor/input/ro_RO/Localizable.stringsdict b/Localization/StringsConvertor/input/ro.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/ro_RO/Localizable.stringsdict rename to Localization/StringsConvertor/input/ro.lproj/Localizable.stringsdict index 2acc32767..7ae5a1c79 100644 --- a/Localization/StringsConvertor/input/ro_RO/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/ro.lproj/Localizable.stringsdict @@ -56,6 +56,37 @@ %ld characters + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + few + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + few + Followed by %1$@, and %ld mutuals + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -74,6 +105,24 @@ posts + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + few + %ld media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/ro_RO/app.json b/Localization/StringsConvertor/input/ro.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/ro_RO/app.json rename to Localization/StringsConvertor/input/ro.lproj/app.json index 3436a94ef..20fe425df 100644 --- a/Localization/StringsConvertor/input/ro_RO/app.json +++ b/Localization/StringsConvertor/input/ro.lproj/app.json @@ -240,7 +240,8 @@ "category": "CATEGORY" }, "input": { - "placeholder": "Search servers" + "placeholder": "Search servers", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Finding available servers...", @@ -250,6 +251,7 @@ }, "register": { "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Delete" @@ -320,6 +322,7 @@ "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" @@ -342,7 +345,11 @@ "offline": "Offline", "new_posts": "See new posts", "published": "Published!", - "Publishing": "Publishing post..." + "Publishing": "Publishing post...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Followers from other servers are not displayed." }, "following": { + "title": "following", "footer": "Follows from other servers are not displayed." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Search", "search_bar": { @@ -596,7 +615,49 @@ "send": "Send Report", "skip_to_send": "Send without comment", "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/pt_BR/ios-infoPlist.json b/Localization/StringsConvertor/input/ro.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/pt_BR/ios-infoPlist.json rename to Localization/StringsConvertor/input/ro.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/ro_RO/ios-infoPlist.json b/Localization/StringsConvertor/input/ro_RO/ios-infoPlist.json deleted file mode 100644 index c6db73de0..000000000 --- a/Localization/StringsConvertor/input/ro_RO/ios-infoPlist.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "NSCameraUsageDescription": "Used to take photo for post status", - "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library", - "NewPostShortcutItemTitle": "New Post", - "SearchShortcutItemTitle": "Search" -} diff --git a/Localization/StringsConvertor/input/ru_RU/Localizable.stringsdict b/Localization/StringsConvertor/input/ru.lproj/Localizable.stringsdict similarity index 89% rename from Localization/StringsConvertor/input/ru_RU/Localizable.stringsdict rename to Localization/StringsConvertor/input/ru.lproj/Localizable.stringsdict index 626a10d75..afb29a6aa 100644 --- a/Localization/StringsConvertor/input/ru_RU/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/ru.lproj/Localizable.stringsdict @@ -62,6 +62,41 @@ %ld символа осталось + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + few + + many + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %1$@ и ещё %ld человек подписаны + few + %1$@ и ещё %ld человека подписаны + many + %1$@ и ещё %ld человек подписаны + other + %1$@ и ещё %ld человека подписаны + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -82,6 +117,26 @@ поста + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld медиафайл + few + %ld медиафайла + many + %ld медиафайлов + other + %ld медиафайла + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/ru_RU/app.json b/Localization/StringsConvertor/input/ru.lproj/app.json similarity index 89% rename from Localization/StringsConvertor/input/ru_RU/app.json rename to Localization/StringsConvertor/input/ru.lproj/app.json index 1f7a45544..8a26f718d 100644 --- a/Localization/StringsConvertor/input/ru_RU/app.json +++ b/Localization/StringsConvertor/input/ru.lproj/app.json @@ -240,7 +240,8 @@ "category": "КАТЕГОРИЯ" }, "input": { - "placeholder": "Найдите сервер или присоединитесь к своему..." + "placeholder": "Найдите сервер или присоединитесь к своему...", + "search_servers_or_enter_url": "Поиск по серверам или ссылке" }, "empty_state": { "finding_servers": "Ищем доступные сервера...", @@ -250,6 +251,7 @@ }, "register": { "title": "Расскажите нам о себе.", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Удалить" @@ -320,6 +322,7 @@ "confirm_email": { "title": "И ещё кое-что.", "subtitle": "Мы только что отправили письмо на\n%s.\nНажмите на ссылку в нём, чтобы\nподтвердить свою учётную запись.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tap the link we emailed to you to verify your account", "button": { "open_email_app": "Открыть приложение почты", "resend": "Отправить заново" @@ -342,7 +345,11 @@ "offline": "Не в сети", "new_posts": "Показать новые", "published": "Опубликовано!", - "Publishing": "Публикуем пост..." + "Publishing": "Публикуем пост...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Followers from other servers are not displayed." }, "following": { + "title": "following", "footer": "Follows from other servers are not displayed." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Поиск", "search_bar": { @@ -596,7 +615,49 @@ "send": "Пожаловаться", "skip_to_send": "Отправить без комментария", "text_placeholder": "Дополнительные комментарии", - "reported": "REPORTED" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "Пока мы рассматриваем его, вот действия, которые вы можете предпринять лично против %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/ru_RU/ios-infoPlist.json b/Localization/StringsConvertor/input/ru.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/ru_RU/ios-infoPlist.json rename to Localization/StringsConvertor/input/ru.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/sv_SE/Localizable.stringsdict b/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict similarity index 89% rename from Localization/StringsConvertor/input/sv_SE/Localizable.stringsdict rename to Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict index a14b5f622..27ef9fb53 100644 --- a/Localization/StringsConvertor/input/sv_SE/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/sv.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld tecken + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Följs av %1$@ och en annan gemensam + other + Följs av %1$@ och %ld gemensamma + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ inläggen + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey @@ -157,7 +200,7 @@ NSStringFormatValueTypeKey ld one - %ld röst + %ld röstare other %ld röster @@ -317,7 +360,7 @@ NSStringFormatValueTypeKey ld one - %ldå sedan + %ld år sedan other %ldå sedan @@ -333,7 +376,7 @@ NSStringFormatValueTypeKey ld one - %ldmån sedan + %ld mån sedan other %ld mån sedan diff --git a/Localization/StringsConvertor/input/sv_SE/app.json b/Localization/StringsConvertor/input/sv.lproj/app.json similarity index 81% rename from Localization/StringsConvertor/input/sv_SE/app.json rename to Localization/StringsConvertor/input/sv.lproj/app.json index 4f93231ec..802c731ce 100644 --- a/Localization/StringsConvertor/input/sv_SE/app.json +++ b/Localization/StringsConvertor/input/sv.lproj/app.json @@ -23,13 +23,13 @@ "title": "Publicering misslyckades", "message": "Det gick inte att publicera inlägget.\nKontrollera din internetanslutning.", "attachments_message": { - "video_attach_with_photo": "Det går inte att bifoga en video till en status som redan innehåller bilder.", + "video_attach_with_photo": "Det går inte att bifoga en video till ett inlägg som redan innehåller bilder.", "more_than_one_video": "Det går inte att bifoga mer än en video." } }, "edit_profile_failure": { - "title": "Fel vid profilredigering", - "message": "Kan inte redigera profil. Försök igen." + "title": "Profilredigering misslyckades", + "message": "Kan inte redigera profil. Var god försök igen." }, "sign_out": { "title": "Logga ut", @@ -41,7 +41,7 @@ "block_entire_domain": "Blockera domän" }, "save_photo_failure": { - "title": "Kunde inte spara foto", + "title": "Spara foto misslyckades", "message": "Aktivera åtkomst till Bilder för att spara bilden." }, "delete_post": { @@ -57,7 +57,7 @@ "actions": { "back": "Tillbaka", "next": "Nästa", - "previous": "Tidigare", + "previous": "Föregående", "open": "Öppna", "add": "Lägg till", "remove": "Radera", @@ -69,7 +69,7 @@ "continue": "Fortsätt", "compose": "Skriv", "cancel": "Avbryt", - "discard": "Kasta", + "discard": "Släng", "try_again": "Försök igen", "take_photo": "Ta foto", "save_photo": "Spara foto", @@ -77,7 +77,7 @@ "sign_in": "Logga in", "sign_up": "Registrera dig", "see_more": "Visa mer", - "preview": "Förhandstitt", + "preview": "Förhandsvisa", "share": "Dela", "share_user": "Dela %s", "share_post": "Dela inlägg", @@ -96,7 +96,7 @@ "tabs": { "home": "Hem", "search": "Sök", - "notification": "Avisering", + "notification": "Notis", "profile": "Profil" }, "keyboard": { @@ -151,7 +151,7 @@ }, "tag": { "url": "URL", - "mention": "Nämn", + "mention": "Omnämn", "link": "Länk", "hashtag": "Hashtagg", "email": "E-post", @@ -161,13 +161,13 @@ "unlisted": "Alla kan se detta inlägg men det visas inte i den offentliga tidslinjen.", "private": "Endast deras följare kan se detta inlägg.", "private_from_me": "Bara mina följare kan se det här inlägget.", - "direct": "Endast nämnda användare kan se detta inlägg." + "direct": "Endast omnämnda användare kan se detta inlägg." } }, "friendship": { "follow": "Följ", "following": "Följer", - "request": "Begäran", + "request": "Följ", "pending": "Väntande", "block": "Blockera", "block_user": "Blockera %s", @@ -198,7 +198,7 @@ "user_blocking_warning": "Du kan inte visa %ss profil\nförrän du avblockerar dem.\nDin profil ser ut så här för dem.", "blocked_warning": "Du kan inte visa den här användarens profil\nförrän de avblockerar dig.", "user_blocked_warning": "Du kan inte visa %ss profil\nförrän de avblockerar dig.", - "suspended_warning": "Denna användare har stängts av.", + "suspended_warning": "Denna användare har blivit avstängd.", "user_suspended_warning": "%ss konto har blivit avstängt." } } @@ -211,9 +211,9 @@ "log_in": "Logga in" }, "server_picker": { - "title": "Mastodon utgörs av användare i olika gemenskaper.", - "subtitle": "Välj en gemenskap baserad på dina intressen, region eller ett allmänt syfte.", - "subtitle_extend": "Välj en gemenskap baserad på dina intressen, region eller ett allmänt syfte. Varje gemenskap drivs av en helt oberoende organisation eller individ.", + "title": "Mastodon utgörs av användare på olika servrar.", + "subtitle": "Välj en server baserat på dina intressen, region eller ett allmänt syfte.", + "subtitle_extend": "Välj en server baserat på dina intressen, region eller ett allmänt syfte. Varje server drivs av en helt oberoende organisation eller individ.", "button": { "category": { "all": "Alla", @@ -240,7 +240,8 @@ "category": "KATEGORI" }, "input": { - "placeholder": "Sök gemenskaper" + "placeholder": "Sök gemenskaper", + "search_servers_or_enter_url": "Sök servrar eller ange URL" }, "empty_state": { "finding_servers": "Söker tillgängliga servrar...", @@ -250,6 +251,7 @@ }, "register": { "title": "Låt oss få igång dig på %s", + "lets_get_you_set_up_on_domain": "Låt oss få igång dig på %s", "input": { "avatar": { "delete": "Radera" @@ -320,8 +322,9 @@ "confirm_email": { "title": "En sista sak.", "subtitle": "Tryck på länken vi e-postade till dig för att verifiera ditt konto.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Tryck på länken vi e-postade till dig för att verifiera ditt konto", "button": { - "open_email_app": "Öppna epostappen", + "open_email_app": "Öppna e-postappen", "resend": "Skicka igen" }, "dont_receive_email": { @@ -340,9 +343,13 @@ "title": "Hem", "navigation_bar_state": { "offline": "Offline", - "new_posts": "Se nya inlägg", - "published": "Publicerad!", - "Publishing": "Publicerar inlägget..." + "new_posts": "Nya inlägg", + "published": "Publicerat!", + "Publishing": "Publicerar inlägget...", + "accessibility": { + "logo_label": "Logo-knapp", + "logo_hint": "Tryck för att bläddra till toppen och tryck igen för föregående plats" + } } }, "suggestion_account": { @@ -370,11 +377,11 @@ "description_video": "Beskriv videon för de synskadade..." }, "poll": { - "duration_time": "Varaktighet: %s", + "duration_time": "Längd: %s", "thirty_minutes": "30 minuter", "one_hour": "1 timme", "six_hours": "6 timmar", - "one_day": "1dag", + "one_day": "1 dag", "three_days": "3 dagar", "seven_days": "7 dagar", "option_number": "Alternativ %ld" @@ -383,13 +390,13 @@ "placeholder": "Skriv en noggrann varning här..." }, "visibility": { - "public": "Publik", + "public": "Offentlig", "unlisted": "Olistad", "private": "Endast följare", "direct": "Bara personer jag nämner" }, "auto_complete": { - "space_to_add": "Mellanslag att lägga till" + "space_to_add": "Mellanslag för att lägga till" }, "accessibility": { "append_attachment": "Lägg till bilaga", @@ -401,8 +408,8 @@ "post_visibility_menu": "Inläggssynlighetsmeny" }, "keyboard": { - "discard_post": "Kasta inlägget", - "publish_post": "Publicerar inlägget", + "discard_post": "Släng inlägget", + "publish_post": "Publicera inlägget", "toggle_poll": "Växla omröstning", "toggle_content_warning": "Växla innehållsvarning", "append_attachment_entry": "Lägg till bilaga - %s", @@ -455,11 +462,23 @@ } }, "follower": { + "title": "följare", "footer": "Följare från andra servrar visas inte." }, "following": { + "title": "följer", "footer": "Följda på andra servrar visas inte." }, + "familiarFollowers": { + "title": "Följare du liknar", + "followed_by_names": "Följs av %s" + }, + "favorited_by": { + "title": "Favoriserad av" + }, + "reblogged_by": { + "title": "Ompostat av" + }, "search": { "title": "Sök", "search_bar": { @@ -498,7 +517,7 @@ "posts": "Inlägg", "hashtags": "Hashtaggar", "news": "Nyheter", - "community": "Gemenskap", + "community": "Server", "for_you": "För dig" }, "intro": "Detta är de inlägg som engagerar i ditt hörn av Mastodon." @@ -545,11 +564,11 @@ "light": "Ljust" }, "notifications": { - "title": "Aviseringar", + "title": "Notiser", "favorites": "Favoriserar mitt inlägg", "follows": "Följer mig", "boosts": "Ompostar mitt inlägg", - "mentions": "Nämner mig", + "mentions": "Omnämner mig", "trigger": { "anyone": "alla", "follower": "en följare", @@ -596,7 +615,49 @@ "send": "Skicka rapport", "skip_to_send": "Skicka utan kommentar", "text_placeholder": "Skriv eller klistra in ytterligare kommentarer", - "reported": "RAPPORTERAD" + "reported": "RAPPORTERAD", + "step_one": { + "step_1_of_4": "Steg 1 av 4", + "whats_wrong_with_this_post": "Vad är fel med det här inlägget?", + "whats_wrong_with_this_account": "Vad är fel med det här kontot?", + "whats_wrong_with_this_username": "Vad är fel med %s?", + "select_the_best_match": "Välj den bästa träffen", + "i_dont_like_it": "Jag tycker inte om det", + "it_is_not_something_you_want_to_see": "Det är inget som du vill se", + "its_spam": "Det är skräppost", + "malicious_links_fake_engagement_or_repetetive_replies": "Skadliga länkar, bedrägligt beteende eller repetitiva svar", + "it_violates_server_rules": "Det bryter mot serverns regler", + "you_are_aware_that_it_breaks_specific_rules": "Du är medveten om att det bryter mot specifika regler", + "its_something_else": "Det är något annat", + "the_issue_does_not_fit_into_other_categories": "Frågan passar inte in i andra kategorier" + }, + "step_two": { + "step_2_of_4": "Steg 2 av 4", + "which_rules_are_being_violated": "Vilka regler överträds?", + "select_all_that_apply": "Välj allt som stämmer", + "i_just_don’t_like_it": "Jag tycker bara inte om det" + }, + "step_three": { + "step_3_of_4": "Steg 3 av 4", + "are_there_any_posts_that_back_up_this_report": "Finns det några inlägg som stöder denna rapport?", + "select_all_that_apply": "Välj allt som stämmer" + }, + "step_four": { + "step_4_of_4": "Steg 4 av 4", + "is_there_anything_else_we_should_know": "Finns det något annat vi borde veta?" + }, + "step_final": { + "dont_want_to_see_this": "Vill du inte se det här?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "När du ser något som du inte gillar på Mastodon kan du ta bort personen från din upplevelse.", + "unfollow": "Avfölj", + "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.", + "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" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/sv_SE/ios-infoPlist.json b/Localization/StringsConvertor/input/sv.lproj/ios-infoPlist.json similarity index 88% rename from Localization/StringsConvertor/input/sv_SE/ios-infoPlist.json rename to Localization/StringsConvertor/input/sv.lproj/ios-infoPlist.json index 98ff6d3b6..6073413d8 100644 --- a/Localization/StringsConvertor/input/sv_SE/ios-infoPlist.json +++ b/Localization/StringsConvertor/input/sv.lproj/ios-infoPlist.json @@ -1,6 +1,6 @@ { "NSCameraUsageDescription": "Används för att ta foto till inlägg", - "NSPhotoLibraryAddUsageDescription": "Används för att spara foto till Bilder", + "NSPhotoLibraryAddUsageDescription": "Används för att spara foto till bildbiblioteket", "NewPostShortcutItemTitle": "Nytt inlägg", "SearchShortcutItemTitle": "Sök" } diff --git a/Localization/StringsConvertor/input/th_TH/Localizable.stringsdict b/Localization/StringsConvertor/input/th.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/th_TH/Localizable.stringsdict rename to Localization/StringsConvertor/input/th.lproj/Localizable.stringsdict index 8ae8feb7b..897d07eca 100644 --- a/Localization/StringsConvertor/input/th_TH/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/th.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld ตัวอักษร + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + ติดตามโดย %1$@ และ %ld ที่ร่วมกัน + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ โพสต์ + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld สื่อ + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/th_TH/app.json b/Localization/StringsConvertor/input/th.lproj/app.json similarity index 84% rename from Localization/StringsConvertor/input/th_TH/app.json rename to Localization/StringsConvertor/input/th.lproj/app.json index 50513e58e..97a00b41a 100644 --- a/Localization/StringsConvertor/input/th_TH/app.json +++ b/Localization/StringsConvertor/input/th.lproj/app.json @@ -211,20 +211,20 @@ "log_in": "เข้าสู่ระบบ" }, "server_picker": { - "title": "Mastodon ประกอบด้วยผู้ใช้ในชุมชนต่าง ๆ", - "subtitle": "เลือกชุมชนตามความสนใจ, ภูมิภาค หรือวัตถุประสงค์ทั่วไปของคุณ", - "subtitle_extend": "เลือกชุมชนตามความสนใจ, ภูมิภาค หรือวัตถุประสงค์ทั่วไปของคุณ แต่ละชุมชนดำเนินการโดยองค์กรหรือบุคคลที่เป็นอิสระโดยสิ้นเชิง", + "title": "Mastodon ประกอบด้วยผู้ใช้ในเซิร์ฟเวอร์ต่าง ๆ", + "subtitle": "เลือกเซิร์ฟเวอร์ตามความสนใจ, ภูมิภาค หรือวัตถุประสงค์ทั่วไปของคุณ", + "subtitle_extend": "เลือกเซิร์ฟเวอร์ตามความสนใจ, ภูมิภาค หรือวัตถุประสงค์ทั่วไปของคุณ แต่ละเซิร์ฟเวอร์ดำเนินการโดยองค์กรหรือบุคคลที่เป็นอิสระโดยสิ้นเชิง", "button": { "category": { "all": "ทั้งหมด", "all_accessiblity_description": "หมวดหมู่: ทั้งหมด", - "academia": "วิชาการ", + "academia": "สถาบันการศึกษา", "activism": "กิจกรรมเพื่อการเปลี่ยนแปลง", "food": "อาหาร", - "furry": "furry", + "furry": "สัตว์ขนยาว", "games": "เกม", "general": "ทั่วไป", - "journalism": "การเขียนข่าว", + "journalism": "วารสารศาสตร์", "lgbt": "lgbt", "regional": "ภูมิภาค", "art": "ศิลปะ", @@ -240,7 +240,8 @@ "category": "หมวดหมู่" }, "input": { - "placeholder": "ค้นหาชุมชน" + "placeholder": "ค้นหาเซิร์ฟเวอร์", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "กำลังค้นหาเซิร์ฟเวอร์ที่พร้อมใช้งาน...", @@ -250,6 +251,7 @@ }, "register": { "title": "มาตั้งค่าของคุณใน %s กันเลย", + "lets_get_you_set_up_on_domain": "มาตั้งค่าของคุณใน %s กันเลย", "input": { "avatar": { "delete": "ลบ" @@ -266,13 +268,13 @@ }, "password": { "placeholder": "รหัสผ่าน", - "require": "รหัสผ่านของคุณต้องมีอย่างน้อย:", + "require": "รหัสผ่านของคุณจำเป็นต้องมีอย่างน้อย:", "character_limit": "8 ตัวอักษร", "accessibility": { "checked": "กาเครื่องหมายแล้ว", "unchecked": "ไม่ได้กาเครื่องหมาย" }, - "hint": "รหัสผ่านของคุณต้องมีอย่างน้อยแปดตัวอักษร" + "hint": "รหัสผ่านของคุณจำเป็นต้องมีอย่างน้อยแปดตัวอักษร" }, "invite": { "registration_user_invite_request": "ทำไมคุณจึงต้องการเข้าร่วม?" @@ -293,7 +295,7 @@ "taken": "%s ถูกใช้งานแล้ว", "reserved": "%s เป็นคำสงวน", "accepted": "ต้องยอมรับ %s", - "blank": "ต้องมี %s", + "blank": "ต้องการ %s", "invalid": "%s ไม่ถูกต้อง", "too_long": "%s ยาวเกินไป", "too_short": "%s สั้นเกินไป", @@ -320,6 +322,7 @@ "confirm_email": { "title": "หนึ่งสิ่งสุดท้าย", "subtitle": "แตะลิงก์ที่เราส่งอีเมลถึงคุณเพื่อยืนยันบัญชีของคุณ", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "แตะลิงก์ที่เราส่งอีเมลถึงคุณเพื่อยืนยันบัญชีของคุณ", "button": { "open_email_app": "เปิดแอปอีเมล", "resend": "ส่งใหม่" @@ -342,7 +345,11 @@ "offline": "ออฟไลน์", "new_posts": "ดูโพสต์ใหม่", "published": "เผยแพร่แล้ว!", - "Publishing": "กำลังเผยแพร่โพสต์..." + "Publishing": "กำลังเผยแพร่โพสต์...", + "accessibility": { + "logo_label": "ปุ่มโลโก้", + "logo_hint": "แตะเพื่อเลื่อนไปยังด้านบนสุดและแตะอีกครั้งไปยังตำแหน่งที่ตั้งก่อนหน้า" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "ผู้ติดตาม", "footer": "ไม่ได้แสดงผู้ติดตามจากเซิร์ฟเวอร์อื่น ๆ" }, "following": { + "title": "กำลังติดตาม", "footer": "ไม่ได้แสดงการติดตามจากเซิร์ฟเวอร์อื่น ๆ" }, + "familiarFollowers": { + "title": "ผู้ติดตามที่คุณคุ้นเคย", + "followed_by_names": "ติดตามโดย %s" + }, + "favorited_by": { + "title": "ชื่นชอบโดย" + }, + "reblogged_by": { + "title": "ดันโดย" + }, "search": { "title": "ค้นหา", "search_bar": { @@ -498,7 +517,7 @@ "posts": "โพสต์", "hashtags": "แฮชแท็ก", "news": "ข่าว", - "community": "Community", + "community": "ชุมชน", "for_you": "สำหรับคุณ" }, "intro": "นี่คือโพสต์ที่กำลังได้รับความสนใจในมุมของ Mastodon ของคุณ" @@ -596,7 +615,49 @@ "send": "ส่งรายงาน", "skip_to_send": "ส่งโดยไม่มีความคิดเห็น", "text_placeholder": "พิมพ์หรือวางความคิดเห็นเพิ่มเติม", - "reported": "รายงานแล้ว" + "reported": "รายงานแล้ว", + "step_one": { + "step_1_of_4": "ขั้นตอนที่ 1 จาก 4", + "whats_wrong_with_this_post": "โพสต์นี้มีอะไรผิดปกติ?", + "whats_wrong_with_this_account": "บัญชีนี้มีอะไรผิดปกติ?", + "whats_wrong_with_this_username": "%s มีอะไรผิดปกติ?", + "select_the_best_match": "เลือกที่ตรงกันที่สุด", + "i_dont_like_it": "ฉันไม่ชอบโพสต์", + "it_is_not_something_you_want_to_see": "โพสต์ไม่ใช่บางอย่างที่คุณต้องการเห็น", + "its_spam": "โพสต์เป็นสแปม", + "malicious_links_fake_engagement_or_repetetive_replies": "ลิงก์ที่เป็นอันตราย, การมีส่วนร่วมปลอม หรือการตอบกลับซ้ำ ๆ", + "it_violates_server_rules": "โพสต์ละเมิดกฎของเซิร์ฟเวอร์", + "you_are_aware_that_it_breaks_specific_rules": "คุณทราบว่าโพสต์แหกกฎเฉพาะ", + "its_something_else": "โพสต์เป็นอย่างอื่น", + "the_issue_does_not_fit_into_other_categories": "ปัญหาไม่เข้าหมวดหมู่อื่น ๆ" + }, + "step_two": { + "step_2_of_4": "ขั้นตอนที่ 2 จาก 4", + "which_rules_are_being_violated": "กำลังละเมิดกฎใด?", + "select_all_that_apply": "เลือกทั้งหมดที่นำไปใช้", + "i_just_don’t_like_it": "ฉันแค่ไม่ชอบโพสต์" + }, + "step_three": { + "step_3_of_4": "ขั้นตอนที่ 3 จาก 4", + "are_there_any_posts_that_back_up_this_report": "มีโพสต์ใด ๆ ที่สนับสนุนรายงานนี้หรือไม่?", + "select_all_that_apply": "เลือกทั้งหมดที่นำไปใช้" + }, + "step_four": { + "step_4_of_4": "ขั้นตอนที่ 4 จาก 4", + "is_there_anything_else_we_should_know": "มีสิ่งอื่นใดที่เราควรทราบหรือไม่?" + }, + "step_final": { + "dont_want_to_see_this": "ไม่ต้องการเห็นสิ่งนี้?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "เมื่อคุณเห็นบางอย่างที่คุณไม่ชอบใน Mastodon คุณสามารถเอาบุคคลออกจากประสบการณ์ของคุณ", + "unfollow": "เลิกติดตาม", + "unfollowed": "เลิกติดตามแล้ว", + "unfollow_user": "เลิกติดตาม %s", + "mute_user": "ซ่อน %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "คุณจะไม่เห็นโพสต์หรือการดันของเขาในฟีดหน้าแรกของคุณ เขาจะไม่ทราบว่ามีการซ่อนเขา", + "block_user": "ปิดกั้น %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "เขาจะไม่สามารถติดตามหรือเห็นโพสต์ของคุณได้อีกต่อไป แต่เขาสามารถเห็นว่ามีการปิดกั้นเขาหรือไม่", + "while_we_review_this_you_can_take_action_against_user": "ขณะที่เราตรวจทานสิ่งนี้ คุณสามารถดำเนินการกับ %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/th_TH/ios-infoPlist.json b/Localization/StringsConvertor/input/th.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/th_TH/ios-infoPlist.json rename to Localization/StringsConvertor/input/th.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/tr_TR/Localizable.stringsdict b/Localization/StringsConvertor/input/tr.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/tr_TR/Localizable.stringsdict rename to Localization/StringsConvertor/input/tr.lproj/Localizable.stringsdict index d6817c1f6..3da12ee4e 100644 --- a/Localization/StringsConvertor/input/tr_TR/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/tr.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld karakter + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ gönderi + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/tr_TR/app.json b/Localization/StringsConvertor/input/tr.lproj/app.json similarity index 87% rename from Localization/StringsConvertor/input/tr_TR/app.json rename to Localization/StringsConvertor/input/tr.lproj/app.json index 9f41a72be..d377b5da1 100644 --- a/Localization/StringsConvertor/input/tr_TR/app.json +++ b/Localization/StringsConvertor/input/tr.lproj/app.json @@ -240,7 +240,8 @@ "category": "KATEGORİ" }, "input": { - "placeholder": "Toplulukları ara" + "placeholder": "Toplulukları ara", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Mevcut sunucular aranıyor...", @@ -250,6 +251,7 @@ }, "register": { "title": "%s için kurulumunuzu yapalım", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Sil" @@ -320,6 +322,7 @@ "confirm_email": { "title": "Son bir şey.", "subtitle": "Hesabınızı doğrulamak için size e-postayla gönderdiğimiz bağlantıya dokunun.", + "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": "E-posta Uygulamasını Aç", "resend": "Yeniden gönder" @@ -342,7 +345,11 @@ "offline": "Çevrimdışı", "new_posts": "Yeni gönderiler gör", "published": "Yayınlandı!", - "Publishing": "Gönderi yayınlanıyor..." + "Publishing": "Gönderi yayınlanıyor...", + "accessibility": { + "logo_label": "Logo Button", + "logo_hint": "Tap to scroll to top and tap again to previous location" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Diğer sunucudaki takipçiler gösterilemiyor." }, "following": { + "title": "following", "footer": "Diğer sunucudaki takip edilenler gösterilemiyor." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Arama", "search_bar": { @@ -498,7 +517,7 @@ "posts": "Gönderiler", "hashtags": "Etiketler", "news": "Haberler", - "community": "Community", + "community": "Topluluk", "for_you": "Senin İçin" }, "intro": "Bunlar, Mastodon'un köşesinde ilgi çeken gönderilerdir." @@ -538,7 +557,7 @@ "dark": "Daima Koyu" }, "look_and_feel": { - "title": "Look and Feel", + "title": "Görünüm", "use_system": "Sistem İle Aynı", "really_dark": "Gerçek Koyu", "sorta_dark": "Hafif Koyu", @@ -596,7 +615,49 @@ "send": "Raporu Gönder", "skip_to_send": "Yorum yapmadan gönder", "text_placeholder": "Ek yorum yazın veya yapıştırın", - "reported": "RAPORLANDI" + "reported": "RAPORLANDI", + "step_one": { + "step_1_of_4": "Adım 1/4", + "whats_wrong_with_this_post": "Bu gönderi ile ilgili sorun nedir?", + "whats_wrong_with_this_account": "Bu hesap ile ilgili sorun nedir?", + "whats_wrong_with_this_username": "%s kişisinin sorunu nedir?", + "select_the_best_match": "En iyi seçeneceği seçiniz", + "i_dont_like_it": "Beğenmedim", + "it_is_not_something_you_want_to_see": "Görmek isteyeceğim bir şey değil", + "its_spam": "Spam", + "malicious_links_fake_engagement_or_repetetive_replies": "Malicious links, fake engagement, or repetetive replies", + "it_violates_server_rules": "Sunucu kurallarını ihlal ediyor", + "you_are_aware_that_it_breaks_specific_rules": "You are aware that it breaks specific rules", + "its_something_else": "Başka bir şey", + "the_issue_does_not_fit_into_other_categories": "Sorun bunlardan biri değil" + }, + "step_two": { + "step_2_of_4": "Adım 2/4", + "which_rules_are_being_violated": "Hangi kurallar ihlal ediliyor?", + "select_all_that_apply": "Geçerli olan tümünü seçiniz", + "i_just_don’t_like_it": "Beğenmedim" + }, + "step_three": { + "step_3_of_4": "Adım 3/4", + "are_there_any_posts_that_back_up_this_report": "Bu bildirimi destekleyecek herhangi bir gönderi var mı?", + "select_all_that_apply": "Geçerli olanların tümünü seçiniz" + }, + "step_four": { + "step_4_of_4": "Adım 4/4", + "is_there_anything_else_we_should_know": "Bilmemiz gereken başka bir şey var mı?" + }, + "step_final": { + "dont_want_to_see_this": "Bunu görmek istemiyor musunuz?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "When you see something you don’t like on Mastodon, you can remove the person from your experience.", + "unfollow": "Takibi bırak", + "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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/tr_TR/ios-infoPlist.json b/Localization/StringsConvertor/input/tr.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/tr_TR/ios-infoPlist.json rename to Localization/StringsConvertor/input/tr.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/vi_VN/Localizable.stringsdict b/Localization/StringsConvertor/input/vi.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/vi_VN/Localizable.stringsdict rename to Localization/StringsConvertor/input/vi.lproj/Localizable.stringsdict index 71ba1951f..6905b240e 100644 --- a/Localization/StringsConvertor/input/vi_VN/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/vi.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld ký tự + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + Theo dõi bởi %1$@, và %ld người quen + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ tút + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/vi_VN/app.json b/Localization/StringsConvertor/input/vi.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/vi_VN/app.json rename to Localization/StringsConvertor/input/vi.lproj/app.json index 2a6c1a49b..58650a088 100644 --- a/Localization/StringsConvertor/input/vi_VN/app.json +++ b/Localization/StringsConvertor/input/vi.lproj/app.json @@ -240,7 +240,8 @@ "category": "PHÂN LOẠI" }, "input": { - "placeholder": "Tìm máy chủ" + "placeholder": "Tìm máy chủ", + "search_servers_or_enter_url": "Search servers or enter URL" }, "empty_state": { "finding_servers": "Đang tìm máy chủ hoạt động...", @@ -250,6 +251,7 @@ }, "register": { "title": "Hãy để tôi đăng ký trên %s", + "lets_get_you_set_up_on_domain": "Hãy để tôi đăng ký trên %s", "input": { "avatar": { "delete": "Xóa" @@ -320,6 +322,7 @@ "confirm_email": { "title": "Còn điều này nữa.", "subtitle": "Nhấn vào liên kết chúng tôi gửi qua email để xác thực tài khoản.", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "Nhấn vào liên kết chúng tôi gửi qua email để xác thực tài khoản", "button": { "open_email_app": "Mở ứng dụng email", "resend": "Gửi lại" @@ -342,7 +345,11 @@ "offline": "Ngoại tuyến", "new_posts": "Đọc những tút mới", "published": "Đã đăng!", - "Publishing": "Đang đăng tút..." + "Publishing": "Đang đăng tút...", + "accessibility": { + "logo_label": "Nút biểu tượng", + "logo_hint": "Nhấn để cuộn lên trên và nhấn lại lần nữa để trở về vị trí cũ" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "người theo dõi", "footer": "Không hiển thị người theo dõi từ máy chủ khác." }, "following": { + "title": "đang theo dõi", "footer": "Không hiển thị người bạn theo dõi từ máy chủ khác." }, + "familiarFollowers": { + "title": "Người theo dõi tương tự", + "followed_by_names": "Theo dõi bởi %s" + }, + "favorited_by": { + "title": "Thích bởi" + }, + "reblogged_by": { + "title": "Đăng lại bởi" + }, "search": { "title": "Tìm kiếm", "search_bar": { @@ -596,7 +615,49 @@ "send": "Gửi báo cáo", "skip_to_send": "Gửi không ghi chú", "text_placeholder": "Nhập hoặc bổ sung chú thích", - "reported": "ĐÃ BÁO CÁO" + "reported": "ĐÃ BÁO CÁO", + "step_one": { + "step_1_of_4": "Bước 1 trong 4", + "whats_wrong_with_this_post": "Có vấn đề gì với tút này?", + "whats_wrong_with_this_account": "Có vấn đề gì với người này?", + "whats_wrong_with_this_username": "Có vấn đề gì với %s?", + "select_the_best_match": "Chọn lý do khớp nhất", + "i_dont_like_it": "Tôi không thích nó", + "it_is_not_something_you_want_to_see": "Đó không phải là thứ gì mà bạn muốn thấy", + "its_spam": "Đây là spam", + "malicious_links_fake_engagement_or_repetetive_replies": "Liên kết độc hại, tạo tương tác giả hoặc trả lời lặp đi lặp lại", + "it_violates_server_rules": "Vi phạm quy tắc máy chủ", + "you_are_aware_that_it_breaks_specific_rules": "Bạn nhận thấy nó vi phạm quy tắc máy chủ", + "its_something_else": "Một lý do khác", + "the_issue_does_not_fit_into_other_categories": "Vấn đề không nằm trong những mục trên" + }, + "step_two": { + "step_2_of_4": "Bước 2 trong 4", + "which_rules_are_being_violated": "Vi phạm quy tắc nào?", + "select_all_that_apply": "Chọn tất cả những gì phù hợp", + "i_just_don’t_like_it": "Tôi không thích nó" + }, + "step_three": { + "step_3_of_4": "Bước 3 trong 4", + "are_there_any_posts_that_back_up_this_report": "Bạn muốn gửi tút nào kèm báo cáo này?", + "select_all_that_apply": "Chọn tất cả những gì phù hợp" + }, + "step_four": { + "step_4_of_4": "Bước 4 trong 4", + "is_there_anything_else_we_should_know": "Bạn nghĩ chúng tôi nên biết thêm điều gì?" + }, + "step_final": { + "dont_want_to_see_this": "Không muốn xem thứ này?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "Khi bạn thấy có gì đó mà bạn không thích trên Mastodon, bạn có thể tự loại bỏ chúng.", + "unfollow": "Ngưng theo dõi", + "unfollowed": "Ngưng theo dõi", + "unfollow_user": "Ngưng theo dõi %s", + "mute_user": "Ẩn %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "Bạn sẽ không thấy tút hoặc lượt đăng lại của họ trên bảng tin. Họ không biết rằng bạn ẩn họ.", + "block_user": "Chặn %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "Họ sẽ không thể theo dõi hoặc đọc tút của bạn, nhưng họ có thể hiểu bạn đã chặn họ.", + "while_we_review_this_you_can_take_action_against_user": "Trong lúc chờ chúng tôi xem xét, bạn có thể áp dụng hành động với @%s" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/vi_VN/ios-infoPlist.json b/Localization/StringsConvertor/input/vi.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/vi_VN/ios-infoPlist.json rename to Localization/StringsConvertor/input/vi.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/zh_CN/Localizable.stringsdict b/Localization/StringsConvertor/input/zh-Hans.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/zh_CN/Localizable.stringsdict rename to Localization/StringsConvertor/input/zh-Hans.lproj/Localizable.stringsdict index 6c2661ee5..5a7af3752 100644 --- a/Localization/StringsConvertor/input/zh_CN/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld 个字符 + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %1$@ 和你关注的另外 %ld 人也关注了这个账号 + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ 个帖子 + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld 个媒体 + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/zh_CN/app.json b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/zh_CN/app.json rename to Localization/StringsConvertor/input/zh-Hans.lproj/app.json index 2809b4c3b..3bc65e32c 100644 --- a/Localization/StringsConvertor/input/zh_CN/app.json +++ b/Localization/StringsConvertor/input/zh-Hans.lproj/app.json @@ -240,7 +240,8 @@ "category": "类别" }, "input": { - "placeholder": "查找或加入你自己的服务器..." + "placeholder": "查找或加入你自己的服务器...", + "search_servers_or_enter_url": "搜索服务器或输入 URL" }, "empty_state": { "finding_servers": "正在查找可用的服务器...", @@ -249,7 +250,8 @@ } }, "register": { - "title": "介绍一下你自己吧", + "title": "让我们在 %s 上开始", + "lets_get_you_set_up_on_domain": "让我们在 %s 上开始", "input": { "avatar": { "delete": "删除" @@ -319,7 +321,8 @@ }, "confirm_email": { "title": "最后一件事。", - "subtitle": "我们刚刚向 %s 发送了一封电子邮件,\n点击链接确认你的帐户。", + "subtitle": "点击我们发送给您的链接来验证您的账户。", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "点击我们发送给您的链接来验证您的账户。", "button": { "open_email_app": "打开电子邮件应用", "resend": "重新发送" @@ -342,7 +345,11 @@ "offline": "离线", "new_posts": "查看新帖子", "published": "已发送", - "Publishing": "正在发送..." + "Publishing": "正在发送...", + "accessibility": { + "logo_label": "Logo 按钮", + "logo_hint": "轻点滚到顶部,再次轻点回到原处" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "关注者", "footer": "不会显示来自其它服务器的关注者" }, "following": { + "title": "正在关注", "footer": "不会显示来自其它服务器的关注" }, + "familiarFollowers": { + "title": "你熟悉的关注者", + "followed_by_names": "%s 关注了这个账号" + }, + "favorited_by": { + "title": "收藏者" + }, + "reblogged_by": { + "title": "转发者" + }, "search": { "title": "搜索", "search_bar": { @@ -596,7 +615,49 @@ "send": "发送举报", "skip_to_send": "直接发送", "text_placeholder": "输入或粘贴额外的注释", - "reported": "已报告" + "reported": "已报告", + "step_one": { + "step_1_of_4": "第 1 步(共 4 步)", + "whats_wrong_with_this_post": "这个帖子有什么问题?", + "whats_wrong_with_this_account": "这个账户有什么问题?", + "whats_wrong_with_this_username": "%s 有什么问题?", + "select_the_best_match": "选择最佳匹配", + "i_dont_like_it": "我不喜欢它", + "it_is_not_something_you_want_to_see": "这不是你想看到的东西", + "its_spam": "它是垃圾信息", + "malicious_links_fake_engagement_or_repetetive_replies": "恶意链接、虚假参与或重复性回复", + "it_violates_server_rules": "它违反了服务器规则", + "you_are_aware_that_it_breaks_specific_rules": "你发现它违反了某个服务器规则", + "its_something_else": "其他原因", + "the_issue_does_not_fit_into_other_categories": "该问题属于其他类别" + }, + "step_two": { + "step_2_of_4": "第 2 步(共 4 步)", + "which_rules_are_being_violated": "哪些规则被违反了?", + "select_all_that_apply": "选择适用选项", + "i_just_don’t_like_it": "我不喜欢它" + }, + "step_three": { + "step_3_of_4": "第 3 步(共 4 步)", + "are_there_any_posts_that_back_up_this_report": "有任何帖子可以支持此报告吗?", + "select_all_that_apply": "选择适用选项" + }, + "step_four": { + "step_4_of_4": "第 4 步(共 4 步)", + "is_there_anything_else_we_should_know": "还有什么你认为我们应该知道的吗?" + }, + "step_final": { + "dont_want_to_see_this": "不想看到这个内容?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "当你在 Mastodon 看到不喜欢的东西时,可以尝试移除它。", + "unfollow": "取消关注", + "unfollowed": "已取消关注", + "unfollow_user": "取消关注 %s", + "mute_user": "静音 %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "你不会在主页里看到他们的帖子和转发。他们不会知道被静音了。", + "block_user": "屏蔽 %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "他们将不再能够关注或看到你的帖子,但他们可以知道他们是否被屏蔽。", + "while_we_review_this_you_can_take_action_against_user": "当我们审核这个报告时,你可以对 %s 采取行动。" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/zh_CN/ios-infoPlist.json b/Localization/StringsConvertor/input/zh-Hans.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/zh_CN/ios-infoPlist.json rename to Localization/StringsConvertor/input/zh-Hans.lproj/ios-infoPlist.json diff --git a/Localization/StringsConvertor/input/zh_TW/Localizable.stringsdict b/Localization/StringsConvertor/input/zh-Hant.lproj/Localizable.stringsdict similarity index 90% rename from Localization/StringsConvertor/input/zh_TW/Localizable.stringsdict rename to Localization/StringsConvertor/input/zh-Hant.lproj/Localizable.stringsdict index 0f28a8f6e..c0ce0f9a2 100644 --- a/Localization/StringsConvertor/input/zh_TW/Localizable.stringsdict +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld 個字 + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + 被 %1$@ 跟隨,%ld 個共同跟隨者 + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ 嘟文 + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld 個媒體 + + plural.count.post NSStringLocalizedFormatKey diff --git a/Localization/StringsConvertor/input/zh_TW/app.json b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json similarity index 86% rename from Localization/StringsConvertor/input/zh_TW/app.json rename to Localization/StringsConvertor/input/zh-Hant.lproj/app.json index 1fd5e2f00..cf910c43a 100644 --- a/Localization/StringsConvertor/input/zh_TW/app.json +++ b/Localization/StringsConvertor/input/zh-Hant.lproj/app.json @@ -240,7 +240,8 @@ "category": "分類" }, "input": { - "placeholder": "搜尋伺服器" + "placeholder": "搜尋伺服器", + "search_servers_or_enter_url": "搜尋伺服器或輸入網址" }, "empty_state": { "finding_servers": "尋找可用的伺服器...", @@ -250,6 +251,7 @@ }, "register": { "title": "讓我們一起設定 %s 吧!", + "lets_get_you_set_up_on_domain": "讓我們一起設定 %s 吧!", "input": { "avatar": { "delete": "刪除" @@ -320,6 +322,7 @@ "confirm_email": { "title": "最後一步。", "subtitle": "點擊我們寄送給您的帳號驗證連結。", + "tap_the_link_we_emailed_to_you_to_verify_your_account": "點擊我們寄送給您的帳號驗證連結", "button": { "open_email_app": "開啟電子郵件 App", "resend": "重新發送" @@ -342,7 +345,11 @@ "offline": "離線", "new_posts": "檢視最新嘟文", "published": "嘟出去!", - "Publishing": "發表嘟文..." + "Publishing": "發表嘟文...", + "accessibility": { + "logo_label": "標誌按鈕", + "logo_hint": "輕點一下捲至頂端並且再點ㄧ下回到原先位置" + } } }, "suggestion_account": { @@ -455,11 +462,23 @@ } }, "follower": { + "title": "跟隨者", "footer": "來自其他伺服器的跟隨者不會被顯示。" }, "following": { + "title": "跟隨中", "footer": "來自其他伺服器的跟隨中不會被顯示。" }, + "familiarFollowers": { + "title": "您熟悉的跟隨者", + "followed_by_names": "被 %s 跟隨" + }, + "favorited_by": { + "title": "已加入最愛" + }, + "reblogged_by": { + "title": "已轉嘟" + }, "search": { "title": "搜尋", "search_bar": { @@ -596,7 +615,49 @@ "send": "傳送檢舉報告", "skip_to_send": "不加入備註並傳送", "text_placeholder": "請輸入或貼上額外的備註", - "reported": "已檢舉" + "reported": "已檢舉", + "step_one": { + "step_1_of_4": "四個步驟中的第一步", + "whats_wrong_with_this_post": "這則嘟文有什麼問題嗎?", + "whats_wrong_with_this_account": "這個帳號有什麼問題嗎?", + "whats_wrong_with_this_username": "%s 有什麼問題嗎?", + "select_the_best_match": "選擇最佳條件符合", + "i_dont_like_it": "我不喜歡", + "it_is_not_something_you_want_to_see": "這是您不想看到的", + "its_spam": "垃圾訊息", + "malicious_links_fake_engagement_or_repetetive_replies": "有害連結、假造的互動,或是重複性回覆", + "it_violates_server_rules": "違反伺服器規則", + "you_are_aware_that_it_breaks_specific_rules": "您知道它違反特定規則", + "its_something_else": "其他原因", + "the_issue_does_not_fit_into_other_categories": "這個問題不屬於其他分類" + }, + "step_two": { + "step_2_of_4": "四個步驟中的第二步", + "which_rules_are_being_violated": "違反了哪些規則?", + "select_all_that_apply": "請選擇所有適用的選項", + "i_just_don’t_like_it": "就是不順眼" + }, + "step_three": { + "step_3_of_4": "四個步驟中的第三步", + "are_there_any_posts_that_back_up_this_report": "是否有能佐證這份檢舉之嘟文?", + "select_all_that_apply": "請選擇所有適用的選項" + }, + "step_four": { + "step_4_of_4": "四個步驟中的第四步", + "is_there_anything_else_we_should_know": "有什麼其他您想讓我們知道的嗎?" + }, + "step_final": { + "dont_want_to_see_this": "不想再看到這個?", + "when_you_see_something_you_dont_like_on_mastodon_you_can_remove_the_person_from_your_experience.": "當您看到某些不喜歡的內容時,您可以將該帳號從您的體驗中移除。", + "unfollow": "取消跟隨", + "unfollowed": "已取消跟隨", + "unfollow_user": "取消跟隨 %s", + "mute_user": "靜音 %s", + "you_wont_see_their_posts_or_reblogs_in_your_home_feed_they_wont_know_they_ve_been_muted": "您不會在您的首頁時間軸中再見到他們的嘟文或轉嘟。他們不會知道他們已被靜音。", + "block_user": "封鎖 %s", + "they_will_no_longer_be_able_to_follow_or_see_your_posts_but_they_can_see_if_theyve_been_blocked": "他們將無法跟隨您或是看到您的嘟文。他們能看到他們是否已被封鎖。", + "while_we_review_this_you_can_take_action_against_user": "當我們正在審核時,您可以對 %s 採取以下措施" + } }, "preview": { "keyboard": { diff --git a/Localization/StringsConvertor/input/zh_TW/ios-infoPlist.json b/Localization/StringsConvertor/input/zh-Hant.lproj/ios-infoPlist.json similarity index 100% rename from Localization/StringsConvertor/input/zh_TW/ios-infoPlist.json rename to Localization/StringsConvertor/input/zh-Hant.lproj/ios-infoPlist.json diff --git a/Localization/app.json b/Localization/app.json index 90b9b0fd8..7c50eba7f 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -240,7 +240,8 @@ "category": "CATEGORY" }, "input": { - "placeholder": "Search servers" + "placeholder": "Search servers", + "search_servers_or_enter_url": "Search communities or enter URL" }, "empty_state": { "finding_servers": "Finding available servers...", @@ -250,6 +251,7 @@ }, "register": { "title": "Let’s get you set up on %s", + "lets_get_you_set_up_on_domain": "Let’s get you set up on %s", "input": { "avatar": { "delete": "Delete" @@ -320,6 +322,7 @@ "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" @@ -347,7 +350,7 @@ "logo_label": "Logo Button", "logo_hint": "Tap to scroll to top and tap again to previous location" } - }, + } }, "suggestion_account": { "title": "Find People to Follow", @@ -459,11 +462,23 @@ } }, "follower": { + "title": "follower", "footer": "Followers from other servers are not displayed." }, "following": { + "title": "following", "footer": "Follows from other servers are not displayed." }, + "familiarFollowers": { + "title": "Followers you familiar", + "followed_by_names": "Followed by %s" + }, + "favorited_by": { + "title": "Favorited By" + }, + "reblogged_by": { + "title": "Reblogged By" + }, "search": { "title": "Search", "search_bar": { @@ -600,7 +615,49 @@ "send": "Send Report", "skip_to_send": "Send without comment", "text_placeholder": "Type or paste additional comments", - "reported": "REPORTED" + "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 don’t like it", + "it_is_not_something_you_want_to_see": "It is not something you want to see", + "its_spam": "It’s 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": "It’s 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_don’t_like_it": "I just don’t 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": "Don’t 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 don’t 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 won’t see their posts or reblogs in your home feed. They won’t know they’ve 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 they’ve been blocked.", + "while_we_review_this_you_can_take_action_against_user": "While we review this, you can take action against %s" + } }, "preview": { "keyboard": { diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index d5f5cbd79..2187fa0c5 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -12,7 +12,7 @@ 0F202201261326E6000C64BF /* HashtagTimelineViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F202200261326E6000C64BF /* HashtagTimelineViewModel.swift */; }; 0F20220726134DA4000C64BF /* HashtagTimelineViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F20220626134DA4000C64BF /* HashtagTimelineViewModel+Diffable.swift */; }; 0F202213261351F5000C64BF /* APIService+HashtagTimeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F202212261351F5000C64BF /* APIService+HashtagTimeline.swift */; }; - 0F20222D261457EE000C64BF /* HashtagTimelineViewModel+LoadOldestState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F20222C261457EE000C64BF /* HashtagTimelineViewModel+LoadOldestState.swift */; }; + 0F20222D261457EE000C64BF /* HashtagTimelineViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F20222C261457EE000C64BF /* HashtagTimelineViewModel+State.swift */; }; 0F20223926146553000C64BF /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F20223826146553000C64BF /* Array.swift */; }; 0FAA0FDF25E0B57E0017CCDE /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA0FDE25E0B57E0017CCDE /* WelcomeViewController.swift */; }; 0FAA101225E105390017CCDE /* PrimaryActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA101125E105390017CCDE /* PrimaryActionButton.swift */; }; @@ -87,7 +87,7 @@ 2DF123A725C3B0210020F248 /* ActiveLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF123A625C3B0210020F248 /* ActiveLabel.swift */; }; 2DF75BA725D10E1000694EC8 /* APIService+Favorite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF75BA625D10E1000694EC8 /* APIService+Favorite.swift */; }; 5B24BBDA262DB14800A9381B /* ReportViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBD7262DB14800A9381B /* ReportViewModel.swift */; }; - 5B24BBDB262DB14800A9381B /* ReportViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBD8262DB14800A9381B /* ReportViewModel+Diffable.swift */; }; + 5B24BBDB262DB14800A9381B /* ReportStatusViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBD8262DB14800A9381B /* ReportStatusViewModel+Diffable.swift */; }; 5B24BBE2262DB19100A9381B /* APIService+Report.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B24BBE1262DB19100A9381B /* APIService+Report.swift */; }; 5B90C45E262599800002E742 /* SettingsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B90C456262599800002E742 /* SettingsViewModel.swift */; }; 5B90C45F262599800002E742 /* SettingsToggleTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B90C459262599800002E742 /* SettingsToggleTableViewCell.swift */; }; @@ -286,11 +286,20 @@ DB4F097F26A03DA600D62E92 /* SearchHistoryFetchedResultController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4F097E26A03DA600D62E92 /* SearchHistoryFetchedResultController.swift */; }; DB4FFC2B269EC39600D62E92 /* SearchToSearchDetailViewControllerAnimatedTransitioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4FFC29269EC39600D62E92 /* SearchToSearchDetailViewControllerAnimatedTransitioning.swift */; }; DB4FFC2C269EC39600D62E92 /* SearchTransitionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB4FFC2A269EC39600D62E92 /* SearchTransitionController.swift */; }; - DB51D172262832380062B7A1 /* BlurHashDecode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB51D170262832380062B7A1 /* BlurHashDecode.swift */; }; - DB51D173262832380062B7A1 /* BlurHashEncode.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB51D171262832380062B7A1 /* BlurHashEncode.swift */; }; DB552D4F26BBD10C00E481F6 /* OrderedCollections in Frameworks */ = {isa = PBXBuildFile; productRef = DB552D4E26BBD10C00E481F6 /* OrderedCollections */; }; DB564BD3269F3B35001E39A7 /* StatusFilterService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB564BD2269F3B35001E39A7 /* StatusFilterService.swift */; }; DB59F10E25EF724F001F1DAB /* APIService+Poll.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB59F10D25EF724F001F1DAB /* APIService+Poll.swift */; }; + DB5B549A2833A60400DEF8B2 /* FamiliarFollowersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */; }; + DB5B549D2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */; }; + DB5B549F2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */; }; + DB5B54A12833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */; }; + DB5B54A32833BD1A00DEF8B2 /* UserListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A22833BD1A00DEF8B2 /* UserListViewModel.swift */; }; + DB5B54A62833BE0000DEF8B2 /* UserListViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A52833BE0000DEF8B2 /* UserListViewModel+State.swift */; }; + DB5B54A82833BFA500DEF8B2 /* FavoritedByViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54A72833BFA500DEF8B2 /* FavoritedByViewController.swift */; }; + DB5B54AB2833C12A00DEF8B2 /* RebloggedByViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54AA2833C12A00DEF8B2 /* RebloggedByViewController.swift */; }; + DB5B54AE2833C15F00DEF8B2 /* UserListViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54AD2833C15F00DEF8B2 /* UserListViewModel+Diffable.swift */; }; + DB5B54B02833C24200DEF8B2 /* FavoritedByViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54AF2833C24200DEF8B2 /* FavoritedByViewController+DataSourceProvider.swift */; }; + DB5B54B22833C24B00DEF8B2 /* RebloggedByViewController+DataSourceProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B54B12833C24B00DEF8B2 /* RebloggedByViewController+DataSourceProvider.swift */; }; DB5B7295273112B100081888 /* FollowingListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B7294273112B100081888 /* FollowingListViewController.swift */; }; DB5B7298273112C800081888 /* FollowingListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B7297273112C800081888 /* FollowingListViewModel.swift */; }; DB5B729C273113C200081888 /* FollowingListViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5B729B273113C200081888 /* FollowingListViewModel+Diffable.swift */; }; @@ -410,12 +419,12 @@ DB7A9F932818F33C0016AF98 /* MastodonServerRulesViewController+Debug.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7A9F922818F33C0016AF98 /* MastodonServerRulesViewController+Debug.swift */; }; DB7F48452620241000796008 /* ProfileHeaderViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB7F48442620241000796008 /* ProfileHeaderViewModel.swift */; }; DB8190C62601FF0400020C08 /* AttachmentContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8190C52601FF0400020C08 /* AttachmentContainerView.swift */; }; + DB848E33282B62A800A302CC /* ReportResultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB848E32282B62A800A302CC /* ReportResultView.swift */; }; DB852D1926FAEB6B00FC9D81 /* SidebarViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB852D1826FAEB6B00FC9D81 /* SidebarViewController.swift */; }; DB852D1C26FB021500FC9D81 /* RootSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB852D1B26FB021500FC9D81 /* RootSplitViewController.swift */; }; DB852D1F26FB037800FC9D81 /* SidebarViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB852D1E26FB037800FC9D81 /* SidebarViewModel.swift */; }; DB87D4452609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB87D4442609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift */; }; DB87D4512609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB87D4502609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift */; }; - DB894CC427A5490600684B74 /* BlurhashImageCacheService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB894CC327A5490600684B74 /* BlurhashImageCacheService.swift */; }; DB8AF52E25C13561002E6C99 /* ViewStateStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF52B25C13561002E6C99 /* ViewStateStore.swift */; }; DB8AF52F25C13561002E6C99 /* DocumentStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF52C25C13561002E6C99 /* DocumentStore.swift */; }; DB8AF53025C13561002E6C99 /* AppContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF52D25C13561002E6C99 /* AppContext.swift */; }; @@ -440,7 +449,7 @@ DB98337125C9443200AD9700 /* APIService+Authentication.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98337025C9443200AD9700 /* APIService+Authentication.swift */; }; DB98337F25C9452D00AD9700 /* APIService+APIError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98337E25C9452D00AD9700 /* APIService+APIError.swift */; }; DB98339C25C96DE600AD9700 /* APIService+Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98339B25C96DE600AD9700 /* APIService+Account.swift */; }; - DB98EB4727B0DFAA0082E365 /* ReportViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB4627B0DFAA0082E365 /* ReportViewModel+State.swift */; }; + DB98EB4727B0DFAA0082E365 /* ReportStatusViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB4627B0DFAA0082E365 /* ReportStatusViewModel+State.swift */; }; DB98EB4927B0F0CD0082E365 /* ReportStatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB4827B0F0CD0082E365 /* ReportStatusTableViewCell.swift */; }; DB98EB4C27B0F2BC0082E365 /* ReportStatusTableViewCell+ViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB4B27B0F2BC0082E365 /* ReportStatusTableViewCell+ViewModel.swift */; }; DB98EB5327B0F9890082E365 /* ReportHeadlineTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB5227B0F9890082E365 /* ReportHeadlineTableViewCell.swift */; }; @@ -451,7 +460,6 @@ DB98EB6027B10E150082E365 /* ReportCommentTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB5F27B10E150082E365 /* ReportCommentTableViewCell.swift */; }; DB98EB6227B215EB0082E365 /* ReportResultViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB6127B215EB0082E365 /* ReportResultViewController.swift */; }; DB98EB6527B216500082E365 /* ReportResultViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB6427B216500082E365 /* ReportResultViewModel.swift */; }; - DB98EB6727B216560082E365 /* ReportResultViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98EB6627B216560082E365 /* ReportResultViewModel+Diffable.swift */; }; 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 */; }; @@ -532,6 +540,7 @@ DBC6462826A1736300B0E31B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB427DDE25BAA00100D1B89D /* Assets.xcassets */; }; DBC7A672260C897100E57475 /* StatusContentWarningEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC7A671260C897100E57475 /* StatusContentWarningEditorView.swift */; }; DBC7A67C260DFADE00E57475 /* StatusPublishService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC7A67B260DFADE00E57475 /* StatusPublishService.swift */; }; + DBCA0EBC282BB38A0029E2B0 /* PageboyNavigateable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCA0EBB282BB38A0029E2B0 /* PageboyNavigateable.swift */; }; DBCBCBF4267CB070000F5B51 /* Decode85.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCBCBF3267CB070000F5B51 /* Decode85.swift */; }; DBCBCC0D2680B908000F5B51 /* HomeTimelinePreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCBCC0C2680B908000F5B51 /* HomeTimelinePreference.swift */; }; DBCBED1726132DB500B49291 /* UserTimelineViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCBED1626132DB500B49291 /* UserTimelineViewModel+Diffable.swift */; }; @@ -566,6 +575,14 @@ DBE3CE07261D6A0E00430CC6 /* FavoriteViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE3CE06261D6A0E00430CC6 /* FavoriteViewModel+Diffable.swift */; }; DBE54AC62636C89F004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; }; DBE54ACC2636C8FD004E7C0B /* NotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */; }; + DBEFCD71282A12B200C0ABEA /* ReportReasonViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBEFCD70282A12B200C0ABEA /* ReportReasonViewController.swift */; }; + DBEFCD74282A130400C0ABEA /* ReportReasonViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBEFCD73282A130400C0ABEA /* ReportReasonViewModel.swift */; }; + DBEFCD76282A143F00C0ABEA /* ReportStatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBEFCD75282A143F00C0ABEA /* ReportStatusViewController.swift */; }; + DBEFCD79282A147000C0ABEA /* ReportStatusViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBEFCD78282A147000C0ABEA /* ReportStatusViewModel.swift */; }; + DBEFCD7B282A162400C0ABEA /* ReportReasonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBEFCD7A282A162400C0ABEA /* ReportReasonView.swift */; }; + DBEFCD7D282A2A3B00C0ABEA /* ReportServerRulesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBEFCD7C282A2A3B00C0ABEA /* ReportServerRulesViewController.swift */; }; + DBEFCD80282A2AA900C0ABEA /* ReportServerRulesViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBEFCD7F282A2AA900C0ABEA /* ReportServerRulesViewModel.swift */; }; + DBEFCD82282A2AB100C0ABEA /* ReportServerRulesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBEFCD81282A2AB100C0ABEA /* ReportServerRulesView.swift */; }; DBF156DF2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF156DE2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift */; }; DBF156E22702DA6900EC00B7 /* UIStatusBarManager+HandleTapAction.m in Sources */ = {isa = PBXBuildFile; fileRef = DBF156E12702DA6900EC00B7 /* UIStatusBarManager+HandleTapAction.m */; }; DBF156E42702DB3F00EC00B7 /* HandleTapAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBF156E32702DB3F00EC00B7 /* HandleTapAction.swift */; }; @@ -709,7 +726,7 @@ 0F202200261326E6000C64BF /* HashtagTimelineViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineViewModel.swift; sourceTree = ""; }; 0F20220626134DA4000C64BF /* HashtagTimelineViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HashtagTimelineViewModel+Diffable.swift"; sourceTree = ""; }; 0F202212261351F5000C64BF /* APIService+HashtagTimeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+HashtagTimeline.swift"; sourceTree = ""; }; - 0F20222C261457EE000C64BF /* HashtagTimelineViewModel+LoadOldestState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HashtagTimelineViewModel+LoadOldestState.swift"; sourceTree = ""; }; + 0F20222C261457EE000C64BF /* HashtagTimelineViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HashtagTimelineViewModel+State.swift"; sourceTree = ""; }; 0F20223826146553000C64BF /* Array.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Array.swift; sourceTree = ""; }; 0FAA0FDE25E0B57E0017CCDE /* WelcomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeViewController.swift; sourceTree = ""; }; 0FAA101125E105390017CCDE /* PrimaryActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PrimaryActionButton.swift; sourceTree = ""; }; @@ -789,7 +806,7 @@ 459EA4F43058CAB47719E963 /* Pods-Mastodon-MastodonUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.debug.xcconfig"; sourceTree = ""; }; 46DAB0EBDDFB678347CD96FF /* Pods-MastodonTests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.asdk - release.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.asdk - release.xcconfig"; sourceTree = ""; }; 5B24BBD7262DB14800A9381B /* ReportViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReportViewModel.swift; sourceTree = ""; }; - 5B24BBD8262DB14800A9381B /* ReportViewModel+Diffable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ReportViewModel+Diffable.swift"; sourceTree = ""; }; + 5B24BBD8262DB14800A9381B /* ReportStatusViewModel+Diffable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ReportStatusViewModel+Diffable.swift"; sourceTree = ""; }; 5B24BBE1262DB19100A9381B /* APIService+Report.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "APIService+Report.swift"; sourceTree = ""; }; 5B90C456262599800002E742 /* SettingsViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewModel.swift; sourceTree = ""; }; 5B90C459262599800002E742 /* SettingsToggleTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsToggleTableViewCell.swift; sourceTree = ""; }; @@ -810,7 +827,10 @@ 5DDDF1A82617489F00311060 /* Mastodon+Entity+History.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Mastodon+Entity+History.swift"; sourceTree = ""; }; 5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AVPlayer.swift; sourceTree = ""; }; 6130CBE4B26E3C976ACC1688 /* Pods-ShareActionExtension.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareActionExtension.asdk - debug.xcconfig"; path = "Target Support Files/Pods-ShareActionExtension/Pods-ShareActionExtension.asdk - debug.xcconfig"; sourceTree = ""; }; + 63EF9E6E5B575CD2A8B0475D /* Pods-AppShared.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.profile.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.profile.xcconfig"; sourceTree = ""; }; + 728DE51ADA27C395C6E1BAB5 /* Pods-Mastodon-MastodonUITests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.profile.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.profile.xcconfig"; sourceTree = ""; }; 75E3471C898DDD9631729B6E /* Pods-Mastodon.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.release.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.release.xcconfig"; sourceTree = ""; }; + 7CB58D292DA7ACEF179A9050 /* Pods-Mastodon.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.profile.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.profile.xcconfig"; sourceTree = ""; }; 7CEFFAE9AF9284B13C0A758D /* Pods-MastodonTests.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.asdk - debug.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.asdk - debug.xcconfig"; sourceTree = ""; }; 819CEC9DCAD8E8E7BD85A7BB /* Pods-Mastodon.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk.xcconfig"; sourceTree = ""; }; 8850E70A1D5FF51432E43653 /* Pods-Mastodon-MastodonUITests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; sourceTree = ""; }; @@ -894,12 +914,6 @@ DB0FCB992797F7AD006C02E2 /* UserView+Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserView+Configuration.swift"; sourceTree = ""; }; DB0FCB9B27980AB6006C02E2 /* HashtagTimelineViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HashtagTimelineViewController+DataSourceProvider.swift"; sourceTree = ""; }; DB118A8125E4B6E600FAB162 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - DB126A4C278C063F005726EE /* eu-ES */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "eu-ES"; path = "eu-ES.lproj/Intents.strings"; sourceTree = ""; }; - DB126A4F278C063F005726EE /* eu-ES */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "eu-ES"; path = "eu-ES.lproj/InfoPlist.strings"; sourceTree = ""; }; - DB126A50278C063F005726EE /* eu-ES */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "eu-ES"; path = "eu-ES.lproj/Intents.stringsdict"; sourceTree = ""; }; - DB126A56278C088D005726EE /* sv-FI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sv-FI"; path = "sv-FI.lproj/Intents.strings"; sourceTree = ""; }; - DB126A59278C088D005726EE /* sv-FI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "sv-FI"; path = "sv-FI.lproj/InfoPlist.strings"; sourceTree = ""; }; - DB126A5A278C088D005726EE /* sv-FI */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "sv-FI"; path = "sv-FI.lproj/Intents.stringsdict"; sourceTree = ""; }; DB159C2A27A17BAC0068DC77 /* DataSourceFacade+Media.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Media.swift"; sourceTree = ""; }; DB1D186B25EF5BA7003F1F23 /* PollTableView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollTableView.swift; sourceTree = ""; }; DB1D61CE26F1B33600DA8662 /* WelcomeViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeViewModel.swift; sourceTree = ""; }; @@ -1001,11 +1015,7 @@ DB4B777F26CA4EFA00B087B3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Intents.strings; sourceTree = ""; }; DB4B778226CA4EFA00B087B3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/InfoPlist.strings; sourceTree = ""; }; DB4B778326CA4EFA00B087B3 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ru; path = ru.lproj/Intents.stringsdict; sourceTree = ""; }; - DB4B778426CA500E00B087B3 /* gd-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "gd-GB"; path = "gd-GB.lproj/Intents.strings"; sourceTree = ""; }; - DB4B778726CA500E00B087B3 /* gd-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "gd-GB"; path = "gd-GB.lproj/InfoPlist.strings"; sourceTree = ""; }; - DB4B778826CA500E00B087B3 /* gd-GB */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "gd-GB"; path = "gd-GB.lproj/Intents.stringsdict"; sourceTree = ""; }; DB4B778926CA504100B087B3 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = es; path = es.lproj/Intents.stringsdict; sourceTree = ""; }; - DB4B778A26CA504200B087B3 /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-419"; path = "es-419.lproj/Intents.stringsdict"; sourceTree = ""; }; DB4B778B26CA504300B087B3 /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ar; path = ar.lproj/Intents.stringsdict; sourceTree = ""; }; DB4B778C26CA504400B087B3 /* ca */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ca; path = ca.lproj/Intents.stringsdict; sourceTree = ""; }; DB4B778D26CA504500B087B3 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "zh-Hans"; path = "zh-Hans.lproj/Intents.stringsdict"; sourceTree = ""; }; @@ -1041,10 +1051,19 @@ DB519B15281BCC2F00F0C99D /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/Intents.strings; sourceTree = ""; }; DB519B16281BCC2F00F0C99D /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = tr; path = tr.lproj/InfoPlist.strings; sourceTree = ""; }; DB519B17281BCC2F00F0C99D /* tr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = tr; path = tr.lproj/Intents.stringsdict; sourceTree = ""; }; - DB51D170262832380062B7A1 /* BlurHashDecode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlurHashDecode.swift; sourceTree = ""; }; - DB51D171262832380062B7A1 /* BlurHashEncode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlurHashEncode.swift; sourceTree = ""; }; DB564BD2269F3B35001E39A7 /* StatusFilterService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusFilterService.swift; sourceTree = ""; }; DB59F10D25EF724F001F1DAB /* APIService+Poll.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Poll.swift"; sourceTree = ""; }; + DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FamiliarFollowersViewController.swift; sourceTree = ""; }; + DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FamiliarFollowersViewModel.swift; sourceTree = ""; }; + DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FamiliarFollowersViewModel+Diffable.swift"; sourceTree = ""; }; + DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FamiliarFollowersViewController+DataSourceProvider.swift"; sourceTree = ""; }; + DB5B54A22833BD1A00DEF8B2 /* UserListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserListViewModel.swift; sourceTree = ""; }; + DB5B54A52833BE0000DEF8B2 /* UserListViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserListViewModel+State.swift"; sourceTree = ""; }; + DB5B54A72833BFA500DEF8B2 /* FavoritedByViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FavoritedByViewController.swift; sourceTree = ""; }; + DB5B54AA2833C12A00DEF8B2 /* RebloggedByViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RebloggedByViewController.swift; sourceTree = ""; }; + DB5B54AD2833C15F00DEF8B2 /* UserListViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserListViewModel+Diffable.swift"; sourceTree = ""; }; + DB5B54AF2833C24200DEF8B2 /* FavoritedByViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FavoritedByViewController+DataSourceProvider.swift"; sourceTree = ""; }; + DB5B54B12833C24B00DEF8B2 /* RebloggedByViewController+DataSourceProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RebloggedByViewController+DataSourceProvider.swift"; sourceTree = ""; }; DB5B7294273112B100081888 /* FollowingListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingListViewController.swift; sourceTree = ""; }; DB5B7297273112C800081888 /* FollowingListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowingListViewModel.swift; sourceTree = ""; }; DB5B729B273113C200081888 /* FollowingListViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FollowingListViewModel+Diffable.swift"; sourceTree = ""; }; @@ -1162,12 +1181,12 @@ DB8190C52601FF0400020C08 /* AttachmentContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentContainerView.swift; sourceTree = ""; }; DB8481142788121200BBEABA /* MastodonRegisterTextFieldTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonRegisterTextFieldTableViewCell.swift; sourceTree = ""; }; DB84811627883C2600BBEABA /* MastodonRegisterPasswordHintTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonRegisterPasswordHintTableViewCell.swift; sourceTree = ""; }; + DB848E32282B62A800A302CC /* ReportResultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportResultView.swift; sourceTree = ""; }; DB852D1826FAEB6B00FC9D81 /* SidebarViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarViewController.swift; sourceTree = ""; }; DB852D1B26FB021500FC9D81 /* RootSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootSplitViewController.swift; sourceTree = ""; }; DB852D1E26FB037800FC9D81 /* SidebarViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarViewModel.swift; sourceTree = ""; }; DB87D4442609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeStatusPollOptionCollectionViewCell.swift; sourceTree = ""; }; DB87D4502609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeStatusPollOptionAppendEntryCollectionViewCell.swift; sourceTree = ""; }; - DB894CC327A5490600684B74 /* BlurhashImageCacheService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurhashImageCacheService.swift; sourceTree = ""; }; DB89BA1025C10FF5008580ED /* Mastodon.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Mastodon.entitlements; sourceTree = ""; }; DB8AF52B25C13561002E6C99 /* ViewStateStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewStateStore.swift; sourceTree = ""; }; DB8AF52C25C13561002E6C99 /* DocumentStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DocumentStore.swift; sourceTree = ""; }; @@ -1179,6 +1198,9 @@ DB8D8E3128196FA0009FD90F /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/Intents.strings; sourceTree = ""; }; DB8D8E3228196FA0009FD90F /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = sv; path = sv.lproj/InfoPlist.strings; sourceTree = ""; }; DB8D8E3328196FA0009FD90F /* sv */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = sv; path = sv.lproj/Intents.stringsdict; sourceTree = ""; }; + DB8F40042835EE5E006E7513 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/Intents.strings; sourceTree = ""; }; + DB8F40052835EE5E006E7513 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fi; path = fi.lproj/InfoPlist.strings; sourceTree = ""; }; + DB8F40062835EE5E006E7513 /* fi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = fi; path = fi.lproj/Intents.stringsdict; sourceTree = ""; }; DB8F7075279E954700E1225B /* DataSourceFacade+Follow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Follow.swift"; sourceTree = ""; }; DB8FAB9E26AEC3A2008E5AF4 /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; }; DB8FABA926AEC3A2008E5AF4 /* IntentsUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IntentsUI.framework; path = System/Library/Frameworks/IntentsUI.framework; sourceTree = SDKROOT; }; @@ -1199,7 +1221,7 @@ DB98337025C9443200AD9700 /* APIService+Authentication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Authentication.swift"; sourceTree = ""; }; DB98337E25C9452D00AD9700 /* APIService+APIError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "APIService+APIError.swift"; sourceTree = ""; }; DB98339B25C96DE600AD9700 /* APIService+Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Account.swift"; sourceTree = ""; }; - DB98EB4627B0DFAA0082E365 /* ReportViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ReportViewModel+State.swift"; sourceTree = ""; }; + DB98EB4627B0DFAA0082E365 /* ReportStatusViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ReportStatusViewModel+State.swift"; sourceTree = ""; }; DB98EB4827B0F0CD0082E365 /* ReportStatusTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportStatusTableViewCell.swift; sourceTree = ""; }; DB98EB4B27B0F2BC0082E365 /* ReportStatusTableViewCell+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ReportStatusTableViewCell+ViewModel.swift"; sourceTree = ""; }; DB98EB5227B0F9890082E365 /* ReportHeadlineTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportHeadlineTableViewCell.swift; sourceTree = ""; }; @@ -1210,7 +1232,6 @@ DB98EB5F27B10E150082E365 /* ReportCommentTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportCommentTableViewCell.swift; sourceTree = ""; }; DB98EB6127B215EB0082E365 /* ReportResultViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportResultViewController.swift; sourceTree = ""; }; DB98EB6427B216500082E365 /* ReportResultViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportResultViewModel.swift; sourceTree = ""; }; - DB98EB6627B216560082E365 /* ReportResultViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ReportResultViewModel+Diffable.swift"; sourceTree = ""; }; DB98EB6827B21A7C0082E365 /* ReportResultActionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportResultActionTableViewCell.swift; sourceTree = ""; }; DB98EB6A27B243470082E365 /* SettingsAppearanceTableViewCell+ViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SettingsAppearanceTableViewCell+ViewModel.swift"; sourceTree = ""; }; DB9A486B26032AC1008B817C /* AttachmentContainerView+EmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AttachmentContainerView+EmptyStateView.swift"; sourceTree = ""; }; @@ -1237,8 +1258,6 @@ DBA4B0DE26BD11130077136E /* fr */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/InfoPlist.strings; sourceTree = ""; }; DBA4B0DF26BD11C70077136E /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Intents.strings; sourceTree = ""; }; DBA4B0E226BD11C80077136E /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/InfoPlist.strings; sourceTree = ""; }; - DBA4B0E326BD11D10077136E /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/Intents.strings"; sourceTree = ""; }; - DBA4B0E626BD11D10077136E /* es-419 */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-419"; path = "es-419.lproj/InfoPlist.strings"; sourceTree = ""; }; DBA4B0E826C153820077136E /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Intents.strings; sourceTree = ""; }; DBA4B0EB26C153820077136E /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = ""; }; DBA4B0EC26C153B10077136E /* nl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nl; path = nl.lproj/Intents.strings; sourceTree = ""; }; @@ -1296,6 +1315,16 @@ DBC6462226A1712000B0E31B /* ShareViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareViewModel.swift; sourceTree = ""; }; DBC7A671260C897100E57475 /* StatusContentWarningEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusContentWarningEditorView.swift; sourceTree = ""; }; DBC7A67B260DFADE00E57475 /* StatusPublishService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusPublishService.swift; sourceTree = ""; }; + DBC9E3A3282E13BB0063A4D9 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/Intents.strings; sourceTree = ""; }; + DBC9E3A4282E13BB0063A4D9 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = eu; path = eu.lproj/InfoPlist.strings; sourceTree = ""; }; + DBC9E3A5282E13BB0063A4D9 /* eu */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = eu; path = eu.lproj/Intents.stringsdict; sourceTree = ""; }; + DBC9E3A6282E15190063A4D9 /* gd */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gd; path = gd.lproj/Intents.strings; sourceTree = ""; }; + DBC9E3A7282E15190063A4D9 /* gd */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = gd; path = gd.lproj/InfoPlist.strings; sourceTree = ""; }; + DBC9E3A8282E15190063A4D9 /* gd */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = gd; path = gd.lproj/Intents.stringsdict; sourceTree = ""; }; + DBC9E3A9282E17DF0063A4D9 /* es-AR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-AR"; path = "es-AR.lproj/Intents.strings"; sourceTree = ""; }; + DBC9E3AA282E17DF0063A4D9 /* es-AR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-AR"; path = "es-AR.lproj/InfoPlist.strings"; sourceTree = ""; }; + DBC9E3AB282E17DF0063A4D9 /* es-AR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = "es-AR"; path = "es-AR.lproj/Intents.stringsdict"; sourceTree = ""; }; + DBCA0EBB282BB38A0029E2B0 /* PageboyNavigateable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageboyNavigateable.swift; sourceTree = ""; }; DBCBCBF3267CB070000F5B51 /* Decode85.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Decode85.swift; sourceTree = ""; }; DBCBCC0C2680B908000F5B51 /* HomeTimelinePreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelinePreference.swift; sourceTree = ""; }; DBCBED1626132DB500B49291 /* UserTimelineViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UserTimelineViewModel+Diffable.swift"; sourceTree = ""; }; @@ -1329,6 +1358,14 @@ DBEB19E927E4F37B00B0E80E /* ku */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ku; path = ku.lproj/Intents.strings; sourceTree = ""; }; DBEB19EA27E4F37B00B0E80E /* ku */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ku; path = ku.lproj/InfoPlist.strings; sourceTree = ""; }; DBEB19EB27E4F37B00B0E80E /* ku */ = {isa = PBXFileReference; lastKnownFileType = text.plist.stringsdict; name = ku; path = ku.lproj/Intents.stringsdict; sourceTree = ""; }; + DBEFCD70282A12B200C0ABEA /* ReportReasonViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportReasonViewController.swift; sourceTree = ""; }; + DBEFCD73282A130400C0ABEA /* ReportReasonViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportReasonViewModel.swift; sourceTree = ""; }; + DBEFCD75282A143F00C0ABEA /* ReportStatusViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportStatusViewController.swift; sourceTree = ""; }; + DBEFCD78282A147000C0ABEA /* ReportStatusViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportStatusViewModel.swift; sourceTree = ""; }; + DBEFCD7A282A162400C0ABEA /* ReportReasonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportReasonView.swift; sourceTree = ""; }; + DBEFCD7C282A2A3B00C0ABEA /* ReportServerRulesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportServerRulesViewController.swift; sourceTree = ""; }; + DBEFCD7F282A2AA900C0ABEA /* ReportServerRulesViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportServerRulesViewModel.swift; sourceTree = ""; }; + DBEFCD81282A2AB100C0ABEA /* ReportServerRulesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportServerRulesView.swift; sourceTree = ""; }; DBF156DE2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarAddAccountCollectionViewCell.swift; sourceTree = ""; }; DBF156E02702DA6800EC00B7 /* Mastodon-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Mastodon-Bridging-Header.h"; sourceTree = ""; }; DBF156E12702DA6900EC00B7 /* UIStatusBarManager+HandleTapAction.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIStatusBarManager+HandleTapAction.m"; sourceTree = ""; }; @@ -1369,6 +1406,7 @@ DBFEF07226A6913D006D7ED1 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = ""; }; DBFEF07A26A6BCE8006D7ED1 /* APIService+Status+Publish.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Status+Publish.swift"; sourceTree = ""; }; 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 = ""; }; + 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 = ""; }; 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 = ""; }; E9AABD3D26B64B8C00E237DA /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Intents.strings; sourceTree = ""; }; E9AABD4026B64B8D00E237DA /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -1476,7 +1514,7 @@ DB0FCB9B27980AB6006C02E2 /* HashtagTimelineViewController+DataSourceProvider.swift */, 0F202200261326E6000C64BF /* HashtagTimelineViewModel.swift */, 0F20220626134DA4000C64BF /* HashtagTimelineViewModel+Diffable.swift */, - 0F20222C261457EE000C64BF /* HashtagTimelineViewModel+LoadOldestState.swift */, + 0F20222C261457EE000C64BF /* HashtagTimelineViewModel+State.swift */, ); path = HashtagTimeline; sourceTree = ""; @@ -1571,6 +1609,10 @@ 0655B257371274BEB7EB1C19 /* Pods-Mastodon.release snapshot.xcconfig */, 0827D1674B2523503E8605F6 /* Pods-Mastodon-MastodonUITests.release snapshot.xcconfig */, 8E79CCBE51FBC3F7FE8CF49F /* Pods-MastodonTests.release snapshot.xcconfig */, + 63EF9E6E5B575CD2A8B0475D /* Pods-AppShared.profile.xcconfig */, + 7CB58D292DA7ACEF179A9050 /* Pods-Mastodon.profile.xcconfig */, + 728DE51ADA27C395C6E1BAB5 /* Pods-Mastodon-MastodonUITests.profile.xcconfig */, + DF65937EC1FF64462BC002EE /* Pods-MastodonTests.profile.xcconfig */, ); path = Pods; sourceTree = ""; @@ -1665,8 +1707,6 @@ isa = PBXGroup; children = ( 2D5A3D0225CF8742002347D6 /* ControlContainableScrollViews.swift */, - DB51D170262832380062B7A1 /* BlurHashDecode.swift */, - DB51D171262832380062B7A1 /* BlurHashEncode.swift */, DB6180EC26391C6C0018D199 /* TransitioningMath.swift */, DB75BF1D263C1C1B00EDBF1F /* CustomScheduler.swift */, DBF156E32702DB3F00EC00B7 /* HandleTapAction.swift */, @@ -1692,7 +1732,6 @@ DB297B1A2679FAE200704C90 /* PlaceholderImageCacheService.swift */, DB564BD2269F3B35001E39A7 /* StatusFilterService.swift */, DB73BF42271192BB00781945 /* InstanceService.swift */, - DB894CC327A5490600684B74 /* BlurhashImageCacheService.swift */, ); path = Service; sourceTree = ""; @@ -1706,6 +1745,7 @@ DB4AA6B227BA34B6009EC082 /* CellFrameCacheContainer.swift */, 2D38F20725CD491300561493 /* DisposeBagCollectable.swift */, DB1D84372657B275000346B3 /* SegmentedControlNavigateable.swift */, + DBCA0EBB282BB38A0029E2B0 /* PageboyNavigateable.swift */, DB1D843326579931000346B3 /* TableViewControllerNavigateable.swift */, DB1D842D26552C4D000346B3 /* StatusTableViewControllerNavigateable.swift */, ); @@ -1842,6 +1882,9 @@ isa = PBXGroup; children = ( DB98EB5727B0FF1F0082E365 /* Share */, + DBEFCD77282A144D00C0ABEA /* Report */, + DBEFCD72282A12B900C0ABEA /* ReportReason */, + DBEFCD7E282A2A3D00C0ABEA /* ReportServerRules */, DB98EB4F27B0F9300082E365 /* ReportStatus */, DB98EB5A27B109900082E365 /* ReportSupplementary */, DB98EB6327B216490082E365 /* ReportResult */, @@ -2208,8 +2251,8 @@ DB427DD425BAA00100D1B89D /* Mastodon */ = { isa = PBXGroup; children = ( - DB427DE325BAA00100D1B89D /* Info.plist */, DB89BA1025C10FF5008580ED /* Mastodon.entitlements */, + DB427DE325BAA00100D1B89D /* Info.plist */, 2D76319C25C151DE00929FB9 /* Diffiable */, DB8AF52A25C13561002E6C99 /* State */, 2D61335525C1886800CAE157 /* Service */, @@ -2425,6 +2468,47 @@ path = View; sourceTree = ""; }; + DB5B549B2833A60600DEF8B2 /* FamiliarFollowers */ = { + isa = PBXGroup; + children = ( + DB5B54992833A60400DEF8B2 /* FamiliarFollowersViewController.swift */, + DB5B54A02833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift */, + DB5B549C2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift */, + DB5B549E2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift */, + ); + path = FamiliarFollowers; + sourceTree = ""; + }; + DB5B54A42833BD1D00DEF8B2 /* UserLIst */ = { + isa = PBXGroup; + children = ( + DB5B54A22833BD1A00DEF8B2 /* UserListViewModel.swift */, + DB5B54AD2833C15F00DEF8B2 /* UserListViewModel+Diffable.swift */, + DB5B54A52833BE0000DEF8B2 /* UserListViewModel+State.swift */, + DB5B54A92833BFAC00DEF8B2 /* FavoritedBy */, + DB5B54AC2833C12D00DEF8B2 /* RebloggedBy */, + ); + path = UserLIst; + sourceTree = ""; + }; + DB5B54A92833BFAC00DEF8B2 /* FavoritedBy */ = { + isa = PBXGroup; + children = ( + DB5B54A72833BFA500DEF8B2 /* FavoritedByViewController.swift */, + DB5B54AF2833C24200DEF8B2 /* FavoritedByViewController+DataSourceProvider.swift */, + ); + path = FavoritedBy; + sourceTree = ""; + }; + DB5B54AC2833C12D00DEF8B2 /* RebloggedBy */ = { + isa = PBXGroup; + children = ( + DB5B54AA2833C12A00DEF8B2 /* RebloggedByViewController.swift */, + DB5B54B12833C24B00DEF8B2 /* RebloggedByViewController+DataSourceProvider.swift */, + ); + path = RebloggedBy; + sourceTree = ""; + }; DB5B7296273112B400081888 /* Following */ = { isa = PBXGroup; children = ( @@ -2850,10 +2934,10 @@ DB98EB4F27B0F9300082E365 /* ReportStatus */ = { isa = PBXGroup; children = ( - 5BB04FD4262E7AFF0043BFF6 /* ReportViewController.swift */, - 5B24BBD7262DB14800A9381B /* ReportViewModel.swift */, - 5B24BBD8262DB14800A9381B /* ReportViewModel+Diffable.swift */, - DB98EB4627B0DFAA0082E365 /* ReportViewModel+State.swift */, + DBEFCD75282A143F00C0ABEA /* ReportStatusViewController.swift */, + DBEFCD78282A147000C0ABEA /* ReportStatusViewModel.swift */, + 5B24BBD8262DB14800A9381B /* ReportStatusViewModel+Diffable.swift */, + DB98EB4627B0DFAA0082E365 /* ReportStatusViewModel+State.swift */, ); path = ReportStatus; sourceTree = ""; @@ -2882,7 +2966,7 @@ children = ( DB98EB6127B215EB0082E365 /* ReportResultViewController.swift */, DB98EB6427B216500082E365 /* ReportResultViewModel.swift */, - DB98EB6627B216560082E365 /* ReportResultViewModel+Diffable.swift */, + DB848E32282B62A800A302CC /* ReportResultView.swift */, ); path = ReportResult; sourceTree = ""; @@ -2926,6 +3010,8 @@ DBE3CDF1261C6B3100430CC6 /* Favorite */, DB6B74F0272FB55400C70B6E /* Follower */, DB5B7296273112B400081888 /* Following */, + DB5B549B2833A60600DEF8B2 /* FamiliarFollowers */, + DB5B54A42833BD1D00DEF8B2 /* UserLIst */, DBFEEC97279BDC6A004F81DD /* About */, DB9D6BFE25E4F5940051B173 /* ProfileViewController.swift */, DBB5255D2611F07A002F1F29 /* ProfileViewModel.swift */, @@ -3177,6 +3263,35 @@ path = Favorite; sourceTree = ""; }; + DBEFCD72282A12B900C0ABEA /* ReportReason */ = { + isa = PBXGroup; + children = ( + DBEFCD70282A12B200C0ABEA /* ReportReasonViewController.swift */, + DBEFCD73282A130400C0ABEA /* ReportReasonViewModel.swift */, + DBEFCD7A282A162400C0ABEA /* ReportReasonView.swift */, + ); + path = ReportReason; + sourceTree = ""; + }; + DBEFCD77282A144D00C0ABEA /* Report */ = { + isa = PBXGroup; + children = ( + 5BB04FD4262E7AFF0043BFF6 /* ReportViewController.swift */, + 5B24BBD7262DB14800A9381B /* ReportViewModel.swift */, + ); + path = Report; + sourceTree = ""; + }; + DBEFCD7E282A2A3D00C0ABEA /* ReportServerRules */ = { + isa = PBXGroup; + children = ( + DBEFCD7C282A2A3B00C0ABEA /* ReportServerRulesViewController.swift */, + DBEFCD7F282A2AA900C0ABEA /* ReportServerRulesViewModel.swift */, + DBEFCD81282A2AB100C0ABEA /* ReportServerRulesView.swift */, + ); + path = ReportServerRules; + sourceTree = ""; + }; DBF1D24F269DAF6100C1C08A /* SearchDetail */ = { isa = PBXGroup; children = ( @@ -3518,14 +3633,10 @@ ca, fr, es, - "es-419", de, nl, ru, - "gd-GB", th, - "eu-ES", - "sv-FI", ku, kab, vi, @@ -3535,6 +3646,10 @@ gl, it, tr, + eu, + gd, + "es-AR", + fi, ); mainGroup = DB427DC925BAA00100D1B89D; packageReferences = ( @@ -3818,6 +3933,7 @@ buildActionMask = 2147483647; files = ( DBB525212611EBD6002F1F29 /* ProfilePagingViewController.swift in Sources */, + DB5B54A82833BFA500DEF8B2 /* FavoritedByViewController.swift in Sources */, DBDFF19E2805703700557A48 /* DiscoveryPostsViewController+DataSourceProvider.swift in Sources */, DB6180EB26391C140018D199 /* MediaPreviewTransitionItem.swift in Sources */, DB63F74727990B0600455B82 /* DataSourceFacade+Hashtag.swift in Sources */, @@ -3828,6 +3944,7 @@ DB1D843426579931000346B3 /* TableViewControllerNavigateable.swift in Sources */, 0FAA0FDF25E0B57E0017CCDE /* WelcomeViewController.swift in Sources */, DB65C63727A2AF6C008BAC2E /* ReportItem.swift in Sources */, + DB5B54B22833C24B00DEF8B2 /* RebloggedByViewController+DataSourceProvider.swift in Sources */, 2D59819B25E4A581000FB903 /* MastodonConfirmEmailViewController.swift in Sources */, DB45FB1D25CA9D23005A8AC7 /* APIService+HomeTimeline.swift in Sources */, DBA94440265D137600C537E1 /* Mastodon+Entity+Field.swift in Sources */, @@ -3842,6 +3959,7 @@ 0FB3D2F725E4C24D00AAD544 /* MastodonPickServerViewModel.swift in Sources */, 2D61335E25C1894B00CAE157 /* APIService.swift in Sources */, 2D9DB967263A76FB007C1D71 /* BlockDomainService.swift in Sources */, + DB5B54AE2833C15F00DEF8B2 /* UserListViewModel+Diffable.swift in Sources */, DB336F43278EB1690031E64B /* MediaView+Configuration.swift in Sources */, DB66729625F9F91600D60309 /* ComposeStatusSection.swift in Sources */, DB482A3F261331E8008AE74C /* UserTimelineViewModel+State.swift in Sources */, @@ -3873,6 +3991,7 @@ 2D364F7225E66D7500204FDC /* MastodonResendEmailViewController.swift in Sources */, DB68A06325E905E000CFDF14 /* UIApplication.swift in Sources */, DB02CDAB26256A9500D0A2AF /* ThreadReplyLoaderTableViewCell.swift in Sources */, + DBEFCD80282A2AA900C0ABEA /* ReportServerRulesViewModel.swift in Sources */, DB0617FF27855D6C0030EE79 /* MastodonServerRulesViewModel+Diffable.swift in Sources */, DBB5255E2611F07A002F1F29 /* ProfileViewModel.swift in Sources */, DB0FCB982797F6BF006C02E2 /* UserTableViewCell+ViewModel.swift in Sources */, @@ -3894,12 +4013,15 @@ 5DDDF1932617442700311060 /* Mastodon+Entity+Account.swift in Sources */, DB63F767279A5EB300455B82 /* NotificationTimelineViewModel.swift in Sources */, 2D607AD826242FC500B70763 /* NotificationViewModel.swift in Sources */, + DB5B54AB2833C12A00DEF8B2 /* RebloggedByViewController.swift in Sources */, + DB848E33282B62A800A302CC /* ReportResultView.swift in Sources */, DBABE3EC25ECAC4B00879EE5 /* WelcomeIllustrationView.swift in Sources */, DB564BD3269F3B35001E39A7 /* StatusFilterService.swift in Sources */, DB0FCB9C27980AB6006C02E2 /* HashtagTimelineViewController+DataSourceProvider.swift in Sources */, DB63F76F279A7D1100455B82 /* NotificationTableViewCell.swift in Sources */, DB297B1B2679FAE200704C90 /* PlaceholderImageCacheService.swift in Sources */, DB0FCB8C2796BF8D006C02E2 /* SearchViewModel+Diffable.swift in Sources */, + DBEFCD76282A143F00C0ABEA /* ReportStatusViewController.swift in Sources */, 2D8FCA082637EABB00137F46 /* APIService+FollowRequest.swift in Sources */, DBDFF1952805561700557A48 /* DiscoveryPostsViewModel+Diffable.swift in Sources */, DB03A795272A981400EE37C5 /* ContentSplitViewController.swift in Sources */, @@ -3914,12 +4036,14 @@ DB98EB5E27B10A7A0082E365 /* ReportSupplementaryViewModel+Diffable.swift in Sources */, DB0FCB7C2795821F006C02E2 /* StatusThreadRootTableViewCell.swift in Sources */, DB72601C25E36A2100235243 /* MastodonServerRulesViewController.swift in Sources */, + DB5B54A32833BD1A00DEF8B2 /* UserListViewModel.swift in Sources */, DBB5250E2611EBAF002F1F29 /* ProfileSegmentedViewController.swift in Sources */, DBF156DF2701B17600EC00B7 /* SidebarAddAccountCollectionViewCell.swift in Sources */, DB0617F1278413D00030EE79 /* PickServerServerSectionTableHeaderView.swift in Sources */, DB0FCB7E27958957006C02E2 /* StatusThreadRootTableViewCell+ViewModel.swift in Sources */, DB789A0B25F9F2950071ACA0 /* ComposeViewController.swift in Sources */, DB938F0926240F3C00E5B6C1 /* RemoteThreadViewModel.swift in Sources */, + DB5B54A62833BE0000DEF8B2 /* UserListViewModel+State.swift in Sources */, DB0617ED277F02C50030EE79 /* OnboardingNavigationController.swift in Sources */, DB0617F527855AB90030EE79 /* ServerRuleSection.swift in Sources */, DB75BF1E263C1C1B00EDBF1F /* CustomScheduler.swift in Sources */, @@ -3961,11 +4085,13 @@ DBF9814A265E24F500E4BA07 /* ProfileFieldCollectionViewHeaderFooterView.swift in Sources */, 2D939AB525EDD8A90076FA61 /* String.swift in Sources */, DB4481B925EE289600BEFB67 /* UITableView.swift in Sources */, + DB5B54B02833C24200DEF8B2 /* FavoritedByViewController+DataSourceProvider.swift in Sources */, DBE3CDBB261C427900430CC6 /* TimelineHeaderTableViewCell.swift in Sources */, DB159C2B27A17BAC0068DC77 /* DataSourceFacade+Media.swift in Sources */, 0FAA101C25E10E760017CCDE /* UIFont.swift in Sources */, 2D38F1D525CD465300561493 /* HomeTimelineViewController.swift in Sources */, DB6180E926391BDF0018D199 /* MediaHostToMediaPreviewViewControllerAnimatedTransitioning.swift in Sources */, + DB5B549F2833A72500DEF8B2 /* FamiliarFollowersViewModel+Diffable.swift in Sources */, DB6B351E2601FAEE00DC1E11 /* ComposeStatusAttachmentCollectionViewCell.swift in Sources */, DB8F7076279E954700E1225B /* DataSourceFacade+Follow.swift in Sources */, DB36679F268ABAF20027D07F /* ComposeStatusAttachmentSection.swift in Sources */, @@ -3996,6 +4122,7 @@ DB98EB5327B0F9890082E365 /* ReportHeadlineTableViewCell.swift in Sources */, DB5B729C273113C200081888 /* FollowingListViewModel+Diffable.swift in Sources */, DB9E0D6F25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift in Sources */, + DB5B549D2833A67400DEF8B2 /* FamiliarFollowersViewModel.swift in Sources */, DBB9759C262462E1004620BD /* ThreadMetaView.swift in Sources */, DB5B729E273113F300081888 /* FollowingListViewModel+State.swift in Sources */, 2DF123A725C3B0210020F248 /* ActiveLabel.swift in Sources */, @@ -4015,6 +4142,7 @@ DB6180E02639194B0018D199 /* MediaPreviewPagingViewController.swift in Sources */, DBE0822425CD3F1E00FD6BBD /* MastodonRegisterViewModel.swift in Sources */, 5B90C45E262599800002E742 /* SettingsViewModel.swift in Sources */, + DB5B54A12833A89600DEF8B2 /* FamiliarFollowersViewController+DataSourceProvider.swift in Sources */, 2D82B9FF25E7863200E36F0F /* OnboardingViewControllerAppearance.swift in Sources */, DB73BF43271192BB00781945 /* InstanceService.swift in Sources */, DB67D08427312970006A36CF /* APIService+Following.swift in Sources */, @@ -4030,7 +4158,7 @@ DB63F75C279956D000455B82 /* Persistence+Tag.swift in Sources */, 2D84350525FF858100EECE90 /* UIScrollView.swift in Sources */, DB49A61F25FF32AA00B98345 /* EmojiService+CustomEmojiViewModel.swift in Sources */, - 5B24BBDB262DB14800A9381B /* ReportViewModel+Diffable.swift in Sources */, + 5B24BBDB262DB14800A9381B /* ReportStatusViewModel+Diffable.swift in Sources */, DB4F0968269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift in Sources */, 0FB3D2FE25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift in Sources */, 5DA732CC2629CEF500A92342 /* UIView+Remove.swift in Sources */, @@ -4042,6 +4170,7 @@ DBBF1DC92652538500E5B703 /* AutoCompleteSection.swift in Sources */, DB3E6FE72806A7A200B035AE /* DiscoveryItem.swift in Sources */, DB8AF55D25C138B7002E6C99 /* UIViewController.swift in Sources */, + DBEFCD79282A147000C0ABEA /* ReportStatusViewModel.swift in Sources */, DB7F48452620241000796008 /* ProfileHeaderViewModel.swift in Sources */, DB647C5926F1EA2700F7F82C /* WizardPreference.swift in Sources */, DB0A322E280EE9FD001729D2 /* DiscoveryIntroBannerView.swift in Sources */, @@ -4059,7 +4188,7 @@ DB6B74F4272FBAE700C70B6E /* FollowerListViewModel+Diffable.swift in Sources */, DB6B74F2272FB67600C70B6E /* FollowerListViewModel.swift in Sources */, DB44767B260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift in Sources */, - 0F20222D261457EE000C64BF /* HashtagTimelineViewModel+LoadOldestState.swift in Sources */, + 0F20222D261457EE000C64BF /* HashtagTimelineViewModel+State.swift in Sources */, DB0009A626AEE5DC009B9D2D /* Intents.intentdefinition in Sources */, 5B90C462262599800002E742 /* SettingsSectionHeader.swift in Sources */, DB44768B260B3F2100B66B82 /* CustomEmojiPickerItem.swift in Sources */, @@ -4067,7 +4196,6 @@ DB3E6FEF2806D82600B035AE /* DiscoveryNewsViewModel.swift in Sources */, DBBF1DCB2652539E00E5B703 /* AutoCompleteItem.swift in Sources */, 2DA6054725F716A2006356F9 /* PlaybackState.swift in Sources */, - DB98EB6727B216560082E365 /* ReportResultViewModel+Diffable.swift in Sources */, DBC7A672260C897100E57475 /* StatusContentWarningEditorView.swift in Sources */, DB025B95278D6530002F581E /* Persistence+MastodonUser.swift in Sources */, DB3667A6268AE2620027D07F /* ComposeStatusPollSection.swift in Sources */, @@ -4091,8 +4219,9 @@ DB1D186C25EF5BA7003F1F23 /* PollTableView.swift in Sources */, DBA94434265CBB5300C537E1 /* ProfileFieldSection.swift in Sources */, DB336F28278D6EC70031E64B /* MastodonFieldContainer.swift in Sources */, + DBCA0EBC282BB38A0029E2B0 /* PageboyNavigateable.swift in Sources */, DBF156E42702DB3F00EC00B7 /* HandleTapAction.swift in Sources */, - DB98EB4727B0DFAA0082E365 /* ReportViewModel+State.swift in Sources */, + DB98EB4727B0DFAA0082E365 /* ReportStatusViewModel+State.swift in Sources */, 2D5981A125E4A593000FB903 /* MastodonConfirmEmailViewModel.swift in Sources */, DB6B74F6272FBCDB00C70B6E /* FollowerListViewModel+State.swift in Sources */, DB87D4452609BE0500D12C0D /* ComposeStatusPollOptionCollectionViewCell.swift in Sources */, @@ -4150,6 +4279,7 @@ DB6D9F8426358EEC008423CD /* SettingsItem.swift in Sources */, 2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */, DBA465932696B495002B41DB /* APIService+WebFinger.swift in Sources */, + DBEFCD7B282A162400C0ABEA /* ReportReasonView.swift in Sources */, DB8AF54525C13647002E6C99 /* NeedsDependency.swift in Sources */, DB63F77B279ACAE500455B82 /* DataSourceFacade+Favorite.swift in Sources */, DB9D6BF825E4F5690051B173 /* NotificationViewController.swift in Sources */, @@ -4164,6 +4294,7 @@ DB4F097526A037F500D62E92 /* SearchHistoryViewModel.swift in Sources */, DB3EA8E9281B7A3700598866 /* DiscoveryCommunityViewModel.swift in Sources */, DB6180F826391D660018D199 /* MediaPreviewingViewController.swift in Sources */, + DBEFCD71282A12B200C0ABEA /* ReportReasonViewController.swift in Sources */, DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */, DB98EB5627B0FF1B0082E365 /* ReportViewControllerAppearance.swift in Sources */, DB938F1526241FDF00E5B6C1 /* APIService+Thread.swift in Sources */, @@ -4187,6 +4318,7 @@ DBD376AC2692ECDB007FEC24 /* ThemePreference.swift in Sources */, DB4F097D26A03A5B00D62E92 /* SearchHistoryItem.swift in Sources */, DBD5B1FA27BD013700BD6B38 /* DataSourceProvider+StatusTableViewControllerNavigateable.swift in Sources */, + DB5B549A2833A60400DEF8B2 /* FamiliarFollowersViewController.swift in Sources */, DB3E6FE22806A50100B035AE /* DiscoveryHashtagsViewModel+Diffable.swift in Sources */, DB68046C2636DC9E00430867 /* MastodonNotification.swift in Sources */, DBAE3F9E2616E308004B8251 /* APIService+Mute.swift in Sources */, @@ -4200,10 +4332,10 @@ 2D7867192625B77500211898 /* NotificationItem.swift in Sources */, DB45FAB625CA5485005A8AC7 /* UIAlertController.swift in Sources */, DBE0821525CD382600FD6BBD /* MastodonRegisterViewController.swift in Sources */, + DBEFCD74282A130400C0ABEA /* ReportReasonViewModel.swift in Sources */, 2D5A3D0325CF8742002347D6 /* ControlContainableScrollViews.swift in Sources */, DB36679D268AB91B0027D07F /* ComposeStatusAttachmentTableViewCell.swift in Sources */, DB98336B25C9420100AD9700 /* APIService+App.swift in Sources */, - DB894CC427A5490600684B74 /* BlurhashImageCacheService.swift in Sources */, DBFEF07B26A6BCE8006D7ED1 /* APIService+Status+Publish.swift in Sources */, DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */, 5B90C48526259BF10002E742 /* APIService+Subscriptions.swift in Sources */, @@ -4254,7 +4386,6 @@ DB3E6FE42806A5B800B035AE /* DiscoverySection.swift in Sources */, DB8190C62601FF0400020C08 /* AttachmentContainerView.swift in Sources */, DB697DDB278F4DE3004EF2F7 /* DataSourceProvider+StatusTableViewCellDelegate.swift in Sources */, - DB51D173262832380062B7A1 /* BlurHashEncode.swift in Sources */, 2D32EAAC25CB96DC00C9ED86 /* TimelineMiddleLoaderTableViewCell.swift in Sources */, DB87D4512609CF1E00D12C0D /* ComposeStatusPollOptionAppendEntryCollectionViewCell.swift in Sources */, DBB45B5627B39FC9002DC5A7 /* MediaPreviewVideoViewController.swift in Sources */, @@ -4287,6 +4418,7 @@ DB0617EB277EF3820030EE79 /* GradientBorderView.swift in Sources */, DB789A1225F9F2CC0071ACA0 /* ComposeViewModel.swift in Sources */, DB63F74B279914A000455B82 /* FollowingListViewController+DataSourceProvider.swift in Sources */, + DBEFCD7D282A2A3B00C0ABEA /* ReportServerRulesViewController.swift in Sources */, DBB525362611ECEB002F1F29 /* UserTimelineViewController.swift in Sources */, DB938F3326243D6200E5B6C1 /* TimelineTopLoaderTableViewCell.swift in Sources */, DB98EB4927B0F0CD0082E365 /* ReportStatusTableViewCell.swift in Sources */, @@ -4297,6 +4429,7 @@ DB98EB6527B216500082E365 /* ReportResultViewModel.swift in Sources */, DB4F096A269EDAD200D62E92 /* SearchResultViewModel+State.swift in Sources */, 5BB04FF5262F0E6D0043BFF6 /* ReportSection.swift in Sources */, + DBEFCD82282A2AB100C0ABEA /* ReportServerRulesView.swift in Sources */, DBA94436265CBB7400C537E1 /* ProfileFieldItem.swift in Sources */, DB023D2A27A0FE5C005AC798 /* DataSourceProvider+NotificationTableViewCellDelegate.swift in Sources */, DB98EB6027B10E150082E365 /* ReportCommentTableViewCell.swift in Sources */, @@ -4312,7 +4445,6 @@ DB6180ED26391C6C0018D199 /* TransitioningMath.swift in Sources */, DB63F771279A858500455B82 /* Persistence+Notification.swift in Sources */, 2D6DE40026141DF600A63F6A /* SearchViewModel.swift in Sources */, - DB51D172262832380062B7A1 /* BlurHashDecode.swift in Sources */, DBCCC71E25F73297007E1AB6 /* APIService+Reblog.swift in Sources */, DB0617FD27855BFE0030EE79 /* ServerRuleItem.swift in Sources */, 5BB04FD5262E7AFF0043BFF6 /* ReportViewController.swift in Sources */, @@ -4466,15 +4598,11 @@ DBA4B0D726BD10F40077136E /* ca */, DBA4B0DB26BD11130077136E /* fr */, DBA4B0DF26BD11C70077136E /* es */, - DBA4B0E326BD11D10077136E /* es-419 */, DBA4B0E826C153820077136E /* de */, DBA4B0EC26C153B10077136E /* nl */, DBA4B0F526C2621D0077136E /* en */, DB4B777F26CA4EFA00B087B3 /* ru */, - DB4B778426CA500E00B087B3 /* gd-GB */, DB4B779226CA50BA00B087B3 /* th */, - DB126A4C278C063F005726EE /* eu-ES */, - DB126A56278C088D005726EE /* sv-FI */, DBEB19E927E4F37B00B0E80E /* ku */, DBF81C7427F68F5A00004A56 /* kab */, DBF81C7727F6913300004A56 /* vi */, @@ -4484,6 +4612,10 @@ DB519B0F281BCB3300F0C99D /* gl */, DB519B12281BCBC400F0C99D /* it */, DB519B15281BCC2F00F0C99D /* tr */, + DBC9E3A3282E13BB0063A4D9 /* eu */, + DBC9E3A6282E15190063A4D9 /* gd */, + DBC9E3A9282E17DF0063A4D9 /* es-AR */, + DB8F40042835EE5E006E7513 /* fi */, ); name = Intents.intentdefinition; sourceTree = ""; @@ -4498,14 +4630,10 @@ DBA4B0DA26BD10F40077136E /* ca */, DBA4B0DE26BD11130077136E /* fr */, DBA4B0E226BD11C80077136E /* es */, - DBA4B0E626BD11D10077136E /* es-419 */, DBA4B0EB26C153820077136E /* de */, DBA4B0EF26C153B20077136E /* nl */, DB4B778226CA4EFA00B087B3 /* ru */, - DB4B778726CA500E00B087B3 /* gd-GB */, DB4B779526CA50BA00B087B3 /* th */, - DB126A4F278C063F005726EE /* eu-ES */, - DB126A59278C088D005726EE /* sv-FI */, DBEB19EA27E4F37B00B0E80E /* ku */, DBF81C7527F68F5A00004A56 /* kab */, DBF81C7827F6913300004A56 /* vi */, @@ -4515,6 +4643,10 @@ DB519B10281BCB3300F0C99D /* gl */, DB519B13281BCBC400F0C99D /* it */, DB519B16281BCC2F00F0C99D /* tr */, + DBC9E3A4282E13BB0063A4D9 /* eu */, + DBC9E3A7282E15190063A4D9 /* gd */, + DBC9E3AA282E17DF0063A4D9 /* es-AR */, + DB8F40052835EE5E006E7513 /* fi */, ); name = InfoPlist.strings; sourceTree = ""; @@ -4540,9 +4672,7 @@ children = ( DBA4B0F826C269880077136E /* en */, DB4B778326CA4EFA00B087B3 /* ru */, - DB4B778826CA500E00B087B3 /* gd-GB */, DB4B778926CA504100B087B3 /* es */, - DB4B778A26CA504200B087B3 /* es-419 */, DB4B778B26CA504300B087B3 /* ar */, DB4B778C26CA504400B087B3 /* ca */, DB4B778D26CA504500B087B3 /* zh-Hans */, @@ -4551,8 +4681,6 @@ DB4B779026CA504900B087B3 /* fr */, DB4B779126CA504A00B087B3 /* ja */, DB4B779626CA50BA00B087B3 /* th */, - DB126A50278C063F005726EE /* eu-ES */, - DB126A5A278C088D005726EE /* sv-FI */, DBEB19EB27E4F37B00B0E80E /* ku */, DBF81C7627F68F5A00004A56 /* kab */, DBF81C7927F6913300004A56 /* vi */, @@ -4562,6 +4690,10 @@ DB519B11281BCB3400F0C99D /* gl */, DB519B14281BCBC400F0C99D /* it */, DB519B17281BCC2F00F0C99D /* tr */, + DBC9E3A5282E13BB0063A4D9 /* eu */, + DBC9E3A8282E15190063A4D9 /* gd */, + DBC9E3AB282E17DF0063A4D9 /* es-AR */, + DB8F40062835EE5E006E7513 /* fi */, ); name = Intents.stringsdict; sourceTree = ""; @@ -4612,7 +4744,7 @@ CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -4707,7 +4839,7 @@ CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = Mastodon/Info.plist; @@ -4737,7 +4869,7 @@ CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = Mastodon/Info.plist; @@ -4845,11 +4977,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 126; + DYLIB_CURRENT_VERSION = 133; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = AppShared/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -4876,11 +5008,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 126; + DYLIB_CURRENT_VERSION = 133; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = AppShared/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -4899,12 +5031,247 @@ }; name = Release; }; + DB848E2A282B5E6300A302CC /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "PROFILE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + INTENTS_CODEGEN_LANGUAGE = Swift; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = PROFILE; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + }; + name = Profile; + }; + DB848E2B282B5E6300A302CC /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7CB58D292DA7ACEF179A9050 /* Pods-Mastodon.profile.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 133; + DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; + DEVELOPMENT_TEAM = 5Z4GVSS33P; + INFOPLIST_FILE = Mastodon/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0.7; + PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "Mastodon/Vender/Mastodon-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + DB848E2C282B5E6300A302CC /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DF65937EC1FF64462BC002EE /* Pods-MastodonTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 5Z4GVSS33P; + INFOPLIST_FILE = MastodonTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.MastodonTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mastodon.app/Mastodon"; + }; + name = Profile; + }; + DB848E2D282B5E6300A302CC /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 728DE51ADA27C395C6E1BAB5 /* Pods-Mastodon-MastodonUITests.profile.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 5Z4GVSS33P; + INFOPLIST_FILE = MastodonUITests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.MastodonUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = Mastodon; + }; + name = Profile; + }; + DB848E2E282B5E6300A302CC /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 63EF9E6E5B575CD2A8B0475D /* Pods-AppShared.profile.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 133; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = 5Z4GVSS33P; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 133; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = AppShared/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.AppShared; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Profile; + }; + DB848E2F282B5E6300A302CC /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 133; + DEVELOPMENT_TEAM = 5Z4GVSS33P; + INFOPLIST_FILE = NotificationService/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0.7; + PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + DB848E30282B5E6300A302CC /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 133; + DEVELOPMENT_TEAM = 5Z4GVSS33P; + INFOPLIST_FILE = ShareActionExtension/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0.7; + PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + DB848E31282B5E6300A302CC /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 133; + DEVELOPMENT_TEAM = 5Z4GVSS33P; + INFOPLIST_FILE = MastodonIntent/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0.7; + PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.MastodonIntent; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; DB8FABD026AEC7B2008E5AF4 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = MastodonIntent/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -4928,7 +5295,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = MastodonIntent/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -4952,7 +5319,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -4976,7 +5343,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5063,7 +5430,7 @@ CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets"; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = Mastodon/Info.plist; @@ -5130,11 +5497,11 @@ APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEFINES_MODULE = YES; DEVELOPMENT_TEAM = 5Z4GVSS33P; DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 126; + DYLIB_CURRENT_VERSION = 133; DYLIB_INSTALL_NAME_BASE = "@rpath"; INFOPLIST_FILE = AppShared/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -5158,7 +5525,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = NotificationService/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5181,7 +5548,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5205,7 +5572,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = MastodonIntent/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5229,7 +5596,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = NotificationService/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5252,7 +5619,7 @@ buildSettings = { CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 126; + CURRENT_PROJECT_VERSION = 133; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = NotificationService/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( @@ -5277,6 +5644,7 @@ isa = XCConfigurationList; buildConfigurations = ( DB427DFA25BAA00100D1B89D /* Debug */, + DB848E2A282B5E6300A302CC /* Profile */, DB427DFB25BAA00100D1B89D /* Release */, DBEB19E127E4658E00B0E80E /* Release Snapshot */, ); @@ -5287,6 +5655,7 @@ isa = XCConfigurationList; buildConfigurations = ( DB427DFD25BAA00100D1B89D /* Debug */, + DB848E2B282B5E6300A302CC /* Profile */, DB427DFE25BAA00100D1B89D /* Release */, DBEB19E227E4658E00B0E80E /* Release Snapshot */, ); @@ -5297,6 +5666,7 @@ isa = XCConfigurationList; buildConfigurations = ( DB427E0025BAA00100D1B89D /* Debug */, + DB848E2C282B5E6300A302CC /* Profile */, DB427E0125BAA00100D1B89D /* Release */, DBEB19E327E4658E00B0E80E /* Release Snapshot */, ); @@ -5307,6 +5677,7 @@ isa = XCConfigurationList; buildConfigurations = ( DB427E0325BAA00100D1B89D /* Debug */, + DB848E2D282B5E6300A302CC /* Profile */, DB427E0425BAA00100D1B89D /* Release */, DBEB19E427E4658E00B0E80E /* Release Snapshot */, ); @@ -5317,6 +5688,7 @@ isa = XCConfigurationList; buildConfigurations = ( DB6804892637CD4C00430867 /* Debug */, + DB848E2E282B5E6300A302CC /* Profile */, DB68048A2637CD4C00430867 /* Release */, DBEB19E527E4658E00B0E80E /* Release Snapshot */, ); @@ -5327,6 +5699,7 @@ isa = XCConfigurationList; buildConfigurations = ( DB8FABD026AEC7B2008E5AF4 /* Debug */, + DB848E31282B5E6300A302CC /* Profile */, DB8FABD326AEC7B2008E5AF4 /* Release */, DBEB19E827E4658E00B0E80E /* Release Snapshot */, ); @@ -5337,6 +5710,7 @@ isa = XCConfigurationList; buildConfigurations = ( DBC6461D26A170AB00B0E31B /* Debug */, + DB848E30282B5E6300A302CC /* Profile */, DBC6462026A170AB00B0E31B /* Release */, DBEB19E727E4658E00B0E80E /* Release Snapshot */, ); @@ -5347,6 +5721,7 @@ isa = XCConfigurationList; buildConfigurations = ( DBF8AE1C263293E400C9C23C /* Debug */, + DB848E2F282B5E6300A302CC /* Profile */, DBF8AE1D263293E400C9C23C /* Release */, DBEB19E627E4658E00B0E80E /* Release Snapshot */, ); diff --git a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist index 07a847a0c..3e2139aa3 100644 --- a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist @@ -9,33 +9,38 @@ isShown orderHint - 4 + 5 CoreDataStack.xcscheme_^#shared#^_ orderHint 27 - Mastodon - RTL.xcscheme_^#shared#^_ - - orderHint - 6 - - Mastodon - Release.xcscheme_^#shared#^_ + Mastodon - Profile.xcscheme_^#shared#^_ orderHint 1 - Mastodon - Snapshot.xcscheme_^#shared#^_ + Mastodon - RTL.xcscheme_^#shared#^_ + + orderHint + 8 + + Mastodon - Release.xcscheme_^#shared#^_ orderHint 2 - Mastodon - ar.xcscheme + Mastodon - Snapshot.xcscheme_^#shared#^_ orderHint 3 + Mastodon - ar.xcscheme + + orderHint + 4 + Mastodon - ar.xcscheme_^#shared#^_ orderHint @@ -124,12 +129,12 @@ NotificationService.xcscheme_^#shared#^_ orderHint - 27 + 29 ShareActionExtension.xcscheme_^#shared#^_ orderHint - 26 + 27 SuppressBuildableAutocreation diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift index 5e7fbf472..9df3040c7 100644 --- a/Mastodon/Coordinator/SceneCoordinator.swift +++ b/Mastodon/Coordinator/SceneCoordinator.swift @@ -158,7 +158,7 @@ extension SceneCoordinator { case mastodonServerRules(viewModel: MastodonServerRulesViewModel) case mastodonConfirmEmail(viewModel: MastodonConfirmEmailViewModel) case mastodonResendEmail(viewModel: MastodonResendEmailViewModel) - case mastodonWebView(viewModel:WebViewModel) + case mastodonWebView(viewModel: WebViewModel) // search case searchDetail(viewModel: SearchDetailViewModel) @@ -178,12 +178,17 @@ extension SceneCoordinator { case favorite(viewModel: FavoriteViewModel) case follower(viewModel: FollowerListViewModel) case following(viewModel: FollowingListViewModel) + case familiarFollowers(viewModel: FamiliarFollowersViewModel) + case rebloggedBy(viewModel: UserListViewModel) + case favoritedBy(viewModel: UserListViewModel) // setting case settings(viewModel: SettingsViewModel) // report case report(viewModel: ReportViewModel) + case reportServerRules(viewModel: ReportServerRulesViewModel) + case reportStatus(viewModel: ReportStatusViewModel) case reportSupplementary(viewModel: ReportSupplementaryViewModel) case reportResult(viewModel: ReportResultViewModel) @@ -443,10 +448,30 @@ private extension SceneCoordinator { let _viewController = FollowingListViewController() _viewController.viewModel = viewModel viewController = _viewController + case .familiarFollowers(let viewModel): + let _viewController = FamiliarFollowersViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .rebloggedBy(let viewModel): + let _viewController = RebloggedByViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .favoritedBy(let viewModel): + let _viewController = FavoritedByViewController() + _viewController.viewModel = viewModel + viewController = _viewController case .report(let viewModel): let _viewController = ReportViewController() _viewController.viewModel = viewModel viewController = _viewController + case .reportServerRules(let viewModel): + let _viewController = ReportServerRulesViewController() + _viewController.viewModel = viewModel + viewController = _viewController + case .reportStatus(let viewModel): + let _viewController = ReportStatusViewController() + _viewController.viewModel = viewModel + viewController = _viewController case .reportSupplementary(let viewModel): let _viewController = ReportSupplementaryViewController() _viewController.viewModel = viewModel diff --git a/Mastodon/Diffiable/Discovery/DiscoverySection.swift b/Mastodon/Diffiable/Discovery/DiscoverySection.swift index cab2eb82b..94e07c71b 100644 --- a/Mastodon/Diffiable/Discovery/DiscoverySection.swift +++ b/Mastodon/Diffiable/Discovery/DiscoverySection.swift @@ -8,6 +8,7 @@ import os.log import UIKit import MastodonUI +import MastodonSDK enum DiscoverySection: CaseIterable { // case posts @@ -22,9 +23,14 @@ extension DiscoverySection { class Configuration { weak var profileCardTableViewCellDelegate: ProfileCardTableViewCellDelegate? + let familiarFollowers: Published<[Mastodon.Entity.FamiliarFollowers]>.Publisher? - public init(profileCardTableViewCellDelegate: ProfileCardTableViewCellDelegate? = nil) { + public init( + profileCardTableViewCellDelegate: ProfileCardTableViewCellDelegate? = nil, + familiarFollowers: Published<[Mastodon.Entity.FamiliarFollowers]>.Publisher? = nil + ) { self.profileCardTableViewCellDelegate = profileCardTableViewCellDelegate + self.familiarFollowers = familiarFollowers } } @@ -57,6 +63,15 @@ extension DiscoverySection { user: user, profileCardTableViewCellDelegate: configuration.profileCardTableViewCellDelegate ) + // bind familiarFollowers + if let familiarFollowers = configuration.familiarFollowers { + familiarFollowers + .map { array in array.first(where: { $0.id == user.id }) } + .assign(to: \.familiarFollowers, on: cell.profileCardView.viewModel) + .store(in: &cell.disposeBag) + } else { + cell.profileCardView.viewModel.familiarFollowers = nil + } } context.authenticationService.activeMastodonAuthentication .map { $0?.user } diff --git a/Mastodon/Diffiable/User/UserSection.swift b/Mastodon/Diffiable/User/UserSection.swift index a42110d7a..cb806c4e9 100644 --- a/Mastodon/Diffiable/User/UserSection.swift +++ b/Mastodon/Diffiable/User/UserSection.swift @@ -30,7 +30,9 @@ extension UserSection { configuration: Configuration ) -> UITableViewDiffableDataSource { tableView.register(UserTableViewCell.self, forCellReuseIdentifier: String(describing: UserTableViewCell.self)) - + tableView.register(TimelineBottomLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineBottomLoaderTableViewCell.self)) + tableView.register(TimelineFooterTableViewCell.self, forCellReuseIdentifier: String(describing: TimelineFooterTableViewCell.self)) + return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item -> UITableViewCell? in switch item { case .user(let record): diff --git a/Mastodon/Generated/AutoGenerateTableViewDelegate.generated.swift b/Mastodon/Generated/AutoGenerateTableViewDelegate.generated.swift index 7d6e01cf7..4c65e1a3e 100644 --- a/Mastodon/Generated/AutoGenerateTableViewDelegate.generated.swift +++ b/Mastodon/Generated/AutoGenerateTableViewDelegate.generated.swift @@ -36,3 +36,6 @@ func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith con + + + diff --git a/Mastodon/Info.plist b/Mastodon/Info.plist index c93fd9a65..66fdfcaaf 100644 --- a/Mastodon/Info.plist +++ b/Mastodon/Info.plist @@ -30,7 +30,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.1 + 1.4.2 CFBundleURLTypes @@ -43,7 +43,7 @@ CFBundleVersion - 126 + 133 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/Mastodon/Protocol/PageboyNavigateable.swift b/Mastodon/Protocol/PageboyNavigateable.swift new file mode 100644 index 000000000..8ff59ef4f --- /dev/null +++ b/Mastodon/Protocol/PageboyNavigateable.swift @@ -0,0 +1,92 @@ +// +// PageboyNavigateable.swift +// Mastodon +// +// Created by MainasuK on 2022-5-11. +// + +import UIKit +import Pageboy +import MastodonLocalization + +typealias PageboyNavigateable = PageboyNavigateableCore & PageboyNavigateableRelay + +protocol PageboyNavigateableCore: AnyObject { + var navigateablePageViewController: PageboyViewController { get } + var pageboyNavigateKeyCommands: [UIKeyCommand] { get } + + func pageboyNavigateKeyCommandHandler(_ sender: UIKeyCommand) + func navigate(direction: PageboyNavigationDirection) +} + +@objc protocol PageboyNavigateableRelay: AnyObject { + func pageboyNavigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) +} + +enum PageboyNavigationDirection: String, CaseIterable { + case previous + case next + + var title: String { + switch self { + case .previous: return L10n.Common.Controls.Keyboard.SegmentedControl.previousSection + case .next: return L10n.Common.Controls.Keyboard.SegmentedControl.nextSection + } + } + + // UIKeyCommand input + var input: String { + switch self { + case .previous: return "[" + case .next: return "]" + } + } + + var modifierFlags: UIKeyModifierFlags { + switch self { + case .previous: return [.shift, .command] + case .next: return [.shift, .command] + } + } + + var propertyList: Any { + return rawValue + } +} + +extension PageboyNavigateableCore where Self: PageboyNavigateableRelay { + var pageboyNavigateKeyCommands: [UIKeyCommand] { + PageboyNavigationDirection.allCases.map { direction in + UIKeyCommand( + title: direction.title, + image: nil, + action: #selector(Self.pageboyNavigateKeyCommandHandlerRelay(_:)), + input: direction.input, + modifierFlags: direction.modifierFlags, + propertyList: direction.propertyList, + alternates: [], + discoverabilityTitle: nil, + attributes: [], + state: .off + ) + } + } + + func pageboyNavigateKeyCommandHandler(_ sender: UIKeyCommand) { + guard let rawValue = sender.propertyList as? String, + let direction = PageboyNavigationDirection(rawValue: rawValue) else { return } + navigate(direction: direction) + } + +} + +extension PageboyNavigateableCore { + func navigate(direction: PageboyNavigationDirection) { + switch direction { + case .previous: + navigateablePageViewController.scrollToPage(.previous, animated: true) + case .next: + navigateablePageViewController.scrollToPage(.next, animated: true) + } + } +} diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift index f00e14840..d02edcc42 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewCellDelegate.swift @@ -474,6 +474,55 @@ extension StatusTableViewCellDelegate where Self: DataSourceProvider { } +// MARK: - StatusMetricView +extension StatusTableViewCellDelegate where Self: DataSourceProvider { + func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton) { + Task { + let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil) + guard let item = await item(from: source) else { + assertionFailure() + return + } + guard case let .status(status) = item else { + assertionFailure("only works for status data provider") + return + } + let userListViewModel = UserListViewModel( + context: context, + kind: .rebloggedBy(status: status) + ) + await coordinator.present( + scene: .rebloggedBy(viewModel: userListViewModel), + from: self, + transition: .show + ) + } // end Task + } + + func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton) { + Task { + let source = DataSourceItem.Source(tableViewCell: cell, indexPath: nil) + guard let item = await item(from: source) else { + assertionFailure() + return + } + guard case let .status(status) = item else { + assertionFailure("only works for status data provider") + return + } + let userListViewModel = UserListViewModel( + context: context, + kind: .favoritedBy(status: status) + ) + await coordinator.present( + scene: .favoritedBy(viewModel: userListViewModel), + from: self, + transition: .show + ) + } // end Task + } +} + // MARK: a11y extension StatusTableViewCellDelegate where Self: DataSourceProvider { func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, accessibilityActivate: Void) { diff --git a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift index fb4a7d843..ce4e03cdb 100644 --- a/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift +++ b/Mastodon/Protocol/Provider/DataSourceProvider+StatusTableViewControllerNavigateable.swift @@ -115,7 +115,7 @@ extension StatusTableViewControllerNavigateableCore where Self: DataSourceProvid guard let provider = self as? (DataSourceProvider & MediaPreviewableViewController) else { return } guard let indexPathForSelectedRow = tableView.indexPathForSelectedRow, - let cell = tableView.cellForRow(at: indexPathForSelectedRow) as? StatusTableViewCell + let cell = tableView.cellForRow(at: indexPathForSelectedRow) as? StatusViewContainerTableViewCell else { return } guard let mediaView = cell.statusView.mediaGridContainerView.mediaViews.first else { return } diff --git a/Mastodon/Resources/es-419.lproj/InfoPlist.strings b/Mastodon/Resources/es-419.lproj/InfoPlist.strings deleted file mode 100644 index e7ef4cb76..000000000 --- a/Mastodon/Resources/es-419.lproj/InfoPlist.strings +++ /dev/null @@ -1,4 +0,0 @@ -"NSCameraUsageDescription" = "Usado para tomar fotos para los mensajes"; -"NSPhotoLibraryAddUsageDescription" = "Usado para guardar la foto en la Biblioteca de fotos"; -"NewPostShortcutItemTitle" = "Nuevo mensaje"; -"SearchShortcutItemTitle" = "Buscar"; \ No newline at end of file diff --git a/Mastodon/Resources/eu-ES.lproj/InfoPlist.strings b/Mastodon/Resources/es-AR.lproj/InfoPlist.strings similarity index 100% rename from Mastodon/Resources/eu-ES.lproj/InfoPlist.strings rename to Mastodon/Resources/es-AR.lproj/InfoPlist.strings diff --git a/Mastodon/Resources/sv-FI.lproj/InfoPlist.strings b/Mastodon/Resources/eu.lproj/InfoPlist.strings similarity index 100% rename from Mastodon/Resources/sv-FI.lproj/InfoPlist.strings rename to Mastodon/Resources/eu.lproj/InfoPlist.strings diff --git a/Mastodon/Resources/fi.lproj/InfoPlist.strings b/Mastodon/Resources/fi.lproj/InfoPlist.strings new file mode 100644 index 000000000..710865573 --- /dev/null +++ b/Mastodon/Resources/fi.lproj/InfoPlist.strings @@ -0,0 +1,4 @@ +"NSCameraUsageDescription" = "Used to take photo for post status"; +"NSPhotoLibraryAddUsageDescription" = "Used to save photo into the Photo Library"; +"NewPostShortcutItemTitle" = "New Post"; +"SearchShortcutItemTitle" = "Search"; \ No newline at end of file diff --git a/Mastodon/Resources/gd-GB.lproj/InfoPlist.strings b/Mastodon/Resources/gd-GB.lproj/InfoPlist.strings deleted file mode 100644 index ccb39b44e..000000000 --- a/Mastodon/Resources/gd-GB.lproj/InfoPlist.strings +++ /dev/null @@ -1,4 +0,0 @@ -"NSCameraUsageDescription" = "’Ga chleachdadh airson dealbh a thogail do staid puist"; -"NSPhotoLibraryAddUsageDescription" = "’Ga chleachdadh airson dealbh a shàbhaladh ann an tasg-lann nan dealbhan"; -"NewPostShortcutItemTitle" = "Post ùr"; -"SearchShortcutItemTitle" = "Lorg"; \ No newline at end of file diff --git a/Mastodon/Resources/gd.lproj/InfoPlist.strings b/Mastodon/Resources/gd.lproj/InfoPlist.strings new file mode 100644 index 000000000..710865573 --- /dev/null +++ b/Mastodon/Resources/gd.lproj/InfoPlist.strings @@ -0,0 +1,4 @@ +"NSCameraUsageDescription" = "Used to take photo for post status"; +"NSPhotoLibraryAddUsageDescription" = "Used to save photo into the Photo Library"; +"NewPostShortcutItemTitle" = "New Post"; +"SearchShortcutItemTitle" = "Search"; \ No newline at end of file diff --git a/Mastodon/Scene/Compose/AutoComplete/AutoCompleteViewModel.swift b/Mastodon/Scene/Compose/AutoComplete/AutoCompleteViewModel.swift index dc6ab1789..3110f93e3 100644 --- a/Mastodon/Scene/Compose/AutoComplete/AutoCompleteViewModel.swift +++ b/Mastodon/Scene/Compose/AutoComplete/AutoCompleteViewModel.swift @@ -46,7 +46,7 @@ final class AutoCompleteViewModel { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) - snapshot.appendItems(items, toSection: .main) + snapshot.appendItems(items.removingDuplicates(), toSection: .main) if let currentState = self.stateMachine.currentState { switch currentState { case is State.Loading, is State.Fail: diff --git a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewController.swift b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewController.swift index eabed7a0e..4cc32c250 100644 --- a/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewController.swift +++ b/Mastodon/Scene/Discovery/Community/DiscoveryCommunityViewController.swift @@ -152,3 +152,20 @@ extension DiscoveryCommunityViewController: ScrollViewContainer { tableView } } + +extension DiscoveryCommunityViewController { + override var keyCommands: [UIKeyCommand]? { + return navigationKeyCommands + statusNavigationKeyCommands + } +} + +// MARK: - StatusTableViewControllerNavigateable +extension DiscoveryCommunityViewController: StatusTableViewControllerNavigateable { + @objc func navigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + navigateKeyCommandHandler(sender) + } + + @objc func statusKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + statusKeyCommandHandler(sender) + } +} diff --git a/Mastodon/Scene/Discovery/DiscoveryViewController.swift b/Mastodon/Scene/Discovery/DiscoveryViewController.swift index 8e3aab647..1803f687a 100644 --- a/Mastodon/Scene/Discovery/DiscoveryViewController.swift +++ b/Mastodon/Scene/Discovery/DiscoveryViewController.swift @@ -9,6 +9,7 @@ import os.log import UIKit import Combine import Tabman +import Pageboy import MastodonAsset import MastodonUI @@ -126,3 +127,31 @@ extension DiscoveryViewController { } } + +// MARK: - ScrollViewContainer +extension DiscoveryViewController: ScrollViewContainer { + var scrollView: UIScrollView? { + return (currentViewController as? ScrollViewContainer)?.scrollView + } +} + +extension DiscoveryViewController { + + public override var keyCommands: [UIKeyCommand]? { + return pageboyNavigateKeyCommands + } + +} + +// MARK: - PageboyNavigateable +extension DiscoveryViewController: PageboyNavigateable { + + var navigateablePageViewController: PageboyViewController { + return self + } + + @objc func pageboyNavigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + pageboyNavigateKeyCommandHandler(sender) + } + +} diff --git a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift index b8b8f25a7..c7b8fb7f5 100644 --- a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift +++ b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewController.swift @@ -122,7 +122,11 @@ extension DiscoveryForYouViewController: UITableViewDelegate { // MARK: - ProfileCardTableViewCellDelegate extension DiscoveryForYouViewController: ProfileCardTableViewCellDelegate { - func profileCardTableViewCell(_ cell: ProfileCardTableViewCell, profileCardView: ProfileCardView, relationshipButtonDidPressed button: ProfileRelationshipActionButton) { + func profileCardTableViewCell( + _ cell: ProfileCardTableViewCell, + profileCardView: ProfileCardView, + relationshipButtonDidPressed button: ProfileRelationshipActionButton + ) { guard let authenticationBox = viewModel.context.authenticationService.activeMastodonAuthenticationBox.value else { return } guard let indexPath = tableView.indexPath(for: cell) else { return } guard case let .user(record) = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { return } @@ -135,6 +139,31 @@ extension DiscoveryForYouViewController: ProfileCardTableViewCellDelegate { ) } // end Task } + + func profileCardTableViewCell( + _ cell: ProfileCardTableViewCell, + profileCardView: ProfileCardView, + familiarFollowersDashboardViewDidPressed view: FamiliarFollowersDashboardView + ) { + guard let indexPath = tableView.indexPath(for: cell) else { return } + guard case let .user(record) = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { return } + guard let user = record.object(in: context.managedObjectContext) else { return } + + let userID = user.id + let _familiarFollowers = viewModel.familiarFollowers.first(where: { $0.id == userID }) + guard let familiarFollowers = _familiarFollowers else { + assertionFailure() + return + } + + let familiarFollowersViewModel = FamiliarFollowersViewModel(context: context) + familiarFollowersViewModel.familiarFollowers = familiarFollowers + coordinator.present( + scene: .familiarFollowers(viewModel: familiarFollowersViewModel), + from: self, + transition: .show + ) + } } // MARK: ScrollViewContainer diff --git a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift index fe53cf221..f93b4c0bd 100644 --- a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel+Diffable.swift @@ -19,7 +19,8 @@ extension DiscoveryForYouViewModel { tableView: tableView, context: context, configuration: DiscoverySection.Configuration( - profileCardTableViewCellDelegate: profileCardTableViewCellDelegate + profileCardTableViewCellDelegate: profileCardTableViewCellDelegate, + familiarFollowers: $familiarFollowers ) ) diff --git a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift index 7be4aebaf..a31022a7c 100644 --- a/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift +++ b/Mastodon/Scene/Discovery/ForYou/DiscoveryForYouViewModel.swift @@ -20,6 +20,9 @@ final class DiscoveryForYouViewModel { // input let context: AppContext let userFetchedResultsController: UserFetchedResultsController + + @MainActor + @Published var familiarFollowers: [Mastodon.Entity.FamiliarFollowers] = [] @Published var isFetching = false // output @@ -48,12 +51,35 @@ final class DiscoveryForYouViewModel { } extension DiscoveryForYouViewModel { + + @MainActor func fetch() async throws { guard !isFetching else { return } isFetching = true defer { isFetching = false } - - guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else { return } + + guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else { + throw APIService.APIError.implicit(.badRequest) + } + + do { + let userIDs = try await fetchSuggestionAccounts() + + let _familiarFollowersResponse = try? await context.apiService.familiarFollowers( + query: .init(ids: userIDs), + authenticationBox: authenticationBox + ) + familiarFollowers = _familiarFollowersResponse?.value ?? [] + userFetchedResultsController.userIDs = userIDs + } catch { + // do nothing + } + } + + private func fetchSuggestionAccounts() async throws -> [Mastodon.Entity.Account.ID] { + guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else { + throw APIService.APIError.implicit(.badRequest) + } do { let response = try await context.apiService.suggestionAccountV2( @@ -61,15 +87,15 @@ extension DiscoveryForYouViewModel { authenticationBox: authenticationBox ) let userIDs = response.value.map { $0.account.id } - userFetchedResultsController.userIDs = userIDs + return userIDs } catch { // fallback V1 - let response2 = try await context.apiService.suggestionAccount( + let response = try await context.apiService.suggestionAccount( query: nil, authenticationBox: authenticationBox ) - let userIDs = response2.value.map { $0.id } - userFetchedResultsController.userIDs = userIDs + let userIDs = response.value.map { $0.id } + return userIDs } } } diff --git a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift index 91ab5036c..6e6d96924 100644 --- a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift +++ b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewController.swift @@ -131,3 +131,98 @@ extension DiscoveryHashtagsViewController: ScrollViewContainer { tableView } } + +extension DiscoveryHashtagsViewController { + override var keyCommands: [UIKeyCommand]? { + return navigationKeyCommands + } +} + +// MARK: - TableViewControllerNavigateable +extension DiscoveryHashtagsViewController: TableViewControllerNavigateable { + @objc func navigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + navigateKeyCommandHandler(sender) + } + + func navigate(direction: TableViewNavigationDirection) { + if let indexPathForSelectedRow = tableView.indexPathForSelectedRow { + // navigate up/down on the current selected item + navigateToTag(direction: direction, indexPath: indexPathForSelectedRow) + } else { + // set first visible item selected + navigateToFirstVisibleTag() + } + } + + private func navigateToTag(direction: TableViewNavigationDirection, indexPath: IndexPath) { + guard let diffableDataSource = viewModel.diffableDataSource else { return } + let items = diffableDataSource.snapshot().itemIdentifiers + guard let selectedItem = diffableDataSource.itemIdentifier(for: indexPath), + let selectedItemIndex = items.firstIndex(of: selectedItem) else { + return + } + + let _navigateToItem: DiscoveryItem? = { + var index = selectedItemIndex + while 0.. 1 { + // drop first when visible not the first cell of table + visibleItems.removeFirst() + } + guard let item = visibleItems.first, let indexPath = diffableDataSource.indexPath(for: item) else { return } + let scrollPosition: UITableView.ScrollPosition = overrideNavigationScrollPosition ?? Self.navigateScrollPosition(tableView: tableView, indexPath: indexPath) + tableView.selectRow(at: indexPath, animated: true, scrollPosition: scrollPosition) + } + + static func validNavigateableItem(_ item: DiscoveryItem) -> Bool { + switch item { + case .hashtag: + return true + default: + return false + } + } + + func open() { + guard let indexPathForSelectedRow = tableView.indexPathForSelectedRow else { return } + guard let diffableDataSource = viewModel.diffableDataSource else { return } + guard let item = diffableDataSource.itemIdentifier(for: indexPathForSelectedRow) else { return } + + guard case let .hashtag(tag) = item else { return } + let hashtagTimelineViewModel = HashtagTimelineViewModel(context: context, hashtag: tag.name) + coordinator.present( + scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), + from: self, + transition: .show + ) + } +} diff --git a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel+Diffable.swift b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel+Diffable.swift index 0370f3f58..19241d2e6 100644 --- a/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel+Diffable.swift +++ b/Mastodon/Scene/Discovery/Hashtags/DiscoveryHashtagsViewModel+Diffable.swift @@ -32,7 +32,7 @@ extension DiscoveryHashtagsViewModel { snapshot.appendSections([.hashtags]) let items = hashtags.map { DiscoveryItem.hashtag($0) } - snapshot.appendItems(items, toSection: .hashtags) + snapshot.appendItems(items.removingDuplicates(), toSection: .hashtags) diffableDataSource.apply(snapshot) } diff --git a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift index 4042e2cd5..f73602ae4 100644 --- a/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift +++ b/Mastodon/Scene/Discovery/News/DiscoveryNewsViewController.swift @@ -131,3 +131,99 @@ extension DiscoveryNewsViewController: ScrollViewContainer { tableView } } + +extension DiscoveryNewsViewController { + override var keyCommands: [UIKeyCommand]? { + return navigationKeyCommands + } +} + +extension DiscoveryNewsViewController: TableViewControllerNavigateable { + + func navigate(direction: TableViewNavigationDirection) { + if let indexPathForSelectedRow = tableView.indexPathForSelectedRow { + // navigate up/down on the current selected item + navigateToLink(direction: direction, indexPath: indexPathForSelectedRow) + } else { + // set first visible item selected + navigateToFirstVisibleLink() + } + } + + private func navigateToLink(direction: TableViewNavigationDirection, indexPath: IndexPath) { + guard let diffableDataSource = viewModel.diffableDataSource else { return } + let items = diffableDataSource.snapshot().itemIdentifiers + guard let selectedItem = diffableDataSource.itemIdentifier(for: indexPath), + let selectedItemIndex = items.firstIndex(of: selectedItem) else { + return + } + + let _navigateToItem: DiscoveryItem? = { + var index = selectedItemIndex + while 0.. 1 { + // drop first when visible not the first cell of table + visibleItems.removeFirst() + } + guard let item = visibleItems.first, let indexPath = diffableDataSource.indexPath(for: item) else { return } + let scrollPosition: UITableView.ScrollPosition = overrideNavigationScrollPosition ?? Self.navigateScrollPosition(tableView: tableView, indexPath: indexPath) + tableView.selectRow(at: indexPath, animated: true, scrollPosition: scrollPosition) + } + + static func validNavigateableItem(_ item: DiscoveryItem) -> Bool { + switch item { + case .link: + return true + default: + return false + } + } + + func open() { + guard let indexPathForSelectedRow = tableView.indexPathForSelectedRow else { return } + guard let diffableDataSource = viewModel.diffableDataSource else { return } + guard let item = diffableDataSource.itemIdentifier(for: indexPathForSelectedRow) else { return } + + guard case let .link(link) = item else { return } + guard let url = URL(string: link.url) else { return } + coordinator.present( + scene: .safari(url: url), + from: self, + transition: .safariPresent(animated: true, completion: nil) + ) + } + + func navigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + navigateKeyCommandHandler(sender) + } + +} diff --git a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift index 259b21d36..a1d5b5e76 100644 --- a/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift +++ b/Mastodon/Scene/Discovery/Posts/DiscoveryPostsViewController.swift @@ -171,3 +171,20 @@ extension DiscoveryPostsViewController: DiscoveryIntroBannerViewDelegate { UserDefaults.shared.discoveryIntroBannerNeedsHidden = true } } + +extension DiscoveryPostsViewController { + override var keyCommands: [UIKeyCommand]? { + return navigationKeyCommands + statusNavigationKeyCommands + } +} + +// MARK: - StatusTableViewControllerNavigateable +extension DiscoveryPostsViewController: StatusTableViewControllerNavigateable { + @objc func navigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + navigateKeyCommandHandler(sender) + } + + @objc func statusKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + statusKeyCommandHandler(sender) + } +} diff --git a/Mastodon/Scene/Discovery/View/DiscoveryIntroBannerView.swift b/Mastodon/Scene/Discovery/View/DiscoveryIntroBannerView.swift index e3e1c4547..afc2cb7db 100644 --- a/Mastodon/Scene/Discovery/View/DiscoveryIntroBannerView.swift +++ b/Mastodon/Scene/Discovery/View/DiscoveryIntroBannerView.swift @@ -9,6 +9,7 @@ import os.log import UIKit import Combine import MastodonAsset +import MastodonLocalization public protocol DiscoveryIntroBannerViewDelegate: AnyObject { func discoveryIntroBannerView(_ bannerView: DiscoveryIntroBannerView, closeButtonDidPressed button: UIButton) @@ -26,7 +27,7 @@ public final class DiscoveryIntroBannerView: UIView { let label = UILabel() label.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 16, weight: .regular)) label.textColor = Asset.Colors.Label.primary.color - label.text = "These are the posts gaining traction in your corner of Mastodon." // TODO: i18n + label.text = L10n.Scene.Discovery.intro label.numberOfLines = 0 return label }() diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift index 3b8db5d56..02738747c 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewController.swift @@ -46,6 +46,8 @@ final class HashtagTimelineViewController: UIViewController, NeedsDependency, Me return tableView }() + let refreshControl = UIRefreshControl() + deinit { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s:", ((#file as NSString).lastPathComponent), #line, #function) } @@ -84,19 +86,28 @@ extension HashtagTimelineViewController { ]) tableView.delegate = self -// tableView.prefetchDataSource = self viewModel.setupDiffableDataSource( tableView: tableView, statusTableViewCellDelegate: self ) + tableView.refreshControl = refreshControl + refreshControl.addTarget(self, action: #selector(HashtagTimelineViewController.refreshControlValueChanged(_:)), for: .valueChanged) + viewModel.didLoadLatest + .receive(on: DispatchQueue.main) + .sink { [weak self] _ in + guard let self = self else { return } + self.refreshControl.endRefreshing() + } + .store(in: &disposeBag) + // setup batch fetch viewModel.listBatchFetchViewModel.setup(scrollView: tableView) viewModel.listBatchFetchViewModel.shouldFetch .receive(on: DispatchQueue.main) .sink { [weak self] _ in guard let self = self else { return } - self.viewModel.loadOldestStateMachine.enter(HashtagTimelineViewModel.LoadOldestState.Loading.self) + self.viewModel.stateMachine.enter(HashtagTimelineViewModel.State.Loading.self) } .store(in: &disposeBag) @@ -145,6 +156,13 @@ extension HashtagTimelineViewController { extension HashtagTimelineViewController { + @objc private func refreshControlValueChanged(_ sender: UIRefreshControl) { + guard viewModel.stateMachine.enter(HashtagTimelineViewModel.State.Reloading.self) else { + sender.endRefreshing() + return + } + } + @objc private func composeBarButtonItemPressed(_ sender: UIBarButtonItem) { os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else { return } @@ -158,27 +176,6 @@ extension HashtagTimelineViewController { } -// MARK: - TableViewCellHeightCacheableContainer -//extension HashtagTimelineViewController: TableViewCellHeightCacheableContainer { -// var cellFrameCache: NSCache { -// return viewModel.cellFrameCache -// } -//} - -//// MARK: - UIScrollViewDelegate -//extension HashtagTimelineViewController { -// func scrollViewDidScroll(_ scrollView: UIScrollView) { -// aspectScrollViewDidScroll(scrollView) -// } -//} - -//extension HashtagTimelineViewController: LoadMoreConfigurableTableViewContainer { -// typealias BottomLoaderTableViewCell = TimelineBottomLoaderTableViewCell -// typealias LoadingState = HashtagTimelineViewModel.LoadOldestState.Loading -// var loadMoreConfigurableTableView: UITableView { return tableView } -// var loadMoreConfigurableStateMachine: GKStateMachine { return viewModel.loadOldestStateMachine } -//} - // MARK: - UITableViewDelegate extension HashtagTimelineViewController: UITableViewDelegate, AutoGenerateTableViewDelegate { // sourcery:inline:HashtagTimelineViewController.AutoGenerateTableViewDelegate @@ -206,82 +203,23 @@ extension HashtagTimelineViewController: UITableViewDelegate, AutoGenerateTableV } // sourcery:end -// func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { -// return aspectTableView(tableView, estimatedHeightForRowAt: indexPath) -// } -// -// func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { -// aspectTableView(tableView, willDisplay: cell, forRowAt: indexPath) -// } -// -// func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) { -// aspectTableView(tableView, didEndDisplaying: cell, forRowAt: indexPath) -// } -// -// func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { -// aspectTableView(tableView, didSelectRowAt: indexPath) -// } -// -// func tableView(_ tableView: UITableView, contextMenuConfigurationForRowAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { -// return aspectTableView(tableView, contextMenuConfigurationForRowAt: indexPath, point: point) -// } -// -// func tableView(_ tableView: UITableView, previewForHighlightingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? { -// return aspectTableView(tableView, previewForHighlightingContextMenuWithConfiguration: configuration) -// } -// -// func tableView(_ tableView: UITableView, previewForDismissingContextMenuWithConfiguration configuration: UIContextMenuConfiguration) -> UITargetedPreview? { -// return aspectTableView(tableView, previewForDismissingContextMenuWithConfiguration: configuration) -// } -// -// func tableView(_ tableView: UITableView, willPerformPreviewActionForMenuWith configuration: UIContextMenuConfiguration, animator: UIContextMenuInteractionCommitAnimating) { -// aspectTableView(tableView, willPerformPreviewActionForMenuWith: configuration, animator: animator) -// } - } -// MARK: - UITableViewDataSourcePrefetching -//extension HashtagTimelineViewController: UITableViewDataSourcePrefetching { -// func tableView(_ tableView: UITableView, prefetchRowsAt indexPaths: [IndexPath]) { -// aspectTableView(tableView, prefetchRowsAt: indexPaths) -// } -//} - // MARK: - StatusTableViewCellDelegate extension HashtagTimelineViewController: StatusTableViewCellDelegate { } -// MARK: - AVPlayerViewControllerDelegate -//extension HashtagTimelineViewController: AVPlayerViewControllerDelegate { -// -// func playerViewController(_ playerViewController: AVPlayerViewController, willBeginFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) { -// aspectPlayerViewController(playerViewController, willBeginFullScreenPresentationWithAnimationCoordinator: coordinator) -// } -// -// func playerViewController(_ playerViewController: AVPlayerViewController, willEndFullScreenPresentationWithAnimationCoordinator coordinator: UIViewControllerTransitionCoordinator) { -// aspectPlayerViewController(playerViewController, willEndFullScreenPresentationWithAnimationCoordinator: coordinator) -// } -// -//} - -// MARK: - StatusTableViewCellDelegate -//extension HashtagTimelineViewController: StatusTableViewCellDelegate { -// weak var playerViewControllerDelegate: AVPlayerViewControllerDelegate? { return self } -// func parent() -> UIViewController { return self } -//} - -//extension HashtagTimelineViewController { -// override var keyCommands: [UIKeyCommand]? { -// return navigationKeyCommands + statusNavigationKeyCommands -// } -//} -// -//// MARK: - StatusTableViewControllerNavigateable -//extension HashtagTimelineViewController: StatusTableViewControllerNavigateable { -// @objc func navigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { -// navigateKeyCommandHandler(sender) -// } -// -// @objc func statusKeyCommandHandlerRelay(_ sender: UIKeyCommand) { -// statusKeyCommandHandler(sender) -// } -//} +extension HashtagTimelineViewController { + override var keyCommands: [UIKeyCommand]? { + return navigationKeyCommands + statusNavigationKeyCommands + } +} +// MARK: - StatusTableViewControllerNavigateable +extension HashtagTimelineViewController: StatusTableViewControllerNavigateable { + @objc func navigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + navigateKeyCommandHandler(sender) + } + + @objc func statusKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + statusKeyCommandHandler(sender) + } +} diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift index c71d195c7..fc80f4846 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+Diffable.swift @@ -27,6 +27,8 @@ extension HashtagTimelineViewModel { ) ) + stateMachine.enter(State.Reloading.self) + var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) diffableDataSource?.apply(snapshot) @@ -43,14 +45,17 @@ extension HashtagTimelineViewModel { let items = records.map { StatusItem.status(record: $0) } snapshot.appendItems(items, toSection: .main) - if let currentState = self.loadOldestStateMachine.currentState { + if let currentState = self.stateMachine.currentState { switch currentState { - case is LoadOldestState.Initial, - is LoadOldestState.Loading, - is LoadOldestState.Idle, - is LoadOldestState.Fail: - snapshot.appendItems([.bottomLoader], toSection: .main) - case is LoadOldestState.NoMore: + case is State.Initial, + is State.Reloading, + is State.Loading, + is State.Idle, + is State.Fail: + if !items.isEmpty { + snapshot.appendItems([.bottomLoader], toSection: .main) + } + case is State.NoMore: break default: assertionFailure() diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+LoadOldestState.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+State.swift similarity index 51% rename from Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+LoadOldestState.swift rename to Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+State.swift index eba85657b..6b75d3875 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+LoadOldestState.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel+State.swift @@ -1,5 +1,5 @@ // -// HashtagTimelineViewModel+LoadOldestState.swift +// HashtagTimelineViewModel+State.swift // Mastodon // // Created by BradGao on 2021/3/31. @@ -11,7 +11,7 @@ import GameplayKit import CoreDataStack extension HashtagTimelineViewModel { - class LoadOldestState: GKState, NamingState { + class State: GKState, NamingState { let logger = Logger(subsystem: "HashtagTimelineViewModel.LoadOldestState", category: "StateMachine") @@ -28,14 +28,14 @@ extension HashtagTimelineViewModel { } override func didEnter(from previousState: GKState?) { - let previousState = previousState as? HashtagTimelineViewModel.LoadOldestState + let previousState = previousState as? HashtagTimelineViewModel.State logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [\(self.id.uuidString)] enter \(self.name), previous: \(previousState?.name ?? "")") viewModel?.loadOldestStateMachinePublisher.send(self) } @MainActor - func enter(state: LoadOldestState.Type) { + func enter(state: State.Type) { stateMachine?.enter(state) } @@ -45,24 +45,96 @@ extension HashtagTimelineViewModel { } } -extension HashtagTimelineViewModel.LoadOldestState { - class Initial: HashtagTimelineViewModel.LoadOldestState { +extension HashtagTimelineViewModel.State { + class Initial: HashtagTimelineViewModel.State { override func isValidNextState(_ stateClass: AnyClass) -> Bool { - return stateClass == Loading.self + switch stateClass { + case is Reloading.Type: + return true + default: + return false + } } } - class Loading: HashtagTimelineViewModel.LoadOldestState { - var maxID: Status.ID? - + class Reloading: HashtagTimelineViewModel.State { override func isValidNextState(_ stateClass: AnyClass) -> Bool { - return stateClass == Fail.self || stateClass == Idle.self || stateClass == NoMore.self + switch stateClass { + case is Loading.Type: + return true + default: + return false + } } override func didEnter(from previousState: GKState?) { super.didEnter(from: previousState) - guard let viewModel = viewModel, let stateMachine = stateMachine else { return } + + stateMachine.enter(Loading.self) + } + } + + class Fail: HashtagTimelineViewModel.State { + override func isValidNextState(_ stateClass: AnyClass) -> Bool { + switch stateClass { + case is Loading.Type: + return true + default: + return false + } + } + + override func didEnter(from previousState: GKState?) { + super.didEnter(from: previousState) + guard let _ = viewModel, let stateMachine = stateMachine else { return } + + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: retry loading 3s later…", ((#file as NSString).lastPathComponent), #line, #function) + DispatchQueue.main.asyncAfter(deadline: .now() + 3) { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: retry loading", ((#file as NSString).lastPathComponent), #line, #function) + stateMachine.enter(Loading.self) + } + } + } + + class Idle: HashtagTimelineViewModel.State { + override func isValidNextState(_ stateClass: AnyClass) -> Bool { + switch stateClass { + case is Reloading.Type, is Loading.Type: + return true + default: + return false + } + } + } + + class Loading: HashtagTimelineViewModel.State { + var maxID: Status.ID? + + override func isValidNextState(_ stateClass: AnyClass) -> Bool { + switch stateClass { + case is Fail.Type: + return true + case is Idle.Type: + return true + case is NoMore.Type: + return true + default: + return false + } + } + + override func didEnter(from previousState: GKState?) { + super.didEnter(from: previousState) + guard let viewModel = viewModel, let stateMachine = stateMachine else { return } + + switch previousState { + case is Reloading: + maxID = nil + default: + break + } + guard let authenticationBox = viewModel.context.authenticationService.activeMastodonAuthenticationBox.value else { assertionFailure() stateMachine.enter(Fail.self) @@ -71,6 +143,8 @@ extension HashtagTimelineViewModel.LoadOldestState { // TODO: only set large count when using Wi-Fi let maxID = self.maxID + let isReloading = maxID == nil + Task { do { let response = try await viewModel.context.apiService.hashtagTimeline( @@ -79,24 +153,35 @@ extension HashtagTimelineViewModel.LoadOldestState { hashtag: viewModel.hashtag, authenticationBox: authenticationBox ) + + let newMaxID: String? = { + guard let maxID = response.link?.maxID else { return nil } + return maxID + }() - var hasMore = false + let hasMore: Bool = { + guard let newMaxID = newMaxID else { return false } + return newMaxID != maxID + }() - if let _maxID = response.link?.maxID, - _maxID != maxID - { - self.maxID = _maxID - hasMore = true + self.maxID = newMaxID + + var hasNewStatusesAppend = false + var statusIDs = isReloading ? [] : viewModel.fetchedResultsController.statusIDs.value + for status in response.value { + guard !statusIDs.contains(status.id) else { continue } + statusIDs.append(status.id) + hasNewStatusesAppend = true } - if hasMore { + + if hasNewStatusesAppend, hasMore { await enter(state: Idle.self) } else { await enter(state: NoMore.self) } - let statusIDs = response.value.map { $0.id } viewModel.fetchedResultsController.append(statusIDs: statusIDs) - + viewModel.didLoadLatest.send() } catch { logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch statues failed: \(error.localizedDescription)") await enter(state: Fail.self) @@ -104,22 +189,15 @@ extension HashtagTimelineViewModel.LoadOldestState { } // end Task } } - - class Fail: HashtagTimelineViewModel.LoadOldestState { - override func isValidNextState(_ stateClass: AnyClass) -> Bool { - return stateClass == Loading.self || stateClass == Idle.self - } - } - - class Idle: HashtagTimelineViewModel.LoadOldestState { - override func isValidNextState(_ stateClass: AnyClass) -> Bool { - return stateClass == Loading.self - } - } - class NoMore: HashtagTimelineViewModel.LoadOldestState { + class NoMore: HashtagTimelineViewModel.State { override func isValidNextState(_ stateClass: AnyClass) -> Bool { - return false + switch stateClass { + case is Reloading.Type: + return true + default: + return false + } } override func didEnter(from previousState: GKState?) { diff --git a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift index d63fad807..f22987273 100644 --- a/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift +++ b/Mastodon/Scene/HashtagTimeline/HashtagTimelineViewModel.swift @@ -36,19 +36,20 @@ final class HashtagTimelineViewModel { let didLoadLatest = PassthroughSubject() // bottom loader - private(set) lazy var loadOldestStateMachine: GKStateMachine = { + private(set) lazy var stateMachine: GKStateMachine = { // exclude timeline middle fetcher state let stateMachine = GKStateMachine(states: [ - LoadOldestState.Initial(viewModel: self), - LoadOldestState.Loading(viewModel: self), - LoadOldestState.Fail(viewModel: self), - LoadOldestState.Idle(viewModel: self), - LoadOldestState.NoMore(viewModel: self), + State.Initial(viewModel: self), + State.Reloading(viewModel: self), + State.Fail(viewModel: self), + State.Idle(viewModel: self), + State.Loading(viewModel: self), + State.NoMore(viewModel: self), ]) - stateMachine.enter(LoadOldestState.Initial.self) + stateMachine.enter(State.Initial.self) return stateMachine }() - lazy var loadOldestStateMachinePublisher = CurrentValueSubject(nil) + lazy var loadOldestStateMachinePublisher = CurrentValueSubject(nil) init(context: AppContext, hashtag: String) { self.context = context diff --git a/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift b/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift index b1b2280d8..550dae7cc 100644 --- a/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift +++ b/Mastodon/Scene/Onboarding/ConfirmEmail/MastodonConfirmEmailViewController.swift @@ -36,7 +36,7 @@ final class MastodonConfirmEmailViewController: UIViewController, NeedsDependenc let label = UILabel() label.font = UIFontMetrics(forTextStyle: .title1).scaledFont(for: UIFont.systemFont(ofSize: 20)) label.textColor = .secondaryLabel - label.text = L10n.Scene.ConfirmEmail.subtitle + label.text = L10n.Scene.ConfirmEmail.tapTheLinkWeEmailedToYouToVerifyYourAccount label.numberOfLines = 0 return label }() @@ -229,6 +229,11 @@ extension MastodonConfirmEmailViewController { } } +// MARK: - PanPopableViewController +extension MastodonConfirmEmailViewController: PanPopableViewController { + var isPanPopable: Bool { false } +} + // MARK: - OnboardingViewControllerAppearance extension MastodonConfirmEmailViewController: OnboardingViewControllerAppearance { } diff --git a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift index ffc7708f5..d05b446ae 100644 --- a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift +++ b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewController.swift @@ -92,7 +92,7 @@ extension MastodonPickServerViewController { tableView.topAnchor.constraint(equalTo: view.topAnchor), tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + tableView.bottomAnchor.constraint(equalTo: view.layoutMarginsGuide.bottomAnchor), ]) navigationActionView.translatesAutoresizingMaskIntoConstraints = false @@ -107,10 +107,10 @@ extension MastodonPickServerViewController { ]) navigationActionView - .observe(\.bounds, options: [.initial, .new]) { [weak self] navigationActionView, _ in + .observe(\.bounds, options: [.initial, .new]) { [weak self] _, _ in guard let self = self else { return } - let inset = navigationActionView.frame.height - self.tableView.contentInset.bottom = inset + let inset = self.navigationActionView.frame.height + self.viewModel.additionalTableViewInsets.bottom = inset } .store(in: &observations) @@ -149,7 +149,8 @@ extension MastodonPickServerViewController { KeyboardResponderService .configure( scrollView: tableView, - layoutNeedsUpdate: viewModel.viewDidAppear.eraseToAnyPublisher() + layoutNeedsUpdate: viewModel.viewDidAppear.eraseToAnyPublisher(), + additionalSafeAreaInsets: viewModel.$additionalTableViewInsets.eraseToAnyPublisher() ) .store(in: &disposeBag) diff --git a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel.swift b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel.swift index 749843880..b077cbbe1 100644 --- a/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel.swift +++ b/Mastodon/Scene/Onboarding/PickServer/MastodonPickServerViewModel.swift @@ -46,7 +46,8 @@ class MastodonPickServerViewModel: NSObject { let unindexedServers = CurrentValueSubject<[Mastodon.Entity.Server]?, Never>([]) // set nil when loading let viewWillAppear = PassthroughSubject() let viewDidAppear = CurrentValueSubject(Void()) - + @Published var additionalTableViewInsets: UIEdgeInsets = .zero + // output var diffableDataSource: UITableViewDiffableDataSource? private(set) lazy var loadIndexedServerStateMachine: GKStateMachine = { diff --git a/Mastodon/Scene/Onboarding/PickServer/View/PickServerServerSectionTableHeaderView.swift b/Mastodon/Scene/Onboarding/PickServer/View/PickServerServerSectionTableHeaderView.swift index 894cbdbdf..4e757cd1a 100644 --- a/Mastodon/Scene/Onboarding/PickServer/View/PickServerServerSectionTableHeaderView.swift +++ b/Mastodon/Scene/Onboarding/PickServer/View/PickServerServerSectionTableHeaderView.swift @@ -96,11 +96,13 @@ final class PickServerServerSectionTableHeaderView: UIView { textField.tintColor = Asset.Colors.Label.primary.color textField.textColor = Asset.Colors.Label.primary.color textField.adjustsFontForContentSizeCategory = true - textField.attributedPlaceholder = - NSAttributedString( - string: L10n.Scene.ServerPicker.Input.placeholder, - attributes: [.font: UIFont.systemFont(ofSize: 15, weight: .regular), - .foregroundColor: Asset.Colors.Label.secondary.color.withAlphaComponent(0.6)]) + textField.attributedPlaceholder = NSAttributedString( + string: L10n.Scene.ServerPicker.Input.searchServersOrEnterUrl, + attributes: [ + .font: UIFont.systemFont(ofSize: 15, weight: .regular), + .foregroundColor: Asset.Colors.Label.secondary.color.withAlphaComponent(0.6) + ] + ) textField.clearButtonMode = .whileEditing textField.autocapitalizationType = .none textField.autocorrectionType = .no diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterView.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterView.swift index 1a47de22f..2be7c61d7 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterView.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterView.swift @@ -197,9 +197,6 @@ struct MastodonRegisterView: View { } } - - - } struct WidthKey: PreferenceKey { diff --git a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel+Diffable.swift b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel+Diffable.swift index d8dc8943d..dda59843a 100644 --- a/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel+Diffable.swift +++ b/Mastodon/Scene/Onboarding/Register/MastodonRegisterViewModel+Diffable.swift @@ -23,7 +23,7 @@ extension MastodonRegisterViewModel { switch item { case .header(let domain): let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: OnboardingHeadlineTableViewCell.self), for: indexPath) as! OnboardingHeadlineTableViewCell - cell.titleLabel.text = L10n.Scene.Register.title(domain) + cell.titleLabel.text = L10n.Scene.Register.letsGetYouSetUpOnDomain(domain) cell.subTitleLabel.isHidden = true return cell case .avatar: diff --git a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift index 2389947a1..c64dd469f 100644 --- a/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift +++ b/Mastodon/Scene/Onboarding/Welcome/WelcomeViewController.swift @@ -50,7 +50,8 @@ final class WelcomeViewController: UIViewController, NeedsDependency { private(set) lazy var signUpButton: PrimaryActionButton = { let button = PrimaryActionButton() button.adjustsBackgroundImageWhenUserInterfaceStyleChanges = false - button.setTitle(L10n.Scene.Welcome.getStarted, for: .normal) + button.titleLabel?.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold)) + button.setTitle(L10n.Common.Controls.Actions.signUp, for: .normal) let backgroundImageColor: UIColor = .white let backgroundImageHighlightedColor: UIColor = UIColor(white: 0.8, alpha: 1.0) button.setBackgroundImage(.placeholder(color: backgroundImageColor), for: .normal) @@ -63,7 +64,7 @@ final class WelcomeViewController: UIViewController, NeedsDependency { private(set) lazy var signInButton: PrimaryActionButton = { let button = PrimaryActionButton() button.adjustsBackgroundImageWhenUserInterfaceStyleChanges = false - button.titleLabel?.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 15, weight: .semibold)) + button.titleLabel?.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold)) button.setTitle(L10n.Scene.Welcome.logIn, for: .normal) let backgroundImageColor = Asset.Scene.Welcome.signInButtonBackground.color let backgroundImageHighlightedColor = Asset.Scene.Welcome.signInButtonBackground.color.withAlphaComponent(0.8) diff --git a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController+DataSourceProvider.swift b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController+DataSourceProvider.swift new file mode 100644 index 000000000..c014a7900 --- /dev/null +++ b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController+DataSourceProvider.swift @@ -0,0 +1,34 @@ +// +// FamiliarFollowersViewController+DataSourceProvider.swift +// Mastodon +// +// Created by MainasuK on 2022-5-17. +// + +import UIKit + +extension FamiliarFollowersViewController: DataSourceProvider { + func item(from source: DataSourceItem.Source) async -> DataSourceItem? { + var _indexPath = source.indexPath + if _indexPath == nil, let cell = source.tableViewCell { + _indexPath = await self.indexPath(for: cell) + } + guard let indexPath = _indexPath else { return nil } + + guard let item = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { + return nil + } + + switch item { + case .user(let record): + return .user(record: record) + default: + return nil + } + } + + @MainActor + private func indexPath(for cell: UITableViewCell) async -> IndexPath? { + return tableView.indexPath(for: cell) + } +} diff --git a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController.swift b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController.swift new file mode 100644 index 000000000..1e60f7a90 --- /dev/null +++ b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewController.swift @@ -0,0 +1,91 @@ +// +// FamiliarFollowersViewController.swift +// Mastodon +// +// Created by MainasuK on 2022-5-17. +// + +import os.log +import UIKit +import Combine +import MastodonLocalization + +final class FamiliarFollowersViewController: UIViewController, NeedsDependency { + + let logger = Logger(subsystem: "FamiliarFollowersViewController", category: "ViewController") + + weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } + weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } + + var disposeBag = Set() + var viewModel: FamiliarFollowersViewModel! + + lazy var tableView: UITableView = { + let tableView = UITableView() + tableView.rowHeight = UITableView.automaticDimension + tableView.separatorStyle = .none + tableView.backgroundColor = .clear + return tableView + }() + + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + } + +} + +extension FamiliarFollowersViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + title = L10n.Scene.Familiarfollowers.title + + view.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor + ThemeService.shared.currentTheme + .receive(on: DispatchQueue.main) + .sink { [weak self] theme in + guard let self = self else { return } + self.view.backgroundColor = theme.secondarySystemBackgroundColor + } + .store(in: &disposeBag) + + tableView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(tableView) + NSLayoutConstraint.activate([ + tableView.topAnchor.constraint(equalTo: view.topAnchor), + tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + + tableView.delegate = self + viewModel.setupDiffableDataSource( + tableView: tableView, + userTableViewCellDelegate: self + ) + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + tableView.deselectRow(with: transitionCoordinator, animated: animated) + } + +} + +// MARK: - UITableViewDelegate +extension FamiliarFollowersViewController: UITableViewDelegate, AutoGenerateTableViewDelegate { + // sourcery:inline:FamiliarFollowersViewController.AutoGenerateTableViewDelegate + + // Generated using Sourcery + // DO NOT EDIT + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + aspectTableView(tableView, didSelectRowAt: indexPath) + } + + // sourcery:end +} + +// MARK: - UserTableViewCellDelegate +extension FamiliarFollowersViewController: UserTableViewCellDelegate { } diff --git a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel+Diffable.swift b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel+Diffable.swift new file mode 100644 index 000000000..5e995bf21 --- /dev/null +++ b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel+Diffable.swift @@ -0,0 +1,39 @@ +// +// FamiliarFollowersViewModel+Diffable.swift +// Mastodon +// +// Created by MainasuK on 2022-5-17. +// + +import UIKit + +extension FamiliarFollowersViewModel { + func setupDiffableDataSource( + tableView: UITableView, + userTableViewCellDelegate: UserTableViewCellDelegate? + ) { + diffableDataSource = UserSection.diffableDataSource( + tableView: tableView, + context: context, + configuration: UserSection.Configuration( + userTableViewCellDelegate: userTableViewCellDelegate + ) + ) + + userFetchedResultsController.$records + .receive(on: DispatchQueue.main) + .sink { [weak self] records in + guard let self = self else { return } + guard let diffableDataSource = self.diffableDataSource else { return } + + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.main]) + let items = records.map { UserItem.user(record: $0) } + snapshot.appendItems(items, toSection: .main) + + diffableDataSource.apply(snapshot, animatingDifferences: false) + } + .store(in: &disposeBag) + } + +} diff --git a/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel.swift b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel.swift new file mode 100644 index 000000000..544f8a062 --- /dev/null +++ b/Mastodon/Scene/Profile/FamiliarFollowers/FamiliarFollowersViewModel.swift @@ -0,0 +1,49 @@ +// +// FamiliarFollowersViewModel.swift +// Mastodon +// +// Created by MainasuK on 2022-5-17. +// + +import UIKit +import Combine +import MastodonSDK +import CoreDataStack + +final class FamiliarFollowersViewModel { + + var disposeBag = Set() + + // input + let context: AppContext + let userFetchedResultsController: UserFetchedResultsController + + @Published var familiarFollowers: Mastodon.Entity.FamiliarFollowers? + + // output + var diffableDataSource: UITableViewDiffableDataSource? + + init(context: AppContext) { + self.context = context + self.userFetchedResultsController = UserFetchedResultsController( + managedObjectContext: context.managedObjectContext, + domain: nil, + additionalPredicate: nil + ) + // end init + + context.authenticationService.activeMastodonAuthenticationBox + .map { $0?.domain } + .assign(to: \.domain, on: userFetchedResultsController) + .store(in: &disposeBag) + + $familiarFollowers + .map { familiarFollowers -> [MastodonUser.ID] in + guard let familiarFollowers = familiarFollowers else { return [] } + return familiarFollowers.accounts.map { $0.id } + } + .assign(to: \.userIDs, on: userFetchedResultsController) + .store(in: &disposeBag) + } + +} diff --git a/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift b/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift index 68f1d0de1..decc1ee97 100644 --- a/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift +++ b/Mastodon/Scene/Profile/Follower/FollowerListViewController.swift @@ -9,6 +9,7 @@ import os.log import UIKit import GameplayKit import Combine +import MastodonLocalization final class FollowerListViewController: UIViewController, NeedsDependency { @@ -42,6 +43,8 @@ extension FollowerListViewController { override func viewDidLoad() { super.viewDidLoad() + title = L10n.Scene.Follower.title + view.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor ThemeService.shared.currentTheme .receive(on: DispatchQueue.main) diff --git a/Mastodon/Scene/Profile/Following/FollowingListViewController.swift b/Mastodon/Scene/Profile/Following/FollowingListViewController.swift index 7272a2db4..c125b0214 100644 --- a/Mastodon/Scene/Profile/Following/FollowingListViewController.swift +++ b/Mastodon/Scene/Profile/Following/FollowingListViewController.swift @@ -9,6 +9,7 @@ import os.log import UIKit import GameplayKit import Combine +import MastodonLocalization final class FollowingListViewController: UIViewController, NeedsDependency { @@ -42,6 +43,8 @@ extension FollowingListViewController { override func viewDidLoad() { super.viewDidLoad() + title = L10n.Scene.Following.title + view.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor ThemeService.shared.currentTheme .receive(on: DispatchQueue.main) @@ -81,12 +84,18 @@ extension FollowingListViewController { viewModel.domain.removeDuplicates().eraseToAnyPublisher(), viewModel.userID.removeDuplicates().eraseToAnyPublisher() ) - .receive(on: DispatchQueue.main) - .sink { [weak self] _ in - guard let self = self else { return } - self.viewModel.stateMachine.enter(FollowingListViewModel.State.Reloading.self) - } - .store(in: &disposeBag) + .receive(on: DispatchQueue.main) + .sink { [weak self] _ in + guard let self = self else { return } + self.viewModel.stateMachine.enter(FollowingListViewModel.State.Reloading.self) + } + .store(in: &disposeBag) + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + tableView.deselectRow(with: transitionCoordinator, animated: animated) } } diff --git a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift index 78430cb36..1a6e10537 100644 --- a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift +++ b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift @@ -407,8 +407,14 @@ extension ProfileHeaderView { override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) - - updateLayoutMargins() + + // workaround enter background breaking the layout issue + switch UIApplication.shared.applicationState { + case .active: + updateLayoutMargins() + default: + break + } } } diff --git a/Mastodon/Scene/Profile/ProfileViewController.swift b/Mastodon/Scene/Profile/ProfileViewController.swift index b376ebcf9..4c3f9820a 100644 --- a/Mastodon/Scene/Profile/ProfileViewController.swift +++ b/Mastodon/Scene/Profile/ProfileViewController.swift @@ -13,8 +13,9 @@ import MetaTextKit import MastodonAsset import MastodonLocalization import MastodonUI -import Tabman import CoreDataStack +import Tabman +import Pageboy protocol ProfileViewModelEditable { func isEdited() -> Bool @@ -1155,25 +1156,28 @@ extension ProfileViewController: ScrollViewContainer { } } -//extension ProfileViewController { -// -// override var keyCommands: [UIKeyCommand]? { -// if !viewModel.isEditing.value { -// return segmentedControlNavigateKeyCommands -// } -// -// return nil -// } -// -//} +extension ProfileViewController { + + override var keyCommands: [UIKeyCommand]? { + if !viewModel.isEditing.value { + return pageboyNavigateKeyCommands + } + + return nil + } + +} + +// MARK: - PageboyNavigateable +extension ProfileViewController: PageboyNavigateable { + + var navigateablePageViewController: PageboyViewController { + return profileSegmentedViewController.pagingViewController + } + + @objc func pageboyNavigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { + pageboyNavigateKeyCommandHandler(sender) + } + +} -// MARK: - SegmentedControlNavigateable -//extension ProfileViewController: SegmentedControlNavigateable { -// var navigateableSegmentedControl: UISegmentedControl { -// profileHeaderViewController.pageSegmentedControl -// } -// -// @objc func segmentedControlNavigateKeyCommandHandlerRelay(_ sender: UIKeyCommand) { -// segmentedControlNavigateKeyCommandHandler(sender) -// } -//} diff --git a/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewModel.swift b/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewModel.swift index e5220ef79..67a0ca93d 100644 --- a/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewModel.swift +++ b/Mastodon/Scene/Profile/Segmented/Paging/ProfilePagingViewModel.swift @@ -44,7 +44,7 @@ final class ProfilePagingViewModel: NSObject { let barItems: [TMBarItemable] = { let items = [ TMBarItem(title: L10n.Scene.Profile.SegmentedControl.posts), - TMBarItem(title: L10n.Scene.Profile.SegmentedControl.postsAndReplies), // TODO: i18n + TMBarItem(title: L10n.Scene.Profile.SegmentedControl.postsAndReplies), TMBarItem(title: L10n.Scene.Profile.SegmentedControl.media), TMBarItem(title: L10n.Scene.Profile.SegmentedControl.about), ] diff --git a/Mastodon/Scene/Profile/UserLIst/FavoritedBy/FavoritedByViewController+DataSourceProvider.swift b/Mastodon/Scene/Profile/UserLIst/FavoritedBy/FavoritedByViewController+DataSourceProvider.swift new file mode 100644 index 000000000..437873d36 --- /dev/null +++ b/Mastodon/Scene/Profile/UserLIst/FavoritedBy/FavoritedByViewController+DataSourceProvider.swift @@ -0,0 +1,34 @@ +// +// FavoritedByViewController+DataSourceProvider.swift +// Mastodon +// +// Created by MainasuK on 2022-5-17. +// + +import UIKit + +extension FavoritedByViewController: DataSourceProvider { + func item(from source: DataSourceItem.Source) async -> DataSourceItem? { + var _indexPath = source.indexPath + if _indexPath == nil, let cell = source.tableViewCell { + _indexPath = await self.indexPath(for: cell) + } + guard let indexPath = _indexPath else { return nil } + + guard let item = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { + return nil + } + + switch item { + case .user(let record): + return .user(record: record) + default: + return nil + } + } + + @MainActor + private func indexPath(for cell: UITableViewCell) async -> IndexPath? { + return tableView.indexPath(for: cell) + } +} diff --git a/Mastodon/Scene/Profile/UserLIst/FavoritedBy/FavoritedByViewController.swift b/Mastodon/Scene/Profile/UserLIst/FavoritedBy/FavoritedByViewController.swift new file mode 100644 index 000000000..0e2bc64ed --- /dev/null +++ b/Mastodon/Scene/Profile/UserLIst/FavoritedBy/FavoritedByViewController.swift @@ -0,0 +1,109 @@ +// +// FavoritedByViewController.swift +// Mastodon +// +// Created by MainasuK on 2022-5-17. +// + +import os.log +import UIKit +import GameplayKit +import Combine +import MastodonLocalization + +final class FavoritedByViewController: UIViewController, NeedsDependency { + + let logger = Logger(subsystem: "FavoritedByViewController", category: "ViewController") + + weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } + weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } + + var disposeBag = Set() + var viewModel: UserListViewModel! + + lazy var tableView: UITableView = { + let tableView = UITableView() + tableView.rowHeight = UITableView.automaticDimension + tableView.separatorStyle = .none + tableView.backgroundColor = .clear + return tableView + }() + + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + } + +} + +extension FavoritedByViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + #if DEBUG + switch viewModel.kind { + case .favoritedBy: break + default: assertionFailure() + } + #endif + + title = L10n.Scene.FavoritedBy.title + + view.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor + ThemeService.shared.currentTheme + .receive(on: DispatchQueue.main) + .sink { [weak self] theme in + guard let self = self else { return } + self.view.backgroundColor = theme.secondarySystemBackgroundColor + } + .store(in: &disposeBag) + + tableView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(tableView) + NSLayoutConstraint.activate([ + tableView.topAnchor.constraint(equalTo: view.topAnchor), + tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + + tableView.delegate = self + viewModel.setupDiffableDataSource( + tableView: tableView, + userTableViewCellDelegate: self + ) + + // setup batch fetch + viewModel.listBatchFetchViewModel.setup(scrollView: tableView) + viewModel.listBatchFetchViewModel.shouldFetch + .receive(on: DispatchQueue.main) + .sink { [weak self] _ in + guard let self = self else { return } + self.viewModel.stateMachine.enter(UserListViewModel.State.Loading.self) + } + .store(in: &disposeBag) + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + tableView.deselectRow(with: transitionCoordinator, animated: animated) + } + +} + +// MARK: - UITableViewDelegate +extension FavoritedByViewController: UITableViewDelegate, AutoGenerateTableViewDelegate { + // sourcery:inline:FavoritedByViewController.AutoGenerateTableViewDelegate + + // Generated using Sourcery + // DO NOT EDIT + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + aspectTableView(tableView, didSelectRowAt: indexPath) + } + + // sourcery:end +} + +// MARK: - UserTableViewCellDelegate +extension FavoritedByViewController: UserTableViewCellDelegate { } diff --git a/Mastodon/Scene/Profile/UserLIst/RebloggedBy/RebloggedByViewController+DataSourceProvider.swift b/Mastodon/Scene/Profile/UserLIst/RebloggedBy/RebloggedByViewController+DataSourceProvider.swift new file mode 100644 index 000000000..04d5d2596 --- /dev/null +++ b/Mastodon/Scene/Profile/UserLIst/RebloggedBy/RebloggedByViewController+DataSourceProvider.swift @@ -0,0 +1,34 @@ +// +// RebloggedByViewController+DataSourceProvider.swift +// Mastodon +// +// Created by MainasuK on 2022-5-17. +// + +import UIKit + +extension RebloggedByViewController: DataSourceProvider { + func item(from source: DataSourceItem.Source) async -> DataSourceItem? { + var _indexPath = source.indexPath + if _indexPath == nil, let cell = source.tableViewCell { + _indexPath = await self.indexPath(for: cell) + } + guard let indexPath = _indexPath else { return nil } + + guard let item = viewModel.diffableDataSource?.itemIdentifier(for: indexPath) else { + return nil + } + + switch item { + case .user(let record): + return .user(record: record) + default: + return nil + } + } + + @MainActor + private func indexPath(for cell: UITableViewCell) async -> IndexPath? { + return tableView.indexPath(for: cell) + } +} diff --git a/Mastodon/Scene/Profile/UserLIst/RebloggedBy/RebloggedByViewController.swift b/Mastodon/Scene/Profile/UserLIst/RebloggedBy/RebloggedByViewController.swift new file mode 100644 index 000000000..78988bb41 --- /dev/null +++ b/Mastodon/Scene/Profile/UserLIst/RebloggedBy/RebloggedByViewController.swift @@ -0,0 +1,109 @@ +// +// RebloggedByViewController.swift +// Mastodon +// +// Created by MainasuK on 2022-5-17. +// + +import os.log +import UIKit +import GameplayKit +import Combine +import MastodonLocalization + +final class RebloggedByViewController: UIViewController, NeedsDependency { + + let logger = Logger(subsystem: "RebloggedByViewController", category: "ViewController") + + weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } + weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } + + var disposeBag = Set() + var viewModel: UserListViewModel! + + lazy var tableView: UITableView = { + let tableView = UITableView() + tableView.rowHeight = UITableView.automaticDimension + tableView.separatorStyle = .none + tableView.backgroundColor = .clear + return tableView + }() + + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + } + +} + +extension RebloggedByViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + #if DEBUG + switch viewModel.kind { + case .rebloggedBy: break + default: assertionFailure() + } + #endif + + title = L10n.Scene.RebloggedBy.title + + view.backgroundColor = ThemeService.shared.currentTheme.value.secondarySystemBackgroundColor + ThemeService.shared.currentTheme + .receive(on: DispatchQueue.main) + .sink { [weak self] theme in + guard let self = self else { return } + self.view.backgroundColor = theme.secondarySystemBackgroundColor + } + .store(in: &disposeBag) + + tableView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(tableView) + NSLayoutConstraint.activate([ + tableView.topAnchor.constraint(equalTo: view.topAnchor), + tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + + tableView.delegate = self + viewModel.setupDiffableDataSource( + tableView: tableView, + userTableViewCellDelegate: self + ) + + // setup batch fetch + viewModel.listBatchFetchViewModel.setup(scrollView: tableView) + viewModel.listBatchFetchViewModel.shouldFetch + .receive(on: DispatchQueue.main) + .sink { [weak self] _ in + guard let self = self else { return } + self.viewModel.stateMachine.enter(UserListViewModel.State.Loading.self) + } + .store(in: &disposeBag) + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + tableView.deselectRow(with: transitionCoordinator, animated: animated) + } + +} + +// MARK: - UITableViewDelegate +extension RebloggedByViewController: UITableViewDelegate, AutoGenerateTableViewDelegate { + // sourcery:inline:RebloggedByViewController.AutoGenerateTableViewDelegate + + // Generated using Sourcery + // DO NOT EDIT + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + aspectTableView(tableView, didSelectRowAt: indexPath) + } + + // sourcery:end +} + +// MARK: - UserTableViewCellDelegate +extension RebloggedByViewController: UserTableViewCellDelegate { } diff --git a/Mastodon/Scene/Profile/UserLIst/UserListViewModel+Diffable.swift b/Mastodon/Scene/Profile/UserLIst/UserListViewModel+Diffable.swift new file mode 100644 index 000000000..acd225f0c --- /dev/null +++ b/Mastodon/Scene/Profile/UserLIst/UserListViewModel+Diffable.swift @@ -0,0 +1,71 @@ +// +// UserListViewModel+Diffable.swift +// Mastodon +// +// Created by MainasuK on 2022-5-17. +// + +import UIKit +import MastodonAsset +import MastodonLocalization + +extension UserListViewModel { + @MainActor + func setupDiffableDataSource( + tableView: UITableView, + userTableViewCellDelegate: UserTableViewCellDelegate? + ) { + diffableDataSource = UserSection.diffableDataSource( + tableView: tableView, + context: context, + configuration: UserSection.Configuration( + userTableViewCellDelegate: userTableViewCellDelegate + ) + ) + + // workaround to append loader wrong animation issue + // set empty section to make update animation top-to-bottom style + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.main]) + snapshot.appendItems([.bottomLoader], toSection: .main) + if #available(iOS 15.0, *) { + diffableDataSource?.applySnapshotUsingReloadData(snapshot, completion: nil) + } else { + // Fallback on earlier versions + diffableDataSource?.apply(snapshot, animatingDifferences: false) + } + + // trigger initial loading + stateMachine.enter(UserListViewModel.State.Reloading.self) + + userFetchedResultsController.$records + .receive(on: DispatchQueue.main) + .sink { [weak self] records in + guard let self = self else { return } + guard let diffableDataSource = self.diffableDataSource else { return } + + var snapshot = NSDiffableDataSourceSnapshot() + snapshot.appendSections([.main]) + let items = records.map { UserItem.user(record: $0) } + snapshot.appendItems(items, toSection: .main) + + if let currentState = self.stateMachine.currentState { + switch currentState { + case is State.Initial, is State.Idle, is State.Reloading, is State.Loading, is State.Fail: + snapshot.appendItems([.bottomLoader], toSection: .main) + case is State.NoMore: + if items.isEmpty { + snapshot.appendItems([.bottomHeader(text: L10n.Scene.Search.Searching.EmptyState.noResults)], toSection: .main) + } + default: + assertionFailure() + } + } else { + snapshot.appendItems([.bottomLoader], toSection: .main) + } + + diffableDataSource.apply(snapshot, animatingDifferences: false) + } + .store(in: &disposeBag) + } +} diff --git a/Mastodon/Scene/Profile/UserLIst/UserListViewModel+State.swift b/Mastodon/Scene/Profile/UserLIst/UserListViewModel+State.swift new file mode 100644 index 000000000..90b928235 --- /dev/null +++ b/Mastodon/Scene/Profile/UserLIst/UserListViewModel+State.swift @@ -0,0 +1,211 @@ +// +// UserListViewModel+State.swift +// Mastodon +// +// Created by MainasuK on 2022-5-17. +// + +import os.log +import Foundation +import GameplayKit +import MastodonSDK + +extension UserListViewModel { + class State: GKState, NamingState { + + let logger = Logger(subsystem: "UserListViewModel.State", category: "StateMachine") + + let id = UUID() + + var name: String { + String(describing: Self.self) + } + + weak var viewModel: UserListViewModel? + + init(viewModel: UserListViewModel) { + self.viewModel = viewModel + } + + override func didEnter(from previousState: GKState?) { + super.didEnter(from: previousState) + let previousState = previousState as? UserListViewModel.State + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [\(self.id.uuidString)] enter \(self.name), previous: \(previousState?.name ?? "")") + } + + @MainActor + func enter(state: State.Type) { + stateMachine?.enter(state) + } + + deinit { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [\(self.id.uuidString)] \(self.name)") + } + } +} + +extension UserListViewModel.State { + class Initial: UserListViewModel.State { + override func isValidNextState(_ stateClass: AnyClass) -> Bool { + guard let _ = viewModel else { return false } + switch stateClass { + case is Reloading.Type: + return true + default: + return false + } + } + } + + class Reloading: UserListViewModel.State { + override func isValidNextState(_ stateClass: AnyClass) -> Bool { + switch stateClass { + case is Loading.Type: + return true + default: + return false + } + } + + override func didEnter(from previousState: GKState?) { + super.didEnter(from: previousState) + guard let viewModel = viewModel, let stateMachine = stateMachine else { return } + + // reset + viewModel.userFetchedResultsController.userIDs = [] + + stateMachine.enter(Loading.self) + } + } + + class Fail: UserListViewModel.State { + + override func isValidNextState(_ stateClass: AnyClass) -> Bool { + switch stateClass { + case is Loading.Type: + return true + default: + return false + } + } + + override func didEnter(from previousState: GKState?) { + super.didEnter(from: previousState) + guard let _ = viewModel, let stateMachine = stateMachine else { return } + + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: retry loading 3s later…", ((#file as NSString).lastPathComponent), #line, #function) + DispatchQueue.main.asyncAfter(deadline: .now() + 3) { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: retry loading", ((#file as NSString).lastPathComponent), #line, #function) + stateMachine.enter(Loading.self) + } + } + } + + class Idle: UserListViewModel.State { + override func isValidNextState(_ stateClass: AnyClass) -> Bool { + switch stateClass { + case is Reloading.Type, is Loading.Type: + return true + default: + return false + } + } + } + + class Loading: UserListViewModel.State { + + var maxID: String? + + override func isValidNextState(_ stateClass: AnyClass) -> Bool { + switch stateClass { + case is Fail.Type: + return true + case is Idle.Type: + return true + case is NoMore.Type: + return true + default: + return false + } + } + + override func didEnter(from previousState: GKState?) { + super.didEnter(from: previousState) + + if previousState is Reloading { + maxID = nil + } + + guard let viewModel = viewModel, let stateMachine = stateMachine else { return } + guard let authenticationBox = viewModel.context.authenticationService.activeMastodonAuthenticationBox.value else { + stateMachine.enter(Fail.self) + return + } + + let maxID = self.maxID + + Task { + do { + let response: Mastodon.Response.Content<[Mastodon.Entity.Account]> + switch viewModel.kind { + case .favoritedBy(let status): + response = try await viewModel.context.apiService.favoritedBy( + status: status, + query: .init(maxID: maxID, limit: nil), + authenticationBox: authenticationBox + ) + case .rebloggedBy(let status): + response = try await viewModel.context.apiService.rebloggedBy( + status: status, + query: .init(maxID: maxID, limit: nil), + authenticationBox: authenticationBox + ) + } + + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch \(response.value.count) accounts") + + var hasNewAppend = false + var userIDs = viewModel.userFetchedResultsController.userIDs + for user in response.value { + guard !userIDs.contains(user.id) else { continue } + userIDs.append(user.id) + hasNewAppend = true + } + + let maxID = response.link?.maxID + + if hasNewAppend, maxID != nil { + await enter(state: Idle.self) + } else { + await enter(state: NoMore.self) + } + self.maxID = maxID + viewModel.userFetchedResultsController.userIDs = userIDs + + } catch { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch following fail: \(error.localizedDescription)") + await enter(state: Fail.self) + } + } // end Task + } // end func didEnter + } + + class NoMore: UserListViewModel.State { + override func isValidNextState(_ stateClass: AnyClass) -> Bool { + switch stateClass { + case is Reloading.Type: + return true + default: + return false + } + } + + override func didEnter(from previousState: GKState?) { + super.didEnter(from: previousState) + + guard let viewModel = viewModel else { return } + // trigger reload + viewModel.userFetchedResultsController.records = viewModel.userFetchedResultsController.records + } + } +} diff --git a/Mastodon/Scene/Profile/UserLIst/UserListViewModel.swift b/Mastodon/Scene/Profile/UserLIst/UserListViewModel.swift new file mode 100644 index 000000000..472c497f6 --- /dev/null +++ b/Mastodon/Scene/Profile/UserLIst/UserListViewModel.swift @@ -0,0 +1,66 @@ +// +// UserListViewModel.swift +// Mastodon +// +// Created by MainasuK on 2022-5-17. +// + +import os.log +import UIKit +import Combine +import CoreDataStack +import GameplayKit + +final class UserListViewModel { + + let logger = Logger(subsystem: "UserListViewModel", category: "ViewModel") + var disposeBag = Set() + + // input + let context: AppContext + let kind: Kind + let userFetchedResultsController: UserFetchedResultsController + let listBatchFetchViewModel = ListBatchFetchViewModel() + + // output + var diffableDataSource: UITableViewDiffableDataSource! + @MainActor private(set) lazy var stateMachine: GKStateMachine = { + let stateMachine = GKStateMachine(states: [ + State.Initial(viewModel: self), + State.Fail(viewModel: self), + State.Idle(viewModel: self), + State.Loading(viewModel: self), + State.NoMore(viewModel: self), + ]) + stateMachine.enter(State.Initial.self) + return stateMachine + }() + + init( + context: AppContext, + kind: Kind + ) { + self.context = context + self.kind = kind + self.userFetchedResultsController = UserFetchedResultsController( + managedObjectContext: context.managedObjectContext, + domain: nil, + additionalPredicate: nil + ) + // end init + + context.authenticationService.activeMastodonAuthenticationBox + .map { $0?.domain } + .assign(to: \.domain, on: userFetchedResultsController) + .store(in: &disposeBag) + } + +} + +extension UserListViewModel { + // TODO: refactor follower and following into user list + enum Kind { + case rebloggedBy(status: ManagedObjectRecord) + case favoritedBy(status: ManagedObjectRecord) + } +} diff --git a/Mastodon/Scene/Report/Report/ReportViewController.swift b/Mastodon/Scene/Report/Report/ReportViewController.swift new file mode 100644 index 000000000..854ea96b6 --- /dev/null +++ b/Mastodon/Scene/Report/Report/ReportViewController.swift @@ -0,0 +1,195 @@ +// +// ReportViewController.swift +// Mastodon +// +// Created by ihugo on 2021/4/20. +// + +import os.log +import UIKit +import Combine +import CoreDataStack +import MastodonAsset +import MastodonLocalization + +class ReportViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { + + let logger = Logger(subsystem: "ReportViewController", category: "ViewController") + + var disposeBag = Set() + private var observations = Set() + + weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } + weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } + + var viewModel: ReportViewModel! + + lazy var cancelBarButtonItem = UIBarButtonItem( + barButtonSystemItem: .cancel, + target: self, + action: #selector(ReportViewController.cancelBarButtonItemDidPressed(_:)) + ) + + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + } + +} + +extension ReportViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + setupAppearance() + defer { setupNavigationBarBackgroundView() } + + navigationItem.rightBarButtonItem = cancelBarButtonItem + + viewModel.reportReasonViewModel.delegate = self + viewModel.reportServerRulesViewModel.delegate = self + viewModel.reportStatusViewModel.delegate = self + viewModel.reportSupplementaryViewModel.delegate = self + + let reportReasonViewController = ReportReasonViewController() + reportReasonViewController.context = context + reportReasonViewController.coordinator = coordinator + reportReasonViewController.viewModel = viewModel.reportReasonViewModel + + addChild(reportReasonViewController) + reportReasonViewController.view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(reportReasonViewController.view) + reportReasonViewController.didMove(toParent: self) + NSLayoutConstraint.activate([ + reportReasonViewController.view.topAnchor.constraint(equalTo: view.topAnchor), + reportReasonViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), + reportReasonViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), + reportReasonViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + } + +} + +extension ReportViewController { + + @objc private func cancelBarButtonItemDidPressed(_ sender: UIBarButtonItem) { + dismiss(animated: true, completion: nil) + } + +} + +// MARK: - UIAdaptivePresentationControllerDelegate +extension ReportViewController: UIAdaptivePresentationControllerDelegate { + func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool { + return viewModel.isReportSuccess + } +} + +// MARK: - ReportReasonViewControllerDelegate +extension ReportViewController: ReportReasonViewControllerDelegate { + func reportReasonViewController(_ viewController: ReportReasonViewController, nextButtonPressed button: UIButton) { + guard let reason = viewController.viewModel.selectReason else { return } + switch reason { + case .dislike: + let reportResultViewModel = ReportResultViewModel( + context: context, + user: viewModel.user, + isReported: false + ) + coordinator.present( + scene: .reportResult(viewModel: reportResultViewModel), + from: self, + transition: .show + ) + case .violateRule: + coordinator.present( + scene: .reportServerRules(viewModel: viewModel.reportServerRulesViewModel), + from: self, + transition: .show + ) + case .spam, .other: + coordinator.present( + scene: .reportStatus(viewModel: viewModel.reportStatusViewModel), + from: self, + transition: .show + ) + } + } +} + +// MARK: - ReportServerRulesViewControllerDelegate +extension ReportViewController: ReportServerRulesViewControllerDelegate { + func reportServerRulesViewController(_ viewController: ReportServerRulesViewController, nextButtonPressed button: UIButton) { + guard !viewController.viewModel.selectRules.isEmpty else { + return + } + + coordinator.present( + scene: .reportStatus(viewModel: viewModel.reportStatusViewModel), + from: self, + transition: .show + ) + } +} + +// MARK: - ReportStatusViewControllerDelegate +extension ReportViewController: ReportStatusViewControllerDelegate { + func reportStatusViewController(_ viewController: ReportStatusViewController, skipButtonDidPressed button: UIButton) { + coordinateToReportSupplementary() + } + + func reportStatusViewController(_ viewController: ReportStatusViewController, nextButtonDidPressed button: UIButton) { + coordinateToReportSupplementary() + } + + private func coordinateToReportSupplementary() { + coordinator.present( + scene: .reportSupplementary(viewModel: viewModel.reportSupplementaryViewModel), + from: self, + transition: .show + ) + } +} + +// MARK: - ReportSupplementaryViewControllerDelegate +extension ReportViewController: ReportSupplementaryViewControllerDelegate { + func reportSupplementaryViewController(_ viewController: ReportSupplementaryViewController, skipButtonDidPressed button: UIButton) { + report() + } + + func reportSupplementaryViewController(_ viewController: ReportSupplementaryViewController, nextButtonDidPressed button: UIButton) { + report() + } + + private func report() { + Task { @MainActor in + do { + let _ = try await viewModel.report() + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): report success") + + let reportResultViewModel = ReportResultViewModel( + context: context, + user: viewModel.user, + isReported: true + ) + + coordinator.present( + scene: .reportResult(viewModel: reportResultViewModel), + from: self, + transition: .show + ) + + } catch { + let alertController = UIAlertController(for: error, title: nil, preferredStyle: .alert) + let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default, handler: nil) + alertController.addAction(okAction) + self.coordinator.present( + scene: .alertController(alertController: alertController), + from: nil, + transition: .alertController(animated: true, completion: nil) + ) + } + } // end Task + } + +} diff --git a/Mastodon/Scene/Report/Report/ReportViewModel.swift b/Mastodon/Scene/Report/Report/ReportViewModel.swift new file mode 100644 index 000000000..81ba20125 --- /dev/null +++ b/Mastodon/Scene/Report/Report/ReportViewModel.swift @@ -0,0 +1,179 @@ +// +// ReportViewModel.swift +// Mastodon +// +// Created by ihugo on 2021/4/19. +// + +import Combine +import CoreData +import CoreDataStack +import Foundation +import GameplayKit +import MastodonSDK +import OrderedCollections +import os.log +import UIKit +import MastodonLocalization + +class ReportViewModel { + + var disposeBag = Set() + + let reportReasonViewModel: ReportReasonViewModel + let reportServerRulesViewModel: ReportServerRulesViewModel + let reportStatusViewModel: ReportStatusViewModel + let reportSupplementaryViewModel: ReportSupplementaryViewModel + + // input + let context: AppContext + let user: ManagedObjectRecord + let status: ManagedObjectRecord? + + // output + @Published var isReporting = false + @Published var isReportSuccess = false + + init( + context: AppContext, + user: ManagedObjectRecord, + status: ManagedObjectRecord? + ) { + self.context = context + self.user = user + self.status = status + self.reportReasonViewModel = ReportReasonViewModel(context: context) + self.reportServerRulesViewModel = ReportServerRulesViewModel(context: context) + self.reportStatusViewModel = ReportStatusViewModel(context: context, user: user, status: status) + self.reportSupplementaryViewModel = ReportSupplementaryViewModel(context: context, user: user) + // end init + + guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else { + return + } + + // setup reason viewModel + if status != nil { + reportReasonViewModel.headline = L10n.Scene.Report.StepOne.whatsWrongWithThisPost + } else { + Task { @MainActor in + let managedObjectContext = context.managedObjectContext + let _username: String? = try? await managedObjectContext.perform { + let user = user.object(in: managedObjectContext) + return user?.acctWithDomain + } + if let username = _username { + reportReasonViewModel.headline = L10n.Scene.Report.StepOne.whatsWrongWithThisUsername(username) + } else { + reportReasonViewModel.headline = L10n.Scene.Report.StepOne.whatsWrongWithThisAccount + } + } // end Task + } + + // bind server rules + Task { @MainActor in + do { + let response = try await context.apiService.instance(domain: authenticationBox.domain) + .timeout(3, scheduler: DispatchQueue.main) + .singleOutput() + let rules = response.value.rules ?? [] + reportReasonViewModel.serverRules = rules + reportServerRulesViewModel.serverRules = rules + } catch { + reportReasonViewModel.serverRules = [] + reportServerRulesViewModel.serverRules = [] + } + } // end Task + + $isReporting + .assign(to: &reportSupplementaryViewModel.$isBusy) + } + +} + +extension ReportViewModel { + @MainActor + func report() async throws { + guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value, + !isReporting + else { + assertionFailure() + return + } + + let managedObjectContext = context.managedObjectContext + let _query: Mastodon.API.Reports.FileReportQuery? = try await managedObjectContext.perform { + guard let user = self.user.object(in: managedObjectContext) else { return nil } + + // the status picker is essential step in report flow + // only check isSkip or not + let statusIDs: [Status.ID]? = { + if self.reportStatusViewModel.isSkip { + let _id: Status.ID? = self.reportStatusViewModel.status.flatMap { record -> Status.ID? in + guard let status = record.object(in: managedObjectContext) else { return nil } + return status.id + } + return _id.flatMap { [$0] } + } else { + return self.reportStatusViewModel.selectStatuses.compactMap { record -> Status.ID? in + guard let status = record.object(in: managedObjectContext) else { return nil } + return status.id + } + } + }() + + // the user comment is essential step in report flow + // only check isSkip or not + let comment: String? = { + let _comment = self.reportSupplementaryViewModel.isSkip ? nil : self.reportSupplementaryViewModel.commentContext.comment + if let comment = _comment, !comment.isEmpty { + return comment + } else { + return nil + } + }() + return Mastodon.API.Reports.FileReportQuery( + accountID: user.id, + statusIDs: statusIDs, + comment: comment, + forward: true, + category: { + switch self.reportReasonViewModel.selectReason { + case .dislike: return nil + case .spam: return .spam + case .violateRule: return .violation + case .other: return .other + case .none: return nil + } + }(), + ruleIDs: { + switch self.reportReasonViewModel.selectReason { + case .violateRule: + let ruleIDs = self.reportServerRulesViewModel.selectRules.map { $0.id }.sorted() + return ruleIDs + default: + return nil + } + }() + ) + } + + guard let query = _query else { return } + + do { + isReporting = true + #if DEBUG + try await Task.sleep(nanoseconds: .second * 3) + #else + let _ = try await context.apiService.report( + query: query, + authenticationBox: authenticationBox + ) + #endif + isReportSuccess = true + } catch { + isReporting = false + throw error + } + } +} diff --git a/Mastodon/Scene/Report/ReportReason/ReportReasonView.swift b/Mastodon/Scene/Report/ReportReason/ReportReasonView.swift new file mode 100644 index 000000000..8ee04311e --- /dev/null +++ b/Mastodon/Scene/Report/ReportReason/ReportReasonView.swift @@ -0,0 +1,110 @@ +// +// ReportReasonView.swift +// Mastodon +// +// Created by MainasuK on 2022-5-10. +// + +import UIKit +import SwiftUI +import MastodonLocalization +import MastodonSDK +import MastodonAsset + +struct ReportReasonView: View { + + @ObservedObject var viewModel: ReportReasonViewModel + + var body: some View { + ScrollView(.vertical) { + HStack { + VStack(alignment: .leading, spacing: 8) { + Text(L10n.Scene.Report.StepOne.step1Of4) + .foregroundColor(Color(Asset.Colors.Label.secondary.color)) + .font(Font(UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 17, weight: .regular)) as CTFont)) + Text(viewModel.headline) + .foregroundColor(Color(Asset.Colors.Label.primary.color)) + .font(Font(UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 28, weight: .bold)) as CTFont)) + Text(L10n.Scene.Report.StepOne.selectTheBestMatch) + .foregroundColor(Color(Asset.Colors.Label.secondary.color)) + .font(Font(UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 17, weight: .regular)) as CTFont)) + } + Spacer() + } + .padding() + + VStack(spacing: 16) { + if let serverRules = viewModel.serverRules { + ForEach(ReportReasonViewModel.Reason.allCases, id: \.self) { reason in + switch reason { + case .violateRule where serverRules.isEmpty: + EmptyView() + default: + ReportReasonRowView(reason: reason, isSelect: reason == viewModel.selectReason) + .contentShape(Rectangle()) + .onTapGesture { + viewModel.selectReason = reason + } + } + } + } else { + ProgressView() + } + } + .padding() + .transition(.opacity) + .animation(.easeInOut) + + Spacer() + .frame(minHeight: viewModel.bottomPaddingHeight) + } + .background( + Color(viewModel.backgroundColor) + ) + } + +} + +struct ReportReasonRowView: View { + + var reason: ReportReasonViewModel.Reason + var isSelect: Bool + + var body: some View { + HStack(spacing: 14) { + Image(systemName: isSelect ? "checkmark.circle.fill" : "circle") + .resizable() + .frame(width: 28, height: 28, alignment: .center) + VStack(alignment: .leading, spacing: 4) { + Text(reason.title) + .foregroundColor(Color(Asset.Colors.Label.primary.color)) + .font(.headline) + Text(reason.subtitle) + .font(.subheadline) + .foregroundColor(Color(Asset.Colors.Label.secondary.color)) + } + Spacer() + } + } + +} + +#if DEBUG +struct ReportReasonView_Previews: PreviewProvider { + static var previews: some View { + Group { + NavigationView { + ReportReasonView(viewModel: ReportReasonViewModel(context: .shared)) + .navigationBarTitle(Text("")) + .navigationBarTitleDisplayMode(.inline) + } + NavigationView { + ReportReasonView(viewModel: ReportReasonViewModel(context: .shared)) + .navigationBarTitle(Text("")) + .navigationBarTitleDisplayMode(.inline) + } + .preferredColorScheme(.dark) + } + } +} +#endif diff --git a/Mastodon/Scene/Report/ReportReason/ReportReasonViewController.swift b/Mastodon/Scene/Report/ReportReason/ReportReasonViewController.swift new file mode 100644 index 000000000..ac5d9e797 --- /dev/null +++ b/Mastodon/Scene/Report/ReportReason/ReportReasonViewController.swift @@ -0,0 +1,104 @@ +// +// ReportReasonViewController.swift +// Mastodon +// +// Created by MainasuK on 2022-5-10. +// + +import os.log +import UIKit +import SwiftUI +import Combine +import MastodonUI +import MastodonAsset +import MastodonLocalization + +protocol ReportReasonViewControllerDelegate: AnyObject { + func reportReasonViewController(_ viewController: ReportReasonViewController, nextButtonPressed button: UIButton) +} + +final class ReportReasonViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { + + let logger = Logger(subsystem: "ReportReasonViewController", category: "ViewController") + + weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } + weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } + + var disposeBag = Set() + private var observations = Set() + + var viewModel: ReportReasonViewModel! + private(set) lazy var reportReasonView = ReportReasonView(viewModel: viewModel) + + let navigationActionView: NavigationActionView = { + let navigationActionView = NavigationActionView() + navigationActionView.backgroundColor = Asset.Scene.Onboarding.background.color + navigationActionView.hidesBackButton = true + return navigationActionView + }() + + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + } + +} + +extension ReportReasonViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + setupAppearance() + defer { setupNavigationBarBackgroundView() } + + let hostingViewController = UIHostingController(rootView: reportReasonView) + hostingViewController.view.preservesSuperviewLayoutMargins = true + addChild(hostingViewController) + hostingViewController.view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(hostingViewController.view) + NSLayoutConstraint.activate([ + hostingViewController.view.topAnchor.constraint(equalTo: view.topAnchor), + hostingViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), + hostingViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), + hostingViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + + navigationActionView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(navigationActionView) + defer { + view.bringSubviewToFront(navigationActionView) + } + NSLayoutConstraint.activate([ + navigationActionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + navigationActionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + view.bottomAnchor.constraint(equalTo: navigationActionView.bottomAnchor), + ]) + + navigationActionView + .observe(\.bounds, options: [.initial, .new]) { [weak self] navigationActionView, _ in + guard let self = self else { return } + let inset = navigationActionView.frame.height + self.viewModel.bottomPaddingHeight = inset + } + .store(in: &observations) + + viewModel.$selectReason + .map { $0 != nil } + .assign(to: \.isEnabled, on: navigationActionView.nextButton) + .store(in: &disposeBag) + + navigationActionView.nextButton.addTarget(self, action: #selector(ReportReasonViewController.nextButtonPressed(_:)), for: .touchUpInside) + } + +} + +extension ReportReasonViewController { + + @objc private func nextButtonPressed(_ sender: UIButton) { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") + + assert(viewModel.delegate != nil) + viewModel.delegate?.reportReasonViewController(self, nextButtonPressed: sender) + } + +} diff --git a/Mastodon/Scene/Report/ReportReason/ReportReasonViewModel.swift b/Mastodon/Scene/Report/ReportReason/ReportReasonViewModel.swift new file mode 100644 index 000000000..91715cba8 --- /dev/null +++ b/Mastodon/Scene/Report/ReportReason/ReportReasonViewModel.swift @@ -0,0 +1,84 @@ +// +// ReportReasonViewModel.swift +// Mastodon +// +// Created by MainasuK on 2022-5-10. +// + +import UIKit +import SwiftUI +import MastodonAsset +import MastodonSDK +import MastodonLocalization + +final class ReportReasonViewModel: ObservableObject { + + weak var delegate: ReportReasonViewControllerDelegate? + + // input + let context: AppContext + + @Published var headline = L10n.Scene.Report.StepOne.whatsWrongWithThisAccount + @Published var serverRules: [Mastodon.Entity.Instance.Rule]? + + @Published var bottomPaddingHeight: CGFloat = .zero + @Published var backgroundColor: UIColor = Asset.Scene.Report.background.color + + // output + @Published var selectReason: Reason? + + init(context: AppContext) { + self.context = context + // end init + } + +} + +extension ReportReasonViewModel { + enum Reason: Hashable, CaseIterable { + case dislike + case spam + case violateRule + case other + + var title: String { + switch self { + case .dislike: + return L10n.Scene.Report.StepOne.iDontLikeIt + case .spam: + return L10n.Scene.Report.StepOne.itsSpam + case .violateRule: + return L10n.Scene.Report.StepOne.itViolatesServerRules + case .other: + return L10n.Scene.Report.StepOne.itsSomethingElse + } + } + + var subtitle: String { + switch self { + case .dislike: + return L10n.Scene.Report.StepOne.itIsNotSomethingYouWantToSee + case .spam: + return L10n.Scene.Report.StepOne.maliciousLinksFakeEngagementOrRepetetiveReplies + case .violateRule: + return L10n.Scene.Report.StepOne.youAreAwareThatItBreaksSpecificRules + case .other: + return L10n.Scene.Report.StepOne.theIssueDoesNotFitIntoOtherCategories + } + } + + // do not i18n this + var rawValue: String { + switch self { + case .dislike: + return "I don’t like it" + case .spam: + return "It’s spam" + case .violateRule: + return "It violates server rules" + case .other: + return "It’s something else" + } + } + } +} diff --git a/Mastodon/Scene/Report/ReportResult/ReportResultView.swift b/Mastodon/Scene/Report/ReportResult/ReportResultView.swift new file mode 100644 index 000000000..b3bbe7938 --- /dev/null +++ b/Mastodon/Scene/Report/ReportResult/ReportResultView.swift @@ -0,0 +1,218 @@ +// +// ReportResultView.swift +// Mastodon +// +// Created by MainasuK on 2022-5-11. +// + +import UIKit +import SwiftUI +import MastodonSDK +import MastodonUI +import MastodonAsset +import MastodonLocalization +import CoreDataStack + +struct ReportResultView: View { + + @ObservedObject var viewModel: ReportResultViewModel + + var avatarView: some View { + HStack { + Spacer() + ZStack { + AnimatedImage(imageURL: viewModel.avatarURL) + .frame(width: 106, height: 106, alignment: .center) + .background(Color(UIColor.systemFill)) + .cornerRadius(27) + Text(L10n.Scene.Report.reported) + .font(Font(FontFamily.Staatliches.regular.font(size: 49) as CTFont)) + .foregroundColor(Color(Asset.Scene.Report.reportBanner.color)) + .padding(EdgeInsets(top: 0, leading: 10, bottom: -2, trailing: 10)) + .background(Color(viewModel.backgroundColor)) + .cornerRadius(7) + .padding(7) + .background(Color(Asset.Scene.Report.reportBanner.color)) + .cornerRadius(12) + .rotationEffect(.degrees(-8)) + .offset(x: 0, y: -5) + } + Spacer() + } + .padding() + } + + var body: some View { + ScrollView(.vertical) { + HStack { + VStack(alignment: .leading, spacing: 8) { + Text(viewModel.headline) + .foregroundColor(Color(Asset.Colors.Label.primary.color)) + .font(Font(UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 28, weight: .bold)) as CTFont)) + if viewModel.isReported { + avatarView + Text(verbatim: L10n.Scene.Report.StepFinal.whileWeReviewThisYouCanTakeActionAgainstUser("@\(viewModel.username)")) + .foregroundColor(Color(Asset.Colors.Label.secondary.color)) + .font(Font(UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 17, weight: .regular)) as CTFont)) + } else { + Text(verbatim: L10n.Scene.Report.StepFinal.whenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience) + .foregroundColor(Color(Asset.Colors.Label.secondary.color)) + .font(Font(UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 17, weight: .regular)) as CTFont)) + } + } + Spacer() + } + .padding() + + VStack(spacing: 32) { + // Follow + VStack(alignment: .leading, spacing: 4) { + Text(L10n.Scene.Report.StepFinal.unfollowUser("@\(viewModel.username)")) + .font(.headline) + .foregroundColor(Color(Asset.Colors.Label.primary.color)) + ReportActionButton( + action: { + viewModel.followActionPublisher.send() + }, + title: viewModel.relationshipViewModel.isFollowing ? L10n.Scene.Report.StepFinal.unfollow : L10n.Scene.Report.StepFinal.unfollowed, + isBusy: viewModel.isRequestFollow + ) + } + + // Mute + VStack(alignment: .leading, spacing: 4) { + Text(L10n.Scene.Report.StepFinal.muteUser("@\(viewModel.username)")) + .font(.headline) + .foregroundColor(Color(Asset.Colors.Label.primary.color)) + Text(verbatim: L10n.Scene.Report.StepFinal.youWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted) + .foregroundColor(Color(Asset.Colors.Label.secondary.color)) + .font(Font(UIFontMetrics(forTextStyle: .subheadline).scaledFont(for: .systemFont(ofSize: 13, weight: .regular)) as CTFont)) + ReportActionButton( + action: { + viewModel.muteActionPublisher.send() + }, + title: viewModel.relationshipViewModel.isMuting ? L10n.Common.Controls.Friendship.muted : L10n.Common.Controls.Friendship.mute, + isBusy: viewModel.isRequestMute + ) + } + + // Block + VStack(alignment: .leading, spacing: 4) { + Text(L10n.Scene.Report.StepFinal.blockUser("@\(viewModel.username)")) + .font(.headline) + .foregroundColor(Color(Asset.Colors.Label.primary.color)) + Text(verbatim: L10n.Scene.Report.StepFinal.theyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked) + .foregroundColor(Color(Asset.Colors.Label.secondary.color)) + .font(Font(UIFontMetrics(forTextStyle: .subheadline).scaledFont(for: .systemFont(ofSize: 13, weight: .regular)) as CTFont)) + ReportActionButton( + action: { + viewModel.blockActionPublisher.send() + }, + title: viewModel.relationshipViewModel.isBlocking ? L10n.Common.Controls.Friendship.blocked : L10n.Common.Controls.Friendship.block, + isBusy: viewModel.isRequestBlock + ) + } + } + .padding() + + Spacer() + .frame(minHeight: viewModel.bottomPaddingHeight) + } + .background( + Color(viewModel.backgroundColor) + ) + } + +} + +struct ReportActionButton: View { + + var action: () -> Void + var title: String + var isBusy: Bool + + var body: some View { + Button { + action() + } label: { + ZStack { + ProgressView() + .opacity(isBusy ? 1 : 0) + .progressViewStyle(CircularProgressViewStyle(tint: .gray)) + Text(title) + .font(.headline) + .foregroundColor(Color(UIColor.black)) + .opacity(isBusy ? 0 : 1) + } + .frame(maxWidth: .infinity) + .padding() + .background(Color(UIColor.white)) // using white for Light & Dark + .cornerRadius(10) + .shadow(color: .black.opacity(0.1), radius: 2, x: 0, y: 1) + } + } + +} + +#if DEBUG +struct ReportResultView_Previews: PreviewProvider { + + static func viewModel(isReported: Bool) -> ReportResultViewModel { + let context = AppContext.shared + let request = MastodonUser.sortedFetchRequest + request.fetchLimit = 1 + + let property = MastodonUser.Property( + identifier: "1", + domain: "domain.com", + id: "1", + acct: "@user@domain.com", + username: "user", + displayName: "User", + avatar: "", + avatarStatic: "", + header: "", + headerStatic: "", + note: "", + url: "", + statusesCount: Int64(100), + followingCount: Int64(100), + followersCount: Int64(100), + locked: false, + bot: false, + suspended: false, + createdAt: Date(), + updatedAt: Date(), + emojis: [], + fields: [] + ) + let user = try! context.managedObjectContext.fetch(request).first ?? MastodonUser.insert(into: context.managedObjectContext, property: property) + + return ReportResultViewModel( + context: context, + user: .init(objectID: user.objectID), + isReported: isReported + ) + } + static var previews: some View { + Group { + NavigationView { + ReportResultView(viewModel: viewModel(isReported: true)) + .navigationBarTitle(Text("")) + .navigationBarTitleDisplayMode(.inline) + } + NavigationView { + ReportResultView(viewModel: viewModel(isReported: false)) + .navigationBarTitle(Text("")) + .navigationBarTitleDisplayMode(.inline) + } + NavigationView { + ReportResultView(viewModel: viewModel(isReported: true)) + .navigationBarTitle(Text("")) + .navigationBarTitleDisplayMode(.inline) + } + .preferredColorScheme(.dark) + } + } +} +#endif diff --git a/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift b/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift index 26f56b98d..957760f38 100644 --- a/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift +++ b/Mastodon/Scene/Report/ReportResult/ReportResultViewController.swift @@ -7,6 +7,7 @@ import os.log import UIKit +import SwiftUI import Combine import MastodonAsset import MastodonLocalization @@ -20,22 +21,13 @@ final class ReportResultViewController: UIViewController, NeedsDependency, Repor weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } var viewModel: ReportResultViewModel! - - let tableView: UITableView = { - let tableView = ControlContainableTableView() - tableView.backgroundColor = Asset.Scene.Report.background.color - tableView.rowHeight = UITableView.automaticDimension - tableView.separatorStyle = .none - tableView.backgroundColor = .clear - tableView.keyboardDismissMode = .onDrag - tableView.allowsMultipleSelection = true - if #available(iOS 15.0, *) { - tableView.sectionHeaderTopPadding = .leastNonzeroMagnitude - } else { - // Fallback on earlier versions - } - return tableView - }() + private(set) lazy var reportResultView = ReportResultView(viewModel: viewModel) + + lazy var doneBarButtonItem = UIBarButtonItem( + barButtonSystemItem: .done, + target: self, + action: #selector(ReportResultViewController.doneBarButtonItemDidPressed(_:)) + ) let navigationActionView: NavigationActionView = { let navigationActionView = NavigationActionView() @@ -60,21 +52,20 @@ extension ReportResultViewController { defer { setupNavigationBarBackgroundView() } navigationItem.hidesBackButton = true + navigationItem.rightBarButtonItem = doneBarButtonItem - tableView.translatesAutoresizingMaskIntoConstraints = false - view.addSubview(tableView) + let hostingViewController = UIHostingController(rootView: reportResultView) + hostingViewController.view.preservesSuperviewLayoutMargins = true + addChild(hostingViewController) + hostingViewController.view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(hostingViewController.view) NSLayoutConstraint.activate([ - tableView.topAnchor.constraint(equalTo: view.topAnchor), - tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), - tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), - tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor), + hostingViewController.view.topAnchor.constraint(equalTo: view.topAnchor), + hostingViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), + hostingViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), + hostingViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), ]) - tableView.delegate = self - viewModel.setupDiffableDataSource( - tableView: tableView - ) - navigationActionView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(navigationActionView) defer { @@ -90,18 +81,93 @@ extension ReportResultViewController { .observe(\.bounds, options: [.initial, .new]) { [weak self] navigationActionView, _ in guard let self = self else { return } let inset = navigationActionView.frame.height - self.tableView.contentInset.bottom = inset - self.tableView.verticalScrollIndicatorInsets.bottom = inset + self.viewModel.bottomPaddingHeight = inset } .store(in: &observations) navigationActionView.nextButton.addTarget(self, action: #selector(ReportSupplementaryViewController.nextButtonDidPressed(_:)), for: .touchUpInside) + + viewModel.followActionPublisher + .throttle(for: 0.3, scheduler: DispatchQueue.main, latest: false) + .sink { [weak self] in + guard let self = self else { return } + guard let authenticationBox = self.context.authenticationService.activeMastodonAuthenticationBox.value else { + return + } + Task { @MainActor in + guard !self.viewModel.isRequestFollow else { return } + self.viewModel.isRequestFollow = true + do { + try await DataSourceFacade.responseToUserFollowAction( + dependency: self, + user: self.viewModel.user, + authenticationBox: authenticationBox + ) + } catch { + // handle error + } + self.viewModel.isRequestFollow = false + } // end Task + } + .store(in: &disposeBag) + + viewModel.muteActionPublisher + .throttle(for: 0.3, scheduler: DispatchQueue.main, latest: false) + .sink { [weak self] in + guard let self = self else { return } + guard let authenticationBox = self.context.authenticationService.activeMastodonAuthenticationBox.value else { + return + } + Task { @MainActor in + guard !self.viewModel.isRequestMute else { return } + self.viewModel.isRequestMute = true + do { + try await DataSourceFacade.responseToUserMuteAction( + dependency: self, + user: self.viewModel.user, + authenticationBox: authenticationBox + ) + } catch { + // handle error + } + self.viewModel.isRequestMute = false + } // end Task + } + .store(in: &disposeBag) + + viewModel.blockActionPublisher + .throttle(for: 0.3, scheduler: DispatchQueue.main, latest: false) + .sink { [weak self] in + guard let self = self else { return } + guard let authenticationBox = self.context.authenticationService.activeMastodonAuthenticationBox.value else { + return + } + Task { @MainActor in + guard !self.viewModel.isRequestBlock else { return } + self.viewModel.isRequestBlock = true + do { + try await DataSourceFacade.responseToUserBlockAction( + dependency: self, + user: self.viewModel.user, + authenticationBox: authenticationBox + ) + } catch { + // handle error + } + self.viewModel.isRequestBlock = false + } // end Task + } + .store(in: &disposeBag) } } extension ReportResultViewController { + + @objc func doneBarButtonItemDidPressed(_ sender: UIButton) { + dismiss(animated: true, completion: nil) + } @objc func nextButtonDidPressed(_ sender: UIButton) { dismiss(animated: true, completion: nil) @@ -109,5 +175,7 @@ extension ReportResultViewController { } -// MARK: - UITableViewDelegate -extension ReportResultViewController: UITableViewDelegate { } +// MARK: - PanPopableViewController +extension ReportResultViewController: PanPopableViewController { + var isPanPopable: Bool { false } +} diff --git a/Mastodon/Scene/Report/ReportResult/ReportResultViewModel+Diffable.swift b/Mastodon/Scene/Report/ReportResult/ReportResultViewModel+Diffable.swift deleted file mode 100644 index a9c1272df..000000000 --- a/Mastodon/Scene/Report/ReportResult/ReportResultViewModel+Diffable.swift +++ /dev/null @@ -1,37 +0,0 @@ -// -// ReportResultViewModel+Diffable.swift -// Mastodon -// -// Created by MainasuK on 2022-2-8. -// - -import UIKit -import Combine -import CoreData -import CoreDataStack -import MastodonAsset -import MastodonLocalization - -extension ReportResultViewModel { - - static let reportItemHeaderContext = ReportItem.HeaderContext( - primaryLabelText: "Thanks for reporting, we’ll look into this.", - secondaryLabelText: "" - ) - - func setupDiffableDataSource( - tableView: UITableView - ) { - diffableDataSource = ReportSection.diffableDataSource( - tableView: tableView, - context: context, - configuration: ReportSection.Configuration() - ) - - var snapshot = NSDiffableDataSourceSnapshot() - snapshot.appendSections([.main]) - snapshot.appendItems([.header(context: ReportResultViewModel.reportItemHeaderContext)], toSection: .main) - snapshot.appendItems([.result(record: user)], toSection: .main) - diffableDataSource?.apply(snapshot) - } -} diff --git a/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift b/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift index 79fec4936..67d7475dd 100644 --- a/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift +++ b/Mastodon/Scene/Report/ReportResult/ReportResultViewModel.swift @@ -12,25 +12,60 @@ import Foundation import MastodonSDK import os.log import UIKit +import MastodonAsset +import MastodonUI +import MastodonLocalization -class ReportResultViewModel { +class ReportResultViewModel: ObservableObject { var disposeBag = Set() // input let context: AppContext let user: ManagedObjectRecord + let isReported: Bool + + var headline: String { + isReported ? L10n.Scene.Report.reportSentTitle : L10n.Scene.Report.StepFinal.dontWantToSeeThis + } + @Published var bottomPaddingHeight: CGFloat = .zero + @Published var backgroundColor: UIColor = Asset.Scene.Report.background.color + + @Published var isRequestFollow = false + @Published var isRequestMute = false + @Published var isRequestBlock = false // output - var diffableDataSource: UITableViewDiffableDataSource? + @Published var avatarURL: URL? + @Published var username: String = "" + + let relationshipViewModel = RelationshipViewModel() + let muteActionPublisher = PassthroughSubject() + let followActionPublisher = PassthroughSubject() + let blockActionPublisher = PassthroughSubject() init( context: AppContext, - user: ManagedObjectRecord + user: ManagedObjectRecord, + isReported: Bool ) { self.context = context self.user = user + self.isReported = isReported // end init + + Task { @MainActor in + guard let user = user.object(in: context.managedObjectContext) else { return } + guard let me = context.authenticationService.activeMastodonAuthenticationBox.value?.authenticationRecord.object(in: context.managedObjectContext)?.user else { return } + self.relationshipViewModel.user = user + self.relationshipViewModel.me = me + + self.avatarURL = user.avatarImageURL() + self.username = user.acctWithDomain + + } // end Task } } + + diff --git a/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesView.swift b/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesView.swift new file mode 100644 index 000000000..50db9c89b --- /dev/null +++ b/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesView.swift @@ -0,0 +1,107 @@ +// +// ReportServerRulesView.swift +// Mastodon +// +// Created by MainasuK on 2022-5-10. +// + +import UIKit +import SwiftUI +import MastodonLocalization +import MastodonSDK +import MastodonAsset + +struct ReportServerRulesView: View { + + @ObservedObject var viewModel: ReportServerRulesViewModel + + var body: some View { + ScrollView(.vertical) { + HStack { + VStack(alignment: .leading, spacing: 8) { + Text(L10n.Scene.Report.StepTwo.step2Of4) + .foregroundColor(Color(Asset.Colors.Label.secondary.color)) + .font(Font(UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 17, weight: .regular)) as CTFont)) + Text(viewModel.headline) + .foregroundColor(Color(Asset.Colors.Label.primary.color)) + .font(Font(UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 28, weight: .bold)) as CTFont)) + Text(L10n.Scene.Report.StepTwo.selectAllThatApply) + .foregroundColor(Color(Asset.Colors.Label.secondary.color)) + .font(Font(UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 17, weight: .regular)) as CTFont)) + } + Spacer() + } + .padding() + + VStack(spacing: 32) { + ForEach(viewModel.serverRules, id: \.self) { rule in + ReportServerRulesRowView( + title: rule.text, + isSelect: viewModel.selectRules.contains(rule) + ) + .background( + Color(viewModel.backgroundColor) + ) + .onTapGesture { + if viewModel.selectRules.contains(rule) { + viewModel.selectRules.remove(rule) + } else { + viewModel.selectRules.insert(rule) + } + } + } + } + .padding() + .transition(.opacity) + .animation(.easeInOut) + + Spacer() + .frame(minHeight: viewModel.bottomPaddingHeight) + } + .background( + Color(viewModel.backgroundColor) + ) + } + +} + +struct ReportServerRulesRowView: View { + + var title: String + var isSelect: Bool + + var body: some View { + HStack(spacing: 14) { + Image(systemName: isSelect ? "checkmark.square.fill" : "square") + .resizable() + .frame(width: 28, height: 28, alignment: .center) + VStack(alignment: .leading, spacing: 4) { + Text(title) + .foregroundColor(Color(Asset.Colors.Label.primary.color)) + .font(.headline) + } + Spacer() + } + } + +} + +#if DEBUG +struct ReportServerRulesView_Previews: PreviewProvider { + static var previews: some View { + Group { + NavigationView { + ReportServerRulesView(viewModel: ReportServerRulesViewModel(context: .shared)) + .navigationBarTitle(Text("")) + .navigationBarTitleDisplayMode(.inline) + } + NavigationView { + ReportServerRulesView(viewModel: ReportServerRulesViewModel(context: .shared)) + .navigationBarTitle(Text("")) + .navigationBarTitleDisplayMode(.inline) + } + .preferredColorScheme(.dark) + } + } +} +#endif diff --git a/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesViewController.swift b/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesViewController.swift new file mode 100644 index 000000000..73a47496c --- /dev/null +++ b/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesViewController.swift @@ -0,0 +1,114 @@ +// +// ReportServerRulesViewController.swift +// Mastodon +// +// Created by MainasuK on 2022-5-10. +// + +import os.log +import UIKit +import SwiftUI +import Combine +import MastodonUI +import MastodonAsset +import MastodonLocalization + +protocol ReportServerRulesViewControllerDelegate: AnyObject { + func reportServerRulesViewController(_ viewController: ReportServerRulesViewController, nextButtonPressed button: UIButton) +} + +final class ReportServerRulesViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { + + let logger = Logger(subsystem: "ReportReasonViewController", category: "ViewController") + + weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } + weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } + + var disposeBag = Set() + private var observations = Set() + + var viewModel: ReportServerRulesViewModel! + private(set) lazy var reportServerRulesView = ReportServerRulesView(viewModel: viewModel) + + lazy var cancelBarButtonItem = UIBarButtonItem( + barButtonSystemItem: .cancel, + target: self, + action: #selector(ReportServerRulesViewController.cancelBarButtonItemDidPressed(_:)) + ) + + let navigationActionView: NavigationActionView = { + let navigationActionView = NavigationActionView() + navigationActionView.backgroundColor = Asset.Scene.Onboarding.background.color + navigationActionView.hidesBackButton = true + return navigationActionView + }() + + deinit { + os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + } + +} + +extension ReportServerRulesViewController { + + override func viewDidLoad() { + super.viewDidLoad() + + setupAppearance() + defer { setupNavigationBarBackgroundView() } + + let hostingViewController = UIHostingController(rootView: reportServerRulesView) + hostingViewController.view.preservesSuperviewLayoutMargins = true + addChild(hostingViewController) + hostingViewController.view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(hostingViewController.view) + NSLayoutConstraint.activate([ + hostingViewController.view.topAnchor.constraint(equalTo: view.topAnchor), + hostingViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), + hostingViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), + hostingViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + + navigationActionView.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(navigationActionView) + defer { + view.bringSubviewToFront(navigationActionView) + } + NSLayoutConstraint.activate([ + navigationActionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + navigationActionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + view.bottomAnchor.constraint(equalTo: navigationActionView.bottomAnchor), + ]) + + navigationActionView + .observe(\.bounds, options: [.initial, .new]) { [weak self] navigationActionView, _ in + guard let self = self else { return } + let inset = navigationActionView.frame.height + self.viewModel.bottomPaddingHeight = inset + } + .store(in: &observations) + + viewModel.$selectRules + .map { !$0.isEmpty } + .assign(to: \.isEnabled, on: navigationActionView.nextButton) + .store(in: &disposeBag) + + navigationActionView.nextButton.addTarget(self, action: #selector(ReportServerRulesViewController.nextButtonPressed(_:)), for: .touchUpInside) + } + +} + +extension ReportServerRulesViewController { + + @objc private func cancelBarButtonItemDidPressed(_ sender: UIBarButtonItem) { + dismiss(animated: true, completion: nil) + } + + @objc private func nextButtonPressed(_ sender: UIButton) { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") + + assert(viewModel.delegate != nil) + viewModel.delegate?.reportServerRulesViewController(self, nextButtonPressed: sender) + } + +} diff --git a/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesViewModel.swift b/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesViewModel.swift new file mode 100644 index 000000000..50d2bf2d3 --- /dev/null +++ b/Mastodon/Scene/Report/ReportServerRules/ReportServerRulesViewModel.swift @@ -0,0 +1,35 @@ +// +// ReportServerRulesViewModel.swift +// Mastodon +// +// Created by MainasuK on 2022-5-10. +// + +import UIKit +import SwiftUI +import MastodonAsset +import MastodonSDK +import MastodonLocalization + +final class ReportServerRulesViewModel: ObservableObject { + + weak var delegate: ReportServerRulesViewControllerDelegate? + + // input + let context: AppContext + + @Published var headline = L10n.Scene.Report.StepTwo.whichRulesAreBeingViolated + @Published var serverRules: [Mastodon.Entity.Instance.Rule] = [] + + @Published var bottomPaddingHeight: CGFloat = .zero + @Published var backgroundColor: UIColor = Asset.Scene.Report.background.color + + // output + @Published var selectRules: Set = Set() + + init(context: AppContext) { + self.context = context + // end init + } + +} diff --git a/Mastodon/Scene/Report/ReportStatus/ReportViewController.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift similarity index 75% rename from Mastodon/Scene/Report/ReportStatus/ReportViewController.swift rename to Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift index 12291a964..d3844a3be 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportViewController.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewController.swift @@ -1,8 +1,8 @@ // -// ReportViewController.swift +// ReportStatusViewController.swift // Mastodon // -// Created by ihugo on 2021/4/20. +// Created by MainasuK on 2022-5-10. // import os.log @@ -12,21 +12,29 @@ import CoreDataStack import MastodonAsset import MastodonLocalization -class ReportViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { +protocol ReportStatusViewControllerDelegate: AnyObject { + func reportStatusViewController(_ viewController: ReportStatusViewController, skipButtonDidPressed button: UIButton) + func reportStatusViewController(_ viewController: ReportStatusViewController, nextButtonDidPressed button: UIButton) +} + +class ReportStatusViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { + + let logger = Logger(subsystem: "ReportStatusViewController", category: "ViewController") var disposeBag = Set() private var observations = Set() weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } - - var viewModel: ReportViewModel! + + var viewModel: ReportStatusViewModel! // MAKK: - UI + lazy var cancelBarButtonItem = UIBarButtonItem( barButtonSystemItem: .cancel, target: self, - action: #selector(ReportViewController.cancelBarButtonItemDidPressed(_:)) + action: #selector(ReportStatusViewController.cancelBarButtonItemDidPressed(_:)) ) let tableView: UITableView = { @@ -58,7 +66,7 @@ class ReportViewController: UIViewController, NeedsDependency, ReportViewControl } -extension ReportViewController { +extension ReportStatusViewController { override func viewDidLoad() { super.viewDidLoad() @@ -67,7 +75,7 @@ extension ReportViewController { defer { setupNavigationBarBackgroundView() } navigationItem.rightBarButtonItem = cancelBarButtonItem - + tableView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(tableView) NSLayoutConstraint.activate([ @@ -109,7 +117,7 @@ extension ReportViewController { .sink { [weak self] _ in guard let self = self else { return } guard self.view.window != nil else { return } - self.viewModel.stateMachine.enter(ReportViewModel.State.Loading.self) + self.viewModel.stateMachine.enter(ReportStatusViewModel.State.Loading.self) } .store(in: &disposeBag) @@ -118,56 +126,38 @@ extension ReportViewController { .assign(to: \.isEnabled, on: navigationActionView.nextButton) .store(in: &disposeBag) - navigationActionView.backButton.addTarget(self, action: #selector(ReportViewController.skipButtonDidPressed(_:)), for: .touchUpInside) - navigationActionView.nextButton.addTarget(self, action: #selector(ReportViewController.nextButtonDidPressed(_:)), for: .touchUpInside) + navigationActionView.backButton.addTarget(self, action: #selector(ReportStatusViewController.skipButtonDidPressed(_:)), for: .touchUpInside) + navigationActionView.nextButton.addTarget(self, action: #selector(ReportStatusViewController.nextButtonDidPressed(_:)), for: .touchUpInside) } } -extension ReportViewController { - +extension ReportStatusViewController { + @objc private func cancelBarButtonItemDidPressed(_ sender: UIBarButtonItem) { dismiss(animated: true, completion: nil) } - @objc func skipButtonDidPressed(_ sender: UIButton) { - var selectStatuses: [ManagedObjectRecord] = [] - if let selectStatus = viewModel.status { - selectStatuses.append(selectStatus) - } + @objc private func skipButtonDidPressed(_ sender: UIButton) { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") - let reportSupplementaryViewModel = ReportSupplementaryViewModel( - context: context, - user: viewModel.user, - selectStatuses: selectStatuses - ) - coordinator.present( - scene: .reportSupplementary(viewModel: reportSupplementaryViewModel), - from: self, - transition: .show - ) + assert(viewModel.delegate != nil) + viewModel.isSkip = true + viewModel.delegate?.reportStatusViewController(self, skipButtonDidPressed: sender) } - @objc func nextButtonDidPressed(_ sender: UIButton) { - let selectStatuses = Array(viewModel.selectStatuses) - guard !selectStatuses.isEmpty else { return } + @objc private func nextButtonDidPressed(_ sender: UIButton) { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") - let reportSupplementaryViewModel = ReportSupplementaryViewModel( - context: context, - user: viewModel.user, - selectStatuses: selectStatuses - ) - coordinator.present( - scene: .reportSupplementary(viewModel: reportSupplementaryViewModel), - from: self, - transition: .show - ) + assert(viewModel.delegate != nil) + viewModel.isSkip = false + viewModel.delegate?.reportStatusViewController(self, nextButtonDidPressed: sender) } } // MARK: - UITableViewDelegate -extension ReportViewController: UITableViewDelegate { +extension ReportStatusViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { guard let item = viewModel.diffableDataSource?.itemIdentifier(for: indexPath), case .status = item @@ -214,7 +204,7 @@ extension ReportViewController: UITableViewDelegate { } // MARK: - UIAdaptivePresentationControllerDelegate -extension ReportViewController: UIAdaptivePresentationControllerDelegate { +extension ReportStatusViewController: UIAdaptivePresentationControllerDelegate { func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool { return false } diff --git a/Mastodon/Scene/Report/ReportStatus/ReportViewModel+Diffable.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel+Diffable.swift similarity index 93% rename from Mastodon/Scene/Report/ReportStatus/ReportViewModel+Diffable.swift rename to Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel+Diffable.swift index 30ec5d872..4610a38d3 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportViewModel+Diffable.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel+Diffable.swift @@ -12,11 +12,11 @@ import CoreDataStack import MastodonAsset import MastodonLocalization -extension ReportViewModel { +extension ReportStatusViewModel { static let reportItemHeaderContext = ReportItem.HeaderContext( primaryLabelText: L10n.Scene.Report.content1, - secondaryLabelText: L10n.Scene.Report.step1 + secondaryLabelText: L10n.Scene.Report.StepThree.step3Of4 ) func setupDiffableDataSource( @@ -41,7 +41,7 @@ extension ReportViewModel { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.main]) - snapshot.appendItems([.header(context: ReportViewModel.reportItemHeaderContext)], toSection: .main) + snapshot.appendItems([.header(context: ReportStatusViewModel.reportItemHeaderContext)], toSection: .main) let items = records.map { ReportItem.status(record: $0) } snapshot.appendItems(items, toSection: .main) diff --git a/Mastodon/Scene/Report/ReportStatus/ReportViewModel+State.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel+State.swift similarity index 92% rename from Mastodon/Scene/Report/ReportStatus/ReportViewModel+State.swift rename to Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel+State.swift index 1bc43830f..c653fc4ad 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportViewModel+State.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel+State.swift @@ -12,7 +12,7 @@ import CoreData import CoreDataStack import GameplayKit -extension ReportViewModel { +extension ReportStatusViewModel { class State: GKState { let logger = Logger(subsystem: "ReportViewModel.State", category: "StateMachine") @@ -23,15 +23,15 @@ extension ReportViewModel { String(describing: Self.self) } - weak var viewModel: ReportViewModel? + weak var viewModel: ReportStatusViewModel? - init(viewModel: ReportViewModel) { + init(viewModel: ReportStatusViewModel) { self.viewModel = viewModel } override func didEnter(from previousState: GKState?) { super.didEnter(from: previousState) - let previousState = previousState as? ReportViewModel.State + let previousState = previousState as? ReportStatusViewModel.State logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): [\(self.id.uuidString)] enter \(self.name), previous: \(previousState?.name ?? "")") } @@ -46,8 +46,8 @@ extension ReportViewModel { } } -extension ReportViewModel.State { - class Initial: ReportViewModel.State { +extension ReportStatusViewModel.State { + class Initial: ReportStatusViewModel.State { override func isValidNextState(_ stateClass: AnyClass) -> Bool { guard let _ = viewModel else { return false } switch stateClass { @@ -59,7 +59,7 @@ extension ReportViewModel.State { } } - class Loading: ReportViewModel.State { + class Loading: ReportStatusViewModel.State { override func isValidNextState(_ stateClass: AnyClass) -> Bool { switch stateClass { case is Fail.Type: @@ -128,7 +128,7 @@ extension ReportViewModel.State { } } - class Fail: ReportViewModel.State { + class Fail: ReportStatusViewModel.State { override func isValidNextState(_ stateClass: AnyClass) -> Bool { switch stateClass { case is Loading.Type: @@ -139,7 +139,7 @@ extension ReportViewModel.State { } } - class Idle: ReportViewModel.State { + class Idle: ReportStatusViewModel.State { override func isValidNextState(_ stateClass: AnyClass) -> Bool { switch stateClass { case is Loading.Type: @@ -150,7 +150,7 @@ extension ReportViewModel.State { } } - class NoMore: ReportViewModel.State { + class NoMore: ReportStatusViewModel.State { override func isValidNextState(_ stateClass: AnyClass) -> Bool { return false } diff --git a/Mastodon/Scene/Report/ReportStatus/ReportViewModel.swift b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel.swift similarity index 91% rename from Mastodon/Scene/Report/ReportStatus/ReportViewModel.swift rename to Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel.swift index 46a475262..239960637 100644 --- a/Mastodon/Scene/Report/ReportStatus/ReportViewModel.swift +++ b/Mastodon/Scene/Report/ReportStatus/ReportStatusViewModel.swift @@ -1,8 +1,8 @@ // -// ReportViewModel.swift +// ReportStatusViewModel.swift // Mastodon // -// Created by ihugo on 2021/4/19. +// Created by MainasuK on 2022-5-10. // import Combine @@ -15,10 +15,12 @@ import OrderedCollections import os.log import UIKit -class ReportViewModel { +class ReportStatusViewModel { var disposeBag = Set() + weak var delegate: ReportStatusViewControllerDelegate? + // input let context: AppContext let user: ManagedObjectRecord @@ -26,6 +28,7 @@ class ReportViewModel { let statusFetchedResultsController: StatusFetchedResultsController let listBatchFetchViewModel = ListBatchFetchViewModel() + @Published var isSkip = false @Published var selectStatuses = OrderedSet>() // output diff --git a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift index 4f6e102b2..fd7783170 100644 --- a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift +++ b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewController.swift @@ -11,20 +11,25 @@ import Combine import MastodonAsset import MastodonLocalization +protocol ReportSupplementaryViewControllerDelegate: AnyObject { + func reportSupplementaryViewController(_ viewController: ReportSupplementaryViewController, skipButtonDidPressed button: UIButton) + func reportSupplementaryViewController(_ viewController: ReportSupplementaryViewController, nextButtonDidPressed button: UIButton) +} + final class ReportSupplementaryViewController: UIViewController, NeedsDependency, ReportViewControllerAppearance { let logger = Logger(subsystem: "ReportSupplementaryViewController", category: "ViewController") var disposeBag = Set() private var observations = Set() - + weak var context: AppContext! { willSet { precondition(!isViewLoaded) } } weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } } var viewModel: ReportSupplementaryViewModel! { willSet { precondition(!isViewLoaded) } } - // MAKK: - UI + lazy var cancelBarButtonItem = UIBarButtonItem( barButtonSystemItem: .cancel, target: self, @@ -74,16 +79,16 @@ extension ReportSupplementaryViewController { setupAppearance() defer { setupNavigationBarBackgroundView() } - navigationItem.rightBarButtonItem = cancelBarButtonItem - - viewModel.$isReporting + viewModel.$isBusy .receive(on: DispatchQueue.main) - .sink { [weak self] isReporting in + .sink { [weak self] isBusy in guard let self = self else { return } - self.navigationActionView.isUserInteractionEnabled = !isReporting + self.navigationItem.rightBarButtonItem = isBusy ? self.activityIndicatorBarButtonItem : self.cancelBarButtonItem + self.navigationItem.hidesBackButton = isBusy + self.navigationActionView.backButton.isUserInteractionEnabled = !isBusy } .store(in: &disposeBag) - + tableView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(tableView) NSLayoutConstraint.activate([ @@ -130,49 +135,25 @@ extension ReportSupplementaryViewController { } extension ReportSupplementaryViewController { - private func report(withComment: Bool) { - Task { - do { - let _ = try await viewModel.report(withComment: withComment) - logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): report success") - - let reportResultViewModel = ReportResultViewModel( - context: context, - user: viewModel.user - ) - - coordinator.present( - scene: .reportResult(viewModel: reportResultViewModel), - from: self, - transition: .show - ) - - } catch { - let alertController = UIAlertController(for: error, title: nil, preferredStyle: .alert) - let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default, handler: nil) - alertController.addAction(okAction) - self.coordinator.present( - scene: .alertController(alertController: alertController), - from: nil, - transition: .alertController(animated: true, completion: nil) - ) - } - } // end Task - } -} - -extension ReportSupplementaryViewController { - + @objc private func cancelBarButtonItemDidPressed(_ sender: UIBarButtonItem) { dismiss(animated: true, completion: nil) } @objc func skipButtonDidPressed(_ sender: UIButton) { - report(withComment: false) + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") + + assert(viewModel.delegate != nil) + viewModel.isSkip = true + viewModel.delegate?.reportSupplementaryViewController(self, skipButtonDidPressed: sender) } @objc func nextButtonDidPressed(_ sender: UIButton) { - report(withComment: true) + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") + + assert(viewModel.delegate != nil) + viewModel.isSkip = false + viewModel.delegate?.reportSupplementaryViewController(self, nextButtonDidPressed: sender) } } diff --git a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel+Diffable.swift b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel+Diffable.swift index 5fb9e7421..8cbc16242 100644 --- a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel+Diffable.swift +++ b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel+Diffable.swift @@ -15,8 +15,8 @@ import MastodonLocalization extension ReportSupplementaryViewModel { static let reportItemHeaderContext = ReportItem.HeaderContext( - primaryLabelText: L10n.Scene.Report.content2, - secondaryLabelText: L10n.Scene.Report.step2 + primaryLabelText: L10n.Scene.Report.StepFour.isThereAnythingElseWeShouldKnow, + secondaryLabelText: L10n.Scene.Report.StepFour.step4Of4 ) func setupDiffableDataSource( diff --git a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift index e73e82dd6..c07ee1f54 100644 --- a/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift +++ b/Mastodon/Scene/Report/ReportSupplementary/ReportSupplementaryViewModel.swift @@ -12,71 +12,37 @@ import MastodonSDK class ReportSupplementaryViewModel { + weak var delegate: ReportSupplementaryViewControllerDelegate? + // Input var context: AppContext let user: ManagedObjectRecord - let selectStatuses: [ManagedObjectRecord] let commentContext = ReportItem.CommentContext() + @Published var isSkip = false + @Published var isBusy = false + // output var diffableDataSource: UITableViewDiffableDataSource? @Published var isNextButtonEnabled = false - @Published var isReporting = false - @Published var isReportSuccess = false init( context: AppContext, - user: ManagedObjectRecord, - selectStatuses: [ManagedObjectRecord] + user: ManagedObjectRecord ) { self.context = context self.user = user - self.selectStatuses = selectStatuses // end init - commentContext.$comment - .map { comment -> Bool in - return !comment.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty - } - .assign(to: &$isNextButtonEnabled) + Publishers.CombineLatest( + commentContext.$comment, + $isBusy + ) + .map { comment, isBusy -> Bool in + guard !isBusy else { return false } + return !comment.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty + } + .assign(to: &$isNextButtonEnabled) } } - -extension ReportSupplementaryViewModel { - func report(withComment: Bool) async throws { - guard let authenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else { - assertionFailure() - return - } - - let managedObjectContext = context.managedObjectContext - let _query: Mastodon.API.Reports.FileReportQuery? = try await managedObjectContext.perform { - guard let user = self.user.object(in: managedObjectContext) else { return nil } - let statusIDs = self.selectStatuses.compactMap { record -> Status.ID? in - guard let status = record.object(in: managedObjectContext) else { return nil } - return status.id - } - return Mastodon.API.Reports.FileReportQuery( - accountID: user.id, - statusIDs: statusIDs, - comment: withComment ? self.commentContext.comment : nil, - forward: nil - ) - } - - guard let query = _query else { return } - - do { - isReporting = true - let _ = try await context.apiService.report( - query: query, - authenticationBox: authenticationBox - ) - isReportSuccess = true - } catch { - isReporting = false - throw error - } - } -} diff --git a/Mastodon/Scene/Report/Share/Cell/ReportCommentTableViewCell.swift b/Mastodon/Scene/Report/Share/Cell/ReportCommentTableViewCell.swift index b982ee5ac..d735a094c 100644 --- a/Mastodon/Scene/Report/Share/Cell/ReportCommentTableViewCell.swift +++ b/Mastodon/Scene/Report/Share/Cell/ReportCommentTableViewCell.swift @@ -8,6 +8,7 @@ import UIKit import Combine import MastodonUI +import MastodonAsset import MastodonLocalization import UITextView_Placeholder @@ -27,7 +28,8 @@ final class ReportCommentTableViewCell: UITableViewCell { textView.attributedPlaceholder = NSAttributedString( string: L10n.Scene.Report.textPlaceholder, attributes: [ - .font: font + .font: font, + .foregroundColor: Asset.Colors.Label.secondary.color ] ) textView.textContainerInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16) @@ -80,4 +82,17 @@ extension ReportCommentTableViewCell { commentTextView.heightAnchor.constraint(greaterThanOrEqualToConstant: 100).priority(.defaultHigh), ]) } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + super.traitCollectionDidChange(previousTraitCollection) + + commentTextView.attributedPlaceholder = NSAttributedString( + string: L10n.Scene.Report.textPlaceholder, + attributes: [ + .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 17, weight: .regular)), + .foregroundColor: Asset.Colors.Label.secondary.color + ] + ) + } + } diff --git a/Mastodon/Scene/Report/Share/Cell/ReportStatusTableViewCell.swift b/Mastodon/Scene/Report/Share/Cell/ReportStatusTableViewCell.swift index b134db302..6a2cf7fb2 100644 --- a/Mastodon/Scene/Report/Share/Cell/ReportStatusTableViewCell.swift +++ b/Mastodon/Scene/Report/Share/Cell/ReportStatusTableViewCell.swift @@ -86,15 +86,17 @@ extension ReportStatusTableViewCell { separatorLine.bottomAnchor.constraint(equalTo: contentView.bottomAnchor), separatorLine.heightAnchor.constraint(equalToConstant: UIView.separatorLineHeight(of: contentView)).priority(.required - 1), ]) + + statusView.isUserInteractionEnabled = false } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) if selected { - checkbox.image = UIImage(systemName: "checkmark.circle.fill") + checkbox.image = UIImage(systemName: "checkmark.square.fill") checkbox.tintColor = Asset.Colors.Label.primary.color } else { - checkbox.image = UIImage(systemName: "circle") + checkbox.image = UIImage(systemName: "square") checkbox.tintColor = Asset.Colors.Label.secondary.color } } diff --git a/Mastodon/Scene/Report/Share/ReportViewControllerAppearance.swift b/Mastodon/Scene/Report/Share/ReportViewControllerAppearance.swift index 6b35f3d89..fb9bcd63f 100644 --- a/Mastodon/Scene/Report/Share/ReportViewControllerAppearance.swift +++ b/Mastodon/Scene/Report/Share/ReportViewControllerAppearance.swift @@ -19,7 +19,7 @@ extension ReportViewControllerAppearance { func setupAppearance() { - title = L10n.Scene.Report.titleReport + // title = L10n.Scene.Report.titleReport view.backgroundColor = Asset.Scene.Report.background.color setupNavigationBarAppearance() diff --git a/Mastodon/Scene/Root/ContentSplitViewController.swift b/Mastodon/Scene/Root/ContentSplitViewController.swift index 03e203107..0058f5f6e 100644 --- a/Mastodon/Scene/Root/ContentSplitViewController.swift +++ b/Mastodon/Scene/Root/ContentSplitViewController.swift @@ -77,6 +77,16 @@ extension ContentSplitViewController { mainTabBarController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), ]) + // response keyboard command tab switch + mainTabBarController.$currentTab + .sink { [weak self] tab in + guard let self = self else { return } + if tab != self.currentSupplementaryTab { + self.currentSupplementaryTab = tab + } + } + .store(in: &disposeBag) + $currentSupplementaryTab .removeDuplicates() .sink(receiveValue: { [weak self] tab in diff --git a/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift b/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift index f4ad467da..ec145f86d 100644 --- a/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift +++ b/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift @@ -23,6 +23,7 @@ extension AdaptiveStatusBarStyleNavigationController { override func viewDidLoad() { super.viewDidLoad() + setupFullWidthBackGesture() } @@ -45,6 +46,11 @@ extension AdaptiveStatusBarStyleNavigationController: UIGestureRecognizerDelegat func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { let isSystemSwipeToBackEnabled = interactivePopGestureRecognizer?.isEnabled == true let isThereStackedViewControllers = viewControllers.count > 1 - return isSystemSwipeToBackEnabled && isThereStackedViewControllers + let isPanPopable = (topViewController as? PanPopableViewController)?.isPanPopable ?? true + return isSystemSwipeToBackEnabled && isThereStackedViewControllers && isPanPopable } } + +protocol PanPopableViewController: UIViewController { + var isPanPopable: Bool { get } +} diff --git a/Mastodon/Scene/Share/View/Content/MediaView+Configuration.swift b/Mastodon/Scene/Share/View/Content/MediaView+Configuration.swift index 02f9ad5a4..b782f8e8a 100644 --- a/Mastodon/Scene/Share/View/Content/MediaView+Configuration.swift +++ b/Mastodon/Scene/Share/View/Content/MediaView+Configuration.swift @@ -57,33 +57,7 @@ extension MediaView { } // end switch }() - if let previewURL = configuration.previewURL, - let url = URL(string: previewURL) - { - let placeholder = UIImage.placeholder(color: .systemGray6) - let request = URLRequest(url: url) - ImageDownloader.default.download(request, completion: { response in - switch response.result { - case .success(let image): - configuration.previewImage = image - case .failure: - configuration.previewImage = placeholder - } - }) - } - - if let assetURL = configuration.assetURL, - let blurhash = configuration.blurhash - { - AppContext.shared.blurhashImageCacheService.image( - blurhash: blurhash, - size: configuration.aspectRadio, - url: assetURL - ) - .assign(to: \.blurhashImage, on: configuration) - .store(in: &configuration.blurhashImageDisposeBag) - } - + configuration.load() configuration.isReveal = status.isMediaSensitive ? status.isSensitiveToggled : true return configuration diff --git a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift index b4dbef431..034985c03 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/StatusTableViewCellDelegate.swift @@ -34,6 +34,8 @@ protocol StatusTableViewCellDelegate: AnyObject, AutoGenerateProtocolDelegate { func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, menuButton button: UIButton, didSelectAction action: MastodonMenu.Action) func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaSensitiveButtonDidPressed button: UIButton) + func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton) + func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton) func tableViewCell(_ cell: UITableViewCell, statusView: StatusView, accessibilityActivate: Void) // sourcery:end } @@ -87,6 +89,14 @@ extension StatusViewDelegate where Self: StatusViewContainerTableViewCell { delegate?.tableViewCell(self, statusView: statusView, mediaGridContainerView: mediaGridContainerView, mediaSensitiveButtonDidPressed: button) } + func statusView(_ statusView: StatusView, statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton) { + delegate?.tableViewCell(self, statusView: statusView, statusMetricView: statusMetricView, reblogButtonDidPressed: button) + } + + func statusView(_ statusView: StatusView, statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton) { + delegate?.tableViewCell(self, statusView: statusView, statusMetricView: statusMetricView, favoriteButtonDidPressed: button) + } + func statusView(_ statusView: StatusView, accessibilityActivate: Void) { delegate?.tableViewCell(self, statusView: statusView, accessibilityActivate: accessibilityActivate) } diff --git a/Mastodon/Service/APIService/APIService+Favorite.swift b/Mastodon/Service/APIService/APIService+Favorite.swift index 20c2fe729..6ae2254e3 100644 --- a/Mastodon/Service/APIService/APIService+Favorite.swift +++ b/Mastodon/Service/APIService/APIService+Favorite.swift @@ -150,3 +150,45 @@ extension APIService { return response } // end func } + +extension APIService { + func favoritedBy( + status: ManagedObjectRecord, + query: Mastodon.API.Statuses.FavoriteByQuery, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Account]> { + let managedObjectContext = backgroundManagedObjectContext + let _statusID: Status.ID? = try? await managedObjectContext.perform { + guard let _status = status.object(in: managedObjectContext) else { return nil } + let status = _status.reblog ?? _status + return status.id + } + guard let statusID = _statusID else { + throw APIError.implicit(.badRequest) + } + + let response = try await Mastodon.API.Statuses.favoriteBy( + session: session, + domain: authenticationBox.domain, + statusID: statusID, + query: query, + authorization: authenticationBox.userAuthorization + ).singleOutput() + + try await managedObjectContext.performChanges { + for entity in response.value { + _ = Persistence.MastodonUser.createOrMerge( + in: managedObjectContext, + context: .init( + domain: authenticationBox.domain, + entity: entity, + cache: nil, + networkDate: response.networkDate + ) + ) + } // end for … in + } + + return response + } // end func +} diff --git a/Mastodon/Service/APIService/APIService+Reblog.swift b/Mastodon/Service/APIService/APIService+Reblog.swift index c8dde08bb..2542636c4 100644 --- a/Mastodon/Service/APIService/APIService+Reblog.swift +++ b/Mastodon/Service/APIService/APIService+Reblog.swift @@ -106,3 +106,45 @@ extension APIService { } } + +extension APIService { + func rebloggedBy( + status: ManagedObjectRecord, + query: Mastodon.API.Statuses.RebloggedByQuery, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Account]> { + let managedObjectContext = backgroundManagedObjectContext + let _statusID: Status.ID? = try? await managedObjectContext.perform { + guard let _status = status.object(in: managedObjectContext) else { return nil } + let status = _status.reblog ?? _status + return status.id + } + guard let statusID = _statusID else { + throw APIError.implicit(.badRequest) + } + + let response = try await Mastodon.API.Statuses.rebloggedBy( + session: session, + domain: authenticationBox.domain, + statusID: statusID, + query: query, + authorization: authenticationBox.userAuthorization + ).singleOutput() + + try await managedObjectContext.performChanges { + for entity in response.value { + _ = Persistence.MastodonUser.createOrMerge( + in: managedObjectContext, + context: .init( + domain: authenticationBox.domain, + entity: entity, + cache: nil, + networkDate: response.networkDate + ) + ) + } // end for … in + } + + return response + } // end func +} diff --git a/Mastodon/Service/APIService/APIService+Recommend.swift b/Mastodon/Service/APIService/APIService+Recommend.swift index 6e457ad07..f88d82305 100644 --- a/Mastodon/Service/APIService/APIService+Recommend.swift +++ b/Mastodon/Service/APIService/APIService+Recommend.swift @@ -74,3 +74,39 @@ extension APIService { } } + +extension APIService { + + func familiarFollowers( + query: Mastodon.API.Account.FamiliarFollowersQuery, + authenticationBox: MastodonAuthenticationBox + ) async throws -> Mastodon.Response.Content<[Mastodon.Entity.FamiliarFollowers]> { + let response = try await Mastodon.API.Account.familiarFollowers( + session: session, + domain: authenticationBox.domain, + query: query, + authorization: authenticationBox.userAuthorization + ).singleOutput() + + let managedObjectContext = backgroundManagedObjectContext + try await managedObjectContext.performChanges { + for entity in response.value { + for account in entity.accounts { + _ = Persistence.MastodonUser.createOrMerge( + in: managedObjectContext, + context: Persistence.MastodonUser.PersistContext( + domain: authenticationBox.domain, + entity: account, + cache: nil, + networkDate: response.networkDate + ) + ) + + } // end for account in + } // end for entity in + } + + return response + } + +} diff --git a/Mastodon/Service/APIService/APIService+Status.swift b/Mastodon/Service/APIService/APIService+Status.swift index 3d764663c..cf6974fbd 100644 --- a/Mastodon/Service/APIService/APIService+Status.swift +++ b/Mastodon/Service/APIService/APIService+Status.swift @@ -22,7 +22,7 @@ extension APIService { let domain = authenticationBox.domain let authorization = authenticationBox.userAuthorization - let response = try await Mastodon.API.Statuses.status( + let response = try await Mastodon.API.Statuses.status( session: session, domain: domain, statusID: statusID, diff --git a/Mastodon/Service/APIService/APIService.swift b/Mastodon/Service/APIService/APIService.swift index d9ae017d9..dabdadfea 100644 --- a/Mastodon/Service/APIService/APIService.swift +++ b/Mastodon/Service/APIService/APIService.swift @@ -6,7 +6,7 @@ // import os.log -import Foundation +import UIKit import Combine import CoreData import CoreDataStack @@ -38,6 +38,8 @@ final class APIService { NetworkActivityIndicatorManager.shared.isEnabled = true NetworkActivityIndicatorManager.shared.startDelay = 0.2 NetworkActivityIndicatorManager.shared.completionDelay = 0.5 + + UIImageView.af.sharedImageDownloader = ImageDownloader(downloadPrioritization: .lifo) } } diff --git a/Mastodon/State/AppContext.swift b/Mastodon/State/AppContext.swift index 9de19c44f..683c81f33 100644 --- a/Mastodon/State/AppContext.swift +++ b/Mastodon/State/AppContext.swift @@ -11,6 +11,7 @@ import Combine import CoreData import CoreDataStack import AlamofireImage +import MastodonUI class AppContext: ObservableObject { @@ -35,7 +36,7 @@ class AppContext: ObservableObject { let photoLibraryService = PhotoLibraryService() let placeholderImageCacheService = PlaceholderImageCacheService() - let blurhashImageCacheService = BlurhashImageCacheService() + let blurhashImageCacheService = BlurhashImageCacheService.shared let documentStore: DocumentStore private var documentStoreSubscription: AnyCancellable! diff --git a/Mastodon/Supporting Files/SceneDelegate.swift b/Mastodon/Supporting Files/SceneDelegate.swift index d178cd0d3..54b1fd57e 100644 --- a/Mastodon/Supporting Files/SceneDelegate.swift +++ b/Mastodon/Supporting Files/SceneDelegate.swift @@ -10,7 +10,7 @@ import UIKit import Combine import CoreDataStack -#if DEBUG +#if PROFILE import FPSIndicator #endif @@ -22,7 +22,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { var window: UIWindow? var coordinator: SceneCoordinator? - #if DEBUG + #if PROFILE var fpsIndicator: FPSIndicator? #endif @@ -87,8 +87,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate { } .store(in: &observations) - #if DEBUG - // fpsIndicator = FPSIndicator(windowScene: windowScene) + #if PROFILE + fpsIndicator = FPSIndicator(windowScene: windowScene) #endif } diff --git a/MastodonIntent/Info.plist b/MastodonIntent/Info.plist index 3f1630945..1a6ccd5fb 100644 --- a/MastodonIntent/Info.plist +++ b/MastodonIntent/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.1 + 1.4.2 CFBundleVersion - 126 + 133 NSExtension NSExtensionAttributes diff --git a/MastodonIntent/es-419.lproj/Intents.strings b/MastodonIntent/es-419.lproj/Intents.strings deleted file mode 100644 index 55a47e209..000000000 --- a/MastodonIntent/es-419.lproj/Intents.strings +++ /dev/null @@ -1,51 +0,0 @@ -"16wxgf" = "Enviar a Mastodon"; - -"751xkl" = "Contenido del texto"; - -"CsR7G2" = "Enviar"; - -"HZSGTr" = "¿Qué contenido enviar?"; - -"HdGikU" = "Error al enviar mensaje"; - -"KDNTJ4" = "Motivo del error"; - -"RHxKOw" = "Enviar mensaje con contenido de texto"; - -"RxSqsb" = "Mensaje"; - -"WCIR3D" = "Enviar ${content} a Mastodon"; - -"ZKJSNu" = "Mensaje"; - -"ZS1XaK" = "${content}"; - -"ZbSjzC" = "Visibilidad"; - -"Zo4jgJ" = "Visibilidad del mensaje"; - -"apSxMG-dYQ5NN" = "Hay ${count} opciones que coinciden con \"Público\"."; - -"apSxMG-ehFLjY" = "Hay ${count} opciones que coinciden con \"Sólo para seguidores\"."; - -"ayoYEb-dYQ5NN" = "${content}, público"; - -"ayoYEb-ehFLjY" = "${content}, sólo para seguidores"; - -"dUyuGg" = "Enviar"; - -"dYQ5NN" = "Público"; - -"ehFLjY" = "Sólo para seguidores"; - -"gfePDu" = "Error al enviar mensaje. ${failureReason}"; - -"k7dbKQ" = "El mensaje se envió exitosamente."; - -"oGiqmY-dYQ5NN" = "Sólo para confirmar, ¿querías que este mensaje sea PÚBLICO?"; - -"oGiqmY-ehFLjY" = "Sólo para confirmar, ¿querías que este mensaje sea SÓLO PARA SEGUIDORES?"; - -"rM6dvp" = "Dirección web"; - -"ryJLwG" = "El mensaje se envió exitosamente. "; diff --git a/MastodonIntent/sv-FI.lproj/Intents.strings b/MastodonIntent/es-AR.lproj/Intents.strings similarity index 100% rename from MastodonIntent/sv-FI.lproj/Intents.strings rename to MastodonIntent/es-AR.lproj/Intents.strings diff --git a/MastodonIntent/es-419.lproj/Intents.stringsdict b/MastodonIntent/es-AR.lproj/Intents.stringsdict similarity index 100% rename from MastodonIntent/es-419.lproj/Intents.stringsdict rename to MastodonIntent/es-AR.lproj/Intents.stringsdict diff --git a/MastodonIntent/eu-ES.lproj/Intents.strings b/MastodonIntent/eu.lproj/Intents.strings similarity index 100% rename from MastodonIntent/eu-ES.lproj/Intents.strings rename to MastodonIntent/eu.lproj/Intents.strings diff --git a/MastodonIntent/eu-ES.lproj/Intents.stringsdict b/MastodonIntent/eu.lproj/Intents.stringsdict similarity index 100% rename from MastodonIntent/eu-ES.lproj/Intents.stringsdict rename to MastodonIntent/eu.lproj/Intents.stringsdict diff --git a/MastodonIntent/sv_FI.lproj/Intents.strings b/MastodonIntent/fi.lproj/Intents.strings similarity index 100% rename from MastodonIntent/sv_FI.lproj/Intents.strings rename to MastodonIntent/fi.lproj/Intents.strings diff --git a/MastodonIntent/gd-GB.lproj/Intents.stringsdict b/MastodonIntent/fi.lproj/Intents.stringsdict similarity index 100% rename from MastodonIntent/gd-GB.lproj/Intents.stringsdict rename to MastodonIntent/fi.lproj/Intents.stringsdict diff --git a/MastodonIntent/gd-GB.lproj/Intents.strings b/MastodonIntent/gd.lproj/Intents.strings similarity index 100% rename from MastodonIntent/gd-GB.lproj/Intents.strings rename to MastodonIntent/gd.lproj/Intents.strings diff --git a/MastodonIntent/sv-FI.lproj/Intents.stringsdict b/MastodonIntent/gd.lproj/Intents.stringsdict similarity index 100% rename from MastodonIntent/sv-FI.lproj/Intents.stringsdict rename to MastodonIntent/gd.lproj/Intents.stringsdict diff --git a/MastodonIntent/gl.lproj/Intents.strings b/MastodonIntent/gl.lproj/Intents.strings index 6877490ba..2083cc701 100644 --- a/MastodonIntent/gl.lproj/Intents.strings +++ b/MastodonIntent/gl.lproj/Intents.strings @@ -1,51 +1,51 @@ -"16wxgf" = "Post on Mastodon"; +"16wxgf" = "Publicar en Mastodon"; -"751xkl" = "Text Content"; +"751xkl" = "Texto a incluír"; -"CsR7G2" = "Post on Mastodon"; +"CsR7G2" = "Publicar en Mastodon"; -"HZSGTr" = "What content to post?"; +"HZSGTr" = "Cal é o contido a publicar?"; -"HdGikU" = "Posting failed"; +"HdGikU" = "Fallou a publicación"; -"KDNTJ4" = "Failure Reason"; +"KDNTJ4" = "Razón do fallo"; -"RHxKOw" = "Send Post with text content"; +"RHxKOw" = "Enviar Publicación con texto"; -"RxSqsb" = "Post"; +"RxSqsb" = "Publicación"; -"WCIR3D" = "Post ${content} on Mastodon"; +"WCIR3D" = "Publicar ${content} en Mastodon"; -"ZKJSNu" = "Post"; +"ZKJSNu" = "Publicación"; "ZS1XaK" = "${content}"; -"ZbSjzC" = "Visibility"; +"ZbSjzC" = "Visibilidade"; -"Zo4jgJ" = "Post Visibility"; +"Zo4jgJ" = "Visibilidade da publicación"; -"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; +"apSxMG-dYQ5NN" = "Hai ${count} opcións que coinciden con ‘Público’."; -"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; +"apSxMG-ehFLjY" = "Hai ${count} opcións que coinciden con 'Só seguidoras’."; -"ayoYEb-dYQ5NN" = "${content}, Public"; +"ayoYEb-dYQ5NN" = "${content}, Público"; -"ayoYEb-ehFLjY" = "${content}, Followers Only"; +"ayoYEb-ehFLjY" = "${content}, Só seguidoras"; -"dUyuGg" = "Post on Mastodon"; +"dUyuGg" = "Publicar en Mastodon"; -"dYQ5NN" = "Public"; +"dYQ5NN" = "Público"; -"ehFLjY" = "Followers Only"; +"ehFLjY" = "Só seguidoras"; -"gfePDu" = "Posting failed. ${failureReason}"; +"gfePDu" = "Fallou a publicación. ${failureReason}"; -"k7dbKQ" = "Post was sent successfully."; +"k7dbKQ" = "Publicación correcta."; -"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; +"oGiqmY-dYQ5NN" = "Só para confirmar, querías ’Público'?"; -"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; +"oGiqmY-ehFLjY" = "Só para confirmar, querías ’Só para seguidoras'?"; "rM6dvp" = "URL"; -"ryJLwG" = "Post was sent successfully. "; +"ryJLwG" = "Publicación correcta. "; diff --git a/MastodonIntent/sv.lproj/Intents.strings b/MastodonIntent/sv.lproj/Intents.strings index b85bec4c5..526e495d2 100644 --- a/MastodonIntent/sv.lproj/Intents.strings +++ b/MastodonIntent/sv.lproj/Intents.strings @@ -1,52 +1,51 @@ -"16wxgf" = "Post on Mastodon"; +"16wxgf" = "Publicera på Mastodon"; -"751xkl" = "Text Content"; +"751xkl" = "Textinnehåll"; -"CsR7G2" = "Post on Mastodon"; +"CsR7G2" = "Publicera på Mastodon"; -"HZSGTr" = "What content to post?"; +"HZSGTr" = "Vilket innehåll ska publiceras?"; -"HdGikU" = "Posting failed"; +"HdGikU" = "Publiceringen misslyckades"; -"KDNTJ4" = "Failure Reason"; +"KDNTJ4" = "Felorsak"; -"RHxKOw" = "Send Post with text content"; +"RHxKOw" = "Skicka inlägg med textinnehåll"; -"RxSqsb" = "Post"; +"RxSqsb" = "Inlägg"; -"WCIR3D" = "Post ${content} on Mastodon"; +"WCIR3D" = "Publicera ${content} på Mastodon"; -"ZKJSNu" = "Post"; +"ZKJSNu" = "Inlägg"; "ZS1XaK" = "${content}"; -"ZbSjzC" = "Visibility"; +"ZbSjzC" = "Synlighet"; -"Zo4jgJ" = "Post Visibility"; +"Zo4jgJ" = "Inläggssynlighet"; -"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’."; +"apSxMG-dYQ5NN" = "Det finns ${count} alternativ som matchar ‘Offentligt’."; -"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’."; +"apSxMG-ehFLjY" = "Det finns ${count} alternativ som matchar ‘Endast följare’."; -"ayoYEb-dYQ5NN" = "${content}, Public"; +"ayoYEb-dYQ5NN" = "${content}, Offentligt"; -"ayoYEb-ehFLjY" = "${content}, Followers Only"; +"ayoYEb-ehFLjY" = "${content}, Endast följare"; -"dUyuGg" = "Post on Mastodon"; +"dUyuGg" = "Publicera på Mastodon"; -"dYQ5NN" = "Public"; +"dYQ5NN" = "Offentligt"; -"ehFLjY" = "Followers Only"; +"ehFLjY" = "Endast följare"; -"gfePDu" = "Posting failed. ${failureReason}"; +"gfePDu" = "Publicering misslyckades. ${failureReason}"; -"k7dbKQ" = "Post was sent successfully."; +"k7dbKQ" = "Inlägget har publicerats."; -"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?"; +"oGiqmY-dYQ5NN" = "Bara för att bekräfta, ville du ha 'Offentligt'?"; -"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?"; +"oGiqmY-ehFLjY" = "Bara för att bekräfta, ville du ha 'Endast följare'?"; "rM6dvp" = "URL"; -"ryJLwG" = "Post was sent successfully."; - +"ryJLwG" = "Inlägget har publicerats. "; diff --git a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift index de6b55cbd..957071a21 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift +++ b/MastodonSDK/Sources/MastodonLocalization/Generated/Strings.swift @@ -518,6 +518,8 @@ public enum L10n { public enum ConfirmEmail { /// Tap the link we emailed to you to verify your account. public static let subtitle = L10n.tr("Localizable", "Scene.ConfirmEmail.Subtitle") + /// Tap the link we emailed to you to verify your account + public static let tapTheLinkWeEmailedToYouToVerifyYourAccount = L10n.tr("Localizable", "Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount") /// One last thing. public static let title = L10n.tr("Localizable", "Scene.ConfirmEmail.Title") public enum Button { @@ -561,17 +563,33 @@ public enum L10n { public static let posts = L10n.tr("Localizable", "Scene.Discovery.Tabs.Posts") } } + public enum Familiarfollowers { + /// Followed by %@ + public static func followedByNames(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Familiarfollowers.FollowedByNames", String(describing: p1)) + } + /// Followers you familiar + public static let title = L10n.tr("Localizable", "Scene.Familiarfollowers.Title") + } public enum Favorite { /// Your Favorites public static let title = L10n.tr("Localizable", "Scene.Favorite.Title") } + public enum FavoritedBy { + /// Favorited By + public static let title = L10n.tr("Localizable", "Scene.FavoritedBy.Title") + } public enum Follower { /// Followers from other servers are not displayed. public static let footer = L10n.tr("Localizable", "Scene.Follower.Footer") + /// follower + public static let title = L10n.tr("Localizable", "Scene.Follower.Title") } public enum Following { /// Follows from other servers are not displayed. public static let footer = L10n.tr("Localizable", "Scene.Following.Footer") + /// following + public static let title = L10n.tr("Localizable", "Scene.Following.Title") } public enum HomeTimeline { /// Home @@ -585,6 +603,12 @@ public enum L10n { public static let published = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Published") /// Publishing post... public static let publishing = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Publishing") + public enum Accessibility { + /// Tap to scroll to top and tap again to previous location + public static let logoHint = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint") + /// Logo Button + public static let logoLabel = L10n.tr("Localizable", "Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel") + } } } public enum Notification { @@ -701,7 +725,15 @@ public enum L10n { public static let replies = L10n.tr("Localizable", "Scene.Profile.SegmentedControl.Replies") } } + public enum RebloggedBy { + /// Reblogged By + public static let title = L10n.tr("Localizable", "Scene.RebloggedBy.Title") + } public enum Register { + /// Let’s get you set up on %@ + public static func letsGetYouSetUpOnDomain(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Register.LetsGetYouSetUpOnDomain", String(describing: p1)) + } /// Let’s get you set up on %@ public static func title(_ p1: Any) -> String { return L10n.tr("Localizable", "Scene.Register.Title", String(describing: p1)) @@ -840,6 +872,90 @@ public enum L10n { } /// Report public static let titleReport = L10n.tr("Localizable", "Scene.Report.TitleReport") + public enum StepFinal { + /// Block %@ + public static func blockUser(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Report.StepFinal.BlockUser", String(describing: p1)) + } + /// Don’t want to see this? + public static let dontWantToSeeThis = L10n.tr("Localizable", "Scene.Report.StepFinal.DontWantToSeeThis") + /// Mute %@ + public static func muteUser(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Report.StepFinal.MuteUser", String(describing: p1)) + } + /// They will no longer be able to follow or see your posts, but they can see if they’ve been blocked. + public static let theyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked = L10n.tr("Localizable", "Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked") + /// Unfollow + public static let unfollow = L10n.tr("Localizable", "Scene.Report.StepFinal.Unfollow") + /// Unfollowed + public static let unfollowed = L10n.tr("Localizable", "Scene.Report.StepFinal.Unfollowed") + /// Unfollow %@ + public static func unfollowUser(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Report.StepFinal.UnfollowUser", String(describing: p1)) + } + /// When you see something you don’t like on Mastodon, you can remove the person from your experience. + public static let whenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience = L10n.tr("Localizable", "Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience.") + /// While we review this, you can take action against %@ + public static func whileWeReviewThisYouCanTakeActionAgainstUser(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser", String(describing: p1)) + } + /// You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted. + public static let youWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted = L10n.tr("Localizable", "Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted") + } + public enum StepFour { + /// Is there anything else we should know? + public static let isThereAnythingElseWeShouldKnow = L10n.tr("Localizable", "Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow") + /// Step 4 of 4 + public static let step4Of4 = L10n.tr("Localizable", "Scene.Report.StepFour.Step4Of4") + } + public enum StepOne { + /// I don’t like it + public static let iDontLikeIt = L10n.tr("Localizable", "Scene.Report.StepOne.IDontLikeIt") + /// It is not something you want to see + public static let itIsNotSomethingYouWantToSee = L10n.tr("Localizable", "Scene.Report.StepOne.ItIsNotSomethingYouWantToSee") + /// It’s something else + public static let itsSomethingElse = L10n.tr("Localizable", "Scene.Report.StepOne.ItsSomethingElse") + /// It’s spam + public static let itsSpam = L10n.tr("Localizable", "Scene.Report.StepOne.ItsSpam") + /// It violates server rules + public static let itViolatesServerRules = L10n.tr("Localizable", "Scene.Report.StepOne.ItViolatesServerRules") + /// Malicious links, fake engagement, or repetetive replies + public static let maliciousLinksFakeEngagementOrRepetetiveReplies = L10n.tr("Localizable", "Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies") + /// Select the best match + public static let selectTheBestMatch = L10n.tr("Localizable", "Scene.Report.StepOne.SelectTheBestMatch") + /// Step 1 of 4 + public static let step1Of4 = L10n.tr("Localizable", "Scene.Report.StepOne.Step1Of4") + /// The issue does not fit into other categories + public static let theIssueDoesNotFitIntoOtherCategories = L10n.tr("Localizable", "Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories") + /// What's wrong with this account? + public static let whatsWrongWithThisAccount = L10n.tr("Localizable", "Scene.Report.StepOne.WhatsWrongWithThisAccount") + /// What's wrong with this post? + public static let whatsWrongWithThisPost = L10n.tr("Localizable", "Scene.Report.StepOne.WhatsWrongWithThisPost") + /// What's wrong with %@? + public static func whatsWrongWithThisUsername(_ p1: Any) -> String { + return L10n.tr("Localizable", "Scene.Report.StepOne.WhatsWrongWithThisUsername", String(describing: p1)) + } + /// You are aware that it breaks specific rules + public static let youAreAwareThatItBreaksSpecificRules = L10n.tr("Localizable", "Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules") + } + public enum StepThree { + /// Are there any posts that back up this report? + public static let areThereAnyPostsThatBackUpThisReport = L10n.tr("Localizable", "Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport") + /// Select all that apply + public static let selectAllThatApply = L10n.tr("Localizable", "Scene.Report.StepThree.SelectAllThatApply") + /// Step 3 of 4 + public static let step3Of4 = L10n.tr("Localizable", "Scene.Report.StepThree.Step3Of4") + } + public enum StepTwo { + /// I just don’t like it + public static let iJustDonTLikeIt = L10n.tr("Localizable", "Scene.Report.StepTwo.IJustDon’tLikeIt") + /// Select all that apply + public static let selectAllThatApply = L10n.tr("Localizable", "Scene.Report.StepTwo.SelectAllThatApply") + /// Step 2 of 4 + public static let step2Of4 = L10n.tr("Localizable", "Scene.Report.StepTwo.Step2Of4") + /// Which rules are being violated? + public static let whichRulesAreBeingViolated = L10n.tr("Localizable", "Scene.Report.StepTwo.WhichRulesAreBeingViolated") + } } public enum Search { /// Search @@ -947,6 +1063,8 @@ public enum L10n { public enum Input { /// Search servers public static let placeholder = L10n.tr("Localizable", "Scene.ServerPicker.Input.Placeholder") + /// Search servers or enter URL + public static let searchServersOrEnterUrl = L10n.tr("Localizable", "Scene.ServerPicker.Input.SearchServersOrEnterUrl") } public enum Label { /// CATEGORY @@ -1209,6 +1327,10 @@ public enum L10n { public static func favorite(_ p1: Int) -> String { return L10n.tr("Localizable", "plural.count.favorite", p1) } + /// Plural format key: "%#@names@%#@count_mutual@" + public static func followedByAndMutual(_ p1: Int, _ p2: Int) -> String { + return L10n.tr("Localizable", "plural.count.followed_by_and_mutual", p1, p2) + } /// Plural format key: "%#@count_follower@" public static func follower(_ p1: Int) -> String { return L10n.tr("Localizable", "plural.count.follower", p1) @@ -1217,6 +1339,10 @@ public enum L10n { public static func following(_ p1: Int) -> String { return L10n.tr("Localizable", "plural.count.following", p1) } + /// Plural format key: "%#@media_count@" + public static func media(_ p1: Int) -> String { + return L10n.tr("Localizable", "plural.count.media", p1) + } /// Plural format key: "%#@post_count@" public static func post(_ p1: Int) -> String { return L10n.tr("Localizable", "plural.count.post", p1) diff --git a/MastodonSDK/Sources/MastodonLocalization/MastodonLocalization+Bundle.swift b/MastodonSDK/Sources/MastodonLocalization/MastodonLocalization+Bundle.swift new file mode 100644 index 000000000..3e5f62e40 --- /dev/null +++ b/MastodonSDK/Sources/MastodonLocalization/MastodonLocalization+Bundle.swift @@ -0,0 +1,14 @@ +// +// MastodonLocalization+Bundle.swift +// +// +// Created by MainasuK on 2022-5-17. +// + +import Foundation + +public enum MastodonLocalization { + public static var bundle: Bundle { + Bundle.module + } +} diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings index 2ed1a8ad3..6cf6275b5 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.strings @@ -58,7 +58,7 @@ "Common.Controls.Actions.SignIn" = "تسجيل الدخول"; "Common.Controls.Actions.SignUp" = "إنشاء حِساب"; "Common.Controls.Actions.Skip" = "تخطي"; -"Common.Controls.Actions.TakePhoto" = "التقاط صورة"; +"Common.Controls.Actions.TakePhoto" = "اِلتِقاطُ صُورَة"; "Common.Controls.Actions.TryAgain" = "المُحاولة مرة أُخرى"; "Common.Controls.Actions.UnblockDomain" = "رفع الحظر عن %@"; "Common.Controls.Friendship.Block" = "حظر"; @@ -164,7 +164,7 @@ "Scene.Compose.Attachment.Video" = "مقطع مرئي"; "Scene.Compose.AutoComplete.SpaceToAdd" = "انقر على مساحة لإضافتِها"; "Scene.Compose.ComposeAction" = "نَشر"; -"Scene.Compose.ContentInputPlaceholder" = "أخبِرنا بِما يَجُولُ فِي ذِهنَك"; +"Scene.Compose.ContentInputPlaceholder" = "عَبِّر عَمَّ يَجُولُ فِي ذِهنِك"; "Scene.Compose.ContentWarning.Placeholder" = "اكتب تَحذيرًا دَقيقًا هُنا..."; "Scene.Compose.Keyboard.AppendAttachmentEntry" = "إضافة مُرفَق - %@"; "Scene.Compose.Keyboard.DiscardPost" = "تجاهُل المنشور"; @@ -172,9 +172,9 @@ "Scene.Compose.Keyboard.SelectVisibilityEntry" = "اختر مدى الظهور - %@"; "Scene.Compose.Keyboard.ToggleContentWarning" = "تبديل تحذير المُحتَوى"; "Scene.Compose.Keyboard.TogglePoll" = "تبديل الاستطلاع"; -"Scene.Compose.MediaSelection.Browse" = "تصفح"; -"Scene.Compose.MediaSelection.Camera" = "إلتقاط صورة"; -"Scene.Compose.MediaSelection.PhotoLibrary" = "مكتبة الصور"; +"Scene.Compose.MediaSelection.Browse" = "تَصَفَّح"; +"Scene.Compose.MediaSelection.Camera" = "اِلتِقاطُ صُورَة"; +"Scene.Compose.MediaSelection.PhotoLibrary" = "مَكتَبَةُ الصُّوَر"; "Scene.Compose.Poll.DurationTime" = "المُدَّة: %@"; "Scene.Compose.Poll.OneDay" = "يومٌ واحِد"; "Scene.Compose.Poll.OneHour" = "ساعةٌ واحدة"; @@ -199,8 +199,8 @@ "Scene.ConfirmEmail.OpenEmailApp.Mail" = "البريد"; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "فتح عميل البريد الإلكتروني"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "تحقَّق من بريدك الوارِد."; -"Scene.ConfirmEmail.Subtitle" = "لقد أرسلنا للتو بريد إلكتروني إلى %@، -انقر على الرابط لتأكيد حسابك."; +"Scene.ConfirmEmail.Subtitle" = "أنقر على الرابط المرسل إليك لاستيثاق حسابك."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "اُنقُر عَلَى الرَّابِطِ الَّذي أرسَلناهُ إليكَ عَبرَ البَريدِ الإلِكتُرُونيّ لِلتَّحَقُقِ مِن حِسابِك"; "Scene.ConfirmEmail.Title" = "شيءٌ أخير."; "Scene.Discovery.Intro" = "هَذِهِ هِيَ المَنشُوراتُ الَّتي تَكْتَسِبُ شَعبِيَّةً فِي الرُّكنِ الخاصِّ بِكَ مِن مَاستُودون."; "Scene.Discovery.Tabs.Community" = "المُجتَمَع"; @@ -208,9 +208,16 @@ "Scene.Discovery.Tabs.Hashtags" = "وُسُوم"; "Scene.Discovery.Tabs.News" = "أخبار"; "Scene.Discovery.Tabs.Posts" = "مَنشُورات"; +"Scene.Familiarfollowers.FollowedByNames" = "مُتابَعٌ مِن قِبَلِ %@"; +"Scene.Familiarfollowers.Title" = "مُتابِعُونَ مَألُوفُونَ بِالنِّسبَةِ لَك"; "Scene.Favorite.Title" = "مُفضَّلَتُك"; +"Scene.FavoritedBy.Title" = "مُفَضَّلٌ مِن قِبَلِ"; "Scene.Follower.Footer" = "لا يُمكِن عَرض المُتابِعين مِنَ الخوادم الأُخرى."; +"Scene.Follower.Title" = "مُتابِعِين"; "Scene.Following.Footer" = "لا يُمكِن عَرض المُتابَعات مِنَ الخوادم الأُخرى."; +"Scene.Following.Title" = "مُتابَعُون"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "اُنقُر لِلتمريرِ لأعلى واُنقُر مَرّةً أُخرَى لِلذَّهابِ إلَى المَوقِعِ السَّابِق"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "ُّزِرُّ الشِّعار"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "إظهار منشورات جديدة"; "Scene.HomeTimeline.NavigationBarState.Offline" = "غَير مُتَّصِل"; "Scene.HomeTimeline.NavigationBarState.Published" = "تمَّ النَّشر!"; @@ -252,6 +259,7 @@ "Scene.Profile.SegmentedControl.Posts" = "مَنشورات"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "مَنشُوراتٌ وَرُدُود"; "Scene.Profile.SegmentedControl.Replies" = "رُدُود"; +"Scene.RebloggedBy.Title" = "اُعيدَ تَدوينَهُ بِواسِطَةِ"; "Scene.Register.Error.Item.Agreement" = "الاِتِّفاقيَّة"; "Scene.Register.Error.Item.Email" = "البريد الإلكتروني"; "Scene.Register.Error.Item.Locale" = "اللغة المحلية"; @@ -284,6 +292,7 @@ "Scene.Register.Input.Password.Require" = "رمز المرور الخاص بك يجب أن يحتوي على الأقل:"; "Scene.Register.Input.Username.DuplicatePrompt" = "اِسم المُستَخدِم هذا مأخوذٌ بالفعل."; "Scene.Register.Input.Username.Placeholder" = "اِسمُ مُستَخدِم"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "دَعنا نَبدَأُ بِإعدادِكَ عَلَى %@"; "Scene.Register.Title" = "أخبرنا عن نفسك."; "Scene.Report.Content1" = "هل ترغب في إضافة أي منشورات أُخرى إلى البلاغ؟"; "Scene.Report.Content2" = "هل هناك أي شيء يجب أن يعرفه المُراقبين حول هذا البلاغ؟"; @@ -291,8 +300,40 @@ "Scene.Report.Reported" = "مُبْلَغٌ عَنه"; "Scene.Report.Send" = "إرسال البلاغ"; "Scene.Report.SkipToSend" = "إرسال بدون تعليق"; -"Scene.Report.Step1" = "الخطوة الأولى مِن أصل اثنتين"; -"Scene.Report.Step2" = "الخطوة الثانية والأخيرة"; +"Scene.Report.Step1" = "الخطوة 1 مِن أصل 2"; +"Scene.Report.Step2" = "الخطوة 2 مِن أصل 2"; +"Scene.Report.StepFinal.BlockUser" = "حَظرُ %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "ألَا تُريدُ رُؤيَةَ هَذَا؟"; +"Scene.Report.StepFinal.MuteUser" = "كَتمُ %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "لَن يَتمكَّنَ بَعدَ الآنِ مِن مُتابَعَةِ مَنشوراتِكَ أو رُؤيَتِها، وَلكِن يُمكِنَهُ مَعرِفَةُ مَا إذا حُظَرِت عَنه."; +"Scene.Report.StepFinal.Unfollow" = "إلغاءُ المُتابَعَة"; +"Scene.Report.StepFinal.UnfollowUser" = "إلغاءُ مُتابَعَةِ %@"; +"Scene.Report.StepFinal.Unfollowed" = "أُلغِيَت المُتابَعَة"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "عِندما تَرى شيئًا لَا يُعجِبُكَ عَلَى مَاستودُون، يُمكِنُكَ إزالَةُ الشَّخصِ مِن تَجرِبَتِك."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "أثناءُ مُراجَعَتِنا لِذلِك، يُمكِنُكَ اِتِّخاذُ إجراءٍ ضِدَّ %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "لَن تَرى مُشارَكاتِهِ أو إعادَاتِ تَدوينَهِ فِي تغذيَتِكَ الرَّئيسَة. لَن يَعرِفَ أنَّهُ قَد كُتِمَ أيضًا."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "هَل هُناكَ شَيءٌ آخَرَ يَجِبُ أن نَعلَمَ بِه؟"; +"Scene.Report.StepFour.Step4Of4" = "الخطوة 4 مِن أصل 4"; +"Scene.Report.StepOne.IDontLikeIt" = "لا يُعجِبُني"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "إنَّهُ ليسَ شيئًا تُريدُ رُؤيَتَه"; +"Scene.Report.StepOne.ItViolatesServerRules" = "يَنتَهِكُ قَواعِدَ الخادِم"; +"Scene.Report.StepOne.ItsSomethingElse" = "إنَّهُ شَيءٌ آخَر"; +"Scene.Report.StepOne.ItsSpam" = "إنَّهُ غَيرٌ مَرغوبٍ فيه"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "رَوابِطٌ ضَارَّة، اِرتِباطاتٌ مُزيَّفَة أو رُدودٌ مُتَكَرِّرَة"; +"Scene.Report.StepOne.SelectTheBestMatch" = "اِختَر أفضلَ تَطابُق"; +"Scene.Report.StepOne.Step1Of4" = "الخطوة 1 مِن أصل 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "المُشكِلَةُ لَا تَتَناسَبُ مَعَ الفِئاتِ الأُخرَى"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "ما المُشكِلَةُ فِي هَذَا الحِساب؟"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "ما المُشكِلَةُ فِي هَذَا المَنشُور؟"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "ما المُشكِلَة مَعَ %@؟"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "أنتَ مُدِركٌ لِانتِهاكِهِ قَواعِدًا مُحَدَّدَة"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "هَل هُناكَ أيُّ مَنشُوراتٍ أُخرَى تَتَوافَقُ مَعَ هَذَا التَّقرير؟"; +"Scene.Report.StepThree.SelectAllThatApply" = "اِختَر كُلَّ ما يَنطَبِق"; +"Scene.Report.StepThree.Step3Of4" = "الخطوة 3 مِن أصل 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "أنا فَقَط لا يُعجِبُني"; +"Scene.Report.StepTwo.SelectAllThatApply" = "اِختَر كُلَّ ما يَنطَبِق"; +"Scene.Report.StepTwo.Step2Of4" = "الخطوة 2 مِن أصل 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "مَا هِيَ القَواعِدُ الَّتي تُنتَهَك؟"; "Scene.Report.TextPlaceholder" = "اكتب أو الصق تعليقات إضافيَّة"; "Scene.Report.Title" = "الإبلاغ عن %@"; "Scene.Report.TitleReport" = "إبلاغ"; @@ -333,6 +374,7 @@ "Scene.ServerPicker.EmptyState.FindingServers" = "يجري إيجاد خوادم متوفِّرَة..."; "Scene.ServerPicker.EmptyState.NoResults" = "لا توجد نتائج"; "Scene.ServerPicker.Input.Placeholder" = "اِبحَث عن خادِم أو انضم إلى آخر خاص بك..."; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "اِبحَث فِي الخَوادِم أو أدخِل رابِط"; "Scene.ServerPicker.Label.Category" = "الفئة"; "Scene.ServerPicker.Label.Language" = "اللُّغة"; "Scene.ServerPicker.Label.Users" = "مُستَخدِم"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.stringsdict index c2f641720..197897e8e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ar.lproj/Localizable.stringsdict @@ -74,6 +74,49 @@ %ld حَرف + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + zero + + one + + two + + few + + many + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + zero + مُتابَعٌ مِن قِبَلِ لَا أحَد + one + مُتابَعٌ مِن قِبَلِ %1$@، وشَخصٌ آخَرُ مُتبادَل + two + مُتابَعٌ مِن قِبَلِ %1$@، وشَخصانِ آخَرَانِ مُتبادَلَان + few + مُتابَعٌ مِن قِبَلِ %1$@، و%ld آخَرينَ مُتبادَلين + many + مُتابَعٌ مِن قِبَلِ %1$@، و%ld آخَرينَ مُتبادَلين + other + مُتابَعٌ مِن قِبَلِ %1$@، و%ld آخَرَ مُتبادَل + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -98,6 +141,30 @@ منشور + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + zero + لا وسيطة + one + وسيطةٌ واحِدَة + two + وسيطتانِ اِثنتان + few + %ld أوساط + many + %ld وَسَطًا + other + %ld وَسَط + + plural.count.post NSStringLocalizedFormatKey @@ -109,7 +176,7 @@ NSStringFormatValueTypeKey ld zero - لا منشور + لا مَنشورات one منشورٌ واحِد two @@ -447,13 +514,13 @@ zero تتبقى لَحظة one - تتبقى ثانية + تتبقى ثانية واحِدة two - تتبقى ثانيتين + تتبقى ثانيتان few تتبقى %ld ثوان many - تتبقى %ld ثانيةً + تتبقى %ld ثانية other تتبقى %ld ثانية diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings index f22a0ff74..578e60d34 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.strings @@ -200,6 +200,7 @@ carregat a Mastodon."; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Obre el Client de Correu electrònic"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Comprova la teva safata d'entrada."; "Scene.ConfirmEmail.Subtitle" = "Toca l'enllaç del correu electrònic que t'hem enviat per a confirmar el teu compte."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Toca l'enllaç del correu electrònic que t'hem enviat per a confirmar el teu compte"; "Scene.ConfirmEmail.Title" = "Una última cosa."; "Scene.Discovery.Intro" = "Aquestes son les publicacions que criden l'atenció en el teu racó de Mastodon."; "Scene.Discovery.Tabs.Community" = "Comunitat"; @@ -207,9 +208,16 @@ carregat a Mastodon."; "Scene.Discovery.Tabs.Hashtags" = "Etiquetes"; "Scene.Discovery.Tabs.News" = "Notícies"; "Scene.Discovery.Tabs.Posts" = "Publicacions"; +"Scene.Familiarfollowers.FollowedByNames" = "Seguit per %@"; +"Scene.Familiarfollowers.Title" = "Seguidors coneguts"; "Scene.Favorite.Title" = "Els teus Favorits"; +"Scene.FavoritedBy.Title" = "Preferit per"; "Scene.Follower.Footer" = "Els seguidors d'altres servidors no son mostrats."; +"Scene.Follower.Title" = "seguidor"; "Scene.Following.Footer" = "Els seguits d'altres servidors no son mostrats."; +"Scene.Following.Title" = "seguint"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Toca per desplaçar-te cap a dalt i torna a toca de nou per tornar a la ubicació anterior"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Botó de logotip"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Veure noves publicacions"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Fora de línia"; "Scene.HomeTimeline.NavigationBarState.Published" = "Publicat!"; @@ -251,6 +259,7 @@ carregat a Mastodon."; "Scene.Profile.SegmentedControl.Posts" = "Publicacions"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Publicacions i Respostes"; "Scene.Profile.SegmentedControl.Replies" = "Respostes"; +"Scene.RebloggedBy.Title" = "Impulsat per"; "Scene.Register.Error.Item.Agreement" = "Acord"; "Scene.Register.Error.Item.Email" = "Correu electrònic"; "Scene.Register.Error.Item.Locale" = "Idioma"; @@ -283,7 +292,8 @@ carregat a Mastodon."; "Scene.Register.Input.Password.Require" = "La teva contrasenya com a mínim necessita:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Aquest nom d'usuari ja està en ús."; "Scene.Register.Input.Username.Placeholder" = "nom d'usuari"; -"Scene.Register.Title" = "Parla'ns de tu."; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Anem a configurar-te a %@"; +"Scene.Register.Title" = "Anem a configurar-te a %@"; "Scene.Report.Content1" = "Hi ha alguna altre publicació que vulguis afegir a l'informe?"; "Scene.Report.Content2" = "Hi ha alguna cosa que els moderadors hagin de saber sobre aquest informe?"; "Scene.Report.ReportSentTitle" = "Gràcies per informar, ho investigarem."; @@ -292,6 +302,38 @@ carregat a Mastodon."; "Scene.Report.SkipToSend" = "Envia sense comentaris"; "Scene.Report.Step1" = "Pas 1 de 2"; "Scene.Report.Step2" = "Pas 2 de 2"; +"Scene.Report.StepFinal.BlockUser" = "Bloca %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "No vols veure això?"; +"Scene.Report.StepFinal.MuteUser" = "Silencia %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "Ja no podran seguir ni veure les teves publicacions, però poden veure si han estat bloquejats."; +"Scene.Report.StepFinal.Unfollow" = "Deixa de seguir"; +"Scene.Report.StepFinal.UnfollowUser" = "Deixa de seguir %@"; +"Scene.Report.StepFinal.Unfollowed" = "S'ha deixat de seguir"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Quan veus alguna cosa que no t'agrada a Mastodon, pots eliminar la persona de la vostra experiència."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Mentre ho revisem, pots prendre mesures contra %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "No veuràs les seves publicacions o impulsos a la teva línia de temps personal. No sabran que han estat silenciats."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Hi ha res més que hauríem de saber?"; +"Scene.Report.StepFour.Step4Of4" = "Pas 4 de 4"; +"Scene.Report.StepOne.IDontLikeIt" = "No m'agrada"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "No és una cosa que vulguis veure"; +"Scene.Report.StepOne.ItViolatesServerRules" = "Infringeix les normes del servidor"; +"Scene.Report.StepOne.ItsSomethingElse" = "És una altra cosa"; +"Scene.Report.StepOne.ItsSpam" = "És contingut brossa"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Enllaços maliciosos, compromís falç o respostes repetitives"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Selecciona la millor coincidència"; +"Scene.Report.StepOne.Step1Of4" = "Pas 1 de 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "El problema no encaixa en altres categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Quin és el problema amb aquest compte?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Quin és el problema amb aquesta publicació?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Quin és el problema amb %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Ets conscient que incompleix normes específiques"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Hi ha alguna publicació que recolzi aquest informe?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Selecciona tot el que correspongui"; +"Scene.Report.StepThree.Step3Of4" = "Pas 3 de 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "Simplement no m'agrada"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Selecciona tot el que correspongui"; +"Scene.Report.StepTwo.Step2Of4" = "Pas 2 de 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Quines normes s'estan infringint?"; "Scene.Report.TextPlaceholder" = "Escriu o enganxa comentaris addicionals"; "Scene.Report.Title" = "Informa sobre %@"; "Scene.Report.TitleReport" = "Informe"; @@ -328,10 +370,11 @@ carregat a Mastodon."; "Scene.ServerPicker.Button.Category.Tech" = "tecnologia"; "Scene.ServerPicker.Button.SeeLess" = "Veure Menys"; "Scene.ServerPicker.Button.SeeMore" = "Veure Més"; -"Scene.ServerPicker.EmptyState.BadNetwork" = "S'ha produït un error en carregar les dades. Comprova la teva connexió a Internet."; +"Scene.ServerPicker.EmptyState.BadNetwork" = "Alguna cosa no ha anat bé en carregar les dades. Comprova la teva connexió a Internet."; "Scene.ServerPicker.EmptyState.FindingServers" = "Cercant els servidors disponibles..."; "Scene.ServerPicker.EmptyState.NoResults" = "No hi ha resultats"; -"Scene.ServerPicker.Input.Placeholder" = "Troba un servidor o uneix-te al teu..."; +"Scene.ServerPicker.Input.Placeholder" = "Cerca servidors"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Cerca servidors o introdueix l'enllaç"; "Scene.ServerPicker.Label.Category" = "CATEGORIA"; "Scene.ServerPicker.Label.Language" = "LLENGUATGE"; "Scene.ServerPicker.Label.Users" = "USUARIS"; @@ -341,7 +384,7 @@ carregat a Mastodon."; "Scene.ServerRules.Button.Confirm" = "Hi estic d'acord"; "Scene.ServerRules.PrivacyPolicy" = "política de privadesa"; "Scene.ServerRules.Prompt" = "Al continuar, estàs subjecte als termes de servei i a la política de privacitat de %@."; -"Scene.ServerRules.Subtitle" = "Aquestes regles estan establertes per els administradors de %@."; +"Scene.ServerRules.Subtitle" = "Aquestes regles estan establertes i aplicades per els moderadors de %@."; "Scene.ServerRules.TermsOfService" = "termes del servei"; "Scene.ServerRules.Title" = "Algunes regles bàsiques."; "Scene.Settings.Footer.MastodonDescription" = "Mastodon és un programari de codi obert. Pots informar de problemes a GitHub a %@ (%@)"; @@ -380,7 +423,7 @@ carregat a Mastodon."; "Scene.Settings.Section.SpicyZone.Title" = "La Zona Picant"; "Scene.Settings.Title" = "Configuració"; "Scene.SuggestionAccount.FollowExplain" = "Quan segueixes algú, veuràs les seves publicacions a Inici."; -"Scene.SuggestionAccount.Title" = "Cerca Persones per Seguir"; +"Scene.SuggestionAccount.Title" = "Cerca Persones a Seguir"; "Scene.Thread.BackTitle" = "Publicació"; "Scene.Thread.Title" = "Publicació de %@"; "Scene.Welcome.GetStarted" = "Comença"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.stringsdict index dfbd38c0b..cc28edbc6 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ca.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld caràcters + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Seguit per %1$@, i un altre mutu + other + Seguit per %1$@, i %ld mutus + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ publicacions + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 mèdia + other + %ld mèdia + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings index 1db4f7936..628059868 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.strings @@ -199,6 +199,7 @@ "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "بەرنامەی ئیمێڵەکەت بکەوە"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "ئیمێڵەکانت ببینە."; "Scene.ConfirmEmail.Subtitle" = "بۆ پشتڕاستکردنەوەی هەژمارەکەت ئەو بەستەرە بکەوە کە بە ئیمێڵ بۆمان ناردوویت."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "کۆتا شت."; "Scene.Discovery.Intro" = "پۆست هەیە سەرنجیان لەسەرە لە گۆشەکەی تۆ."; "Scene.Discovery.Tabs.Community" = "Community"; @@ -206,9 +207,16 @@ "Scene.Discovery.Tabs.Hashtags" = "هاشتاگەکان"; "Scene.Discovery.Tabs.News" = "هەواڵەکان"; "Scene.Discovery.Tabs.Posts" = "پۆستەکان"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "بەدڵبووەکانت"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "شوێنکەوتووەکانی لە ڕاژەکارەکانی ترەوە نیشان نادرێت."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "شوێنکەوتنەکانی بۆ هەژماری ڕاژەکارەکانی تر نیشان نادرێت."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "پۆستە نوێکان ببینە"; "Scene.HomeTimeline.NavigationBarState.Offline" = "دەرهێڵ"; "Scene.HomeTimeline.NavigationBarState.Published" = "بڵاوکرایەوە!"; @@ -250,6 +258,7 @@ "Scene.Profile.SegmentedControl.Posts" = "پۆستەکان"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "پۆست و وەڵامەکان"; "Scene.Profile.SegmentedControl.Replies" = "وەڵامەکان"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "ڕێککەوتن"; "Scene.Register.Error.Item.Email" = "ئیمێڵ"; "Scene.Register.Error.Item.Locale" = "زمان"; @@ -282,6 +291,7 @@ "Scene.Register.Input.Password.Require" = "تێپەڕوشەکەت لایەنی کەم پێویستیی هەیە بە:"; "Scene.Register.Input.Username.DuplicatePrompt" = "ئەم ناوە گیراوە."; "Scene.Register.Input.Username.Placeholder" = "ناوی بەکارهێنەر"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "خۆت تۆمار بکە لە %@"; "Scene.Report.Content1" = "پۆستی تر هەیە بتەوێت سکاڵایان لێ بکەیت؟"; "Scene.Report.Content2" = "هیچ شتێکی هەیە بە چاودێرەکان بیزانن دەربارەی ئەم سکاڵایە؟"; @@ -291,6 +301,38 @@ "Scene.Report.SkipToSend" = "بەبێ لێدوان بینێرە"; "Scene.Report.Step1" = "هەنگاوی 1 لە 2"; "Scene.Report.Step2" = "هەنگاوی 2 لە 2"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Unfollow"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; +"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; +"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; +"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; +"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; +"Scene.Report.StepOne.ItsSpam" = "It’s spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; "Scene.Report.TextPlaceholder" = "ڕوونکردنەوەی زۆرتر بدە"; "Scene.Report.Title" = "سکاڵا لە %@ بکە"; "Scene.Report.TitleReport" = "سکاڵای لێ بکە"; @@ -331,6 +373,7 @@ "Scene.ServerPicker.EmptyState.FindingServers" = "ڕاژەکار دەدۆزرێتەوە..."; "Scene.ServerPicker.EmptyState.NoResults" = "ئەنجام نییە"; "Scene.ServerPicker.Input.Placeholder" = "بگەڕێ"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "بەش"; "Scene.ServerPicker.Label.Language" = "زمان"; "Scene.ServerPicker.Label.Users" = "بەکارهێنەر"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.stringsdict index e744a4bd5..001a8a608 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ckb.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld نووسە + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ پۆست + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings index 29845981c..d5e8be0a2 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.strings @@ -108,7 +108,7 @@ Bitte überprüfe deine Internetverbindung."; "Common.Controls.Status.MediaContentWarning" = "Tippe irgendwo zum Anzeigen"; "Common.Controls.Status.Poll.Closed" = "Beendet"; "Common.Controls.Status.Poll.Vote" = "Abstimmen"; -"Common.Controls.Status.SensitiveContent" = "Sensitive Content"; +"Common.Controls.Status.SensitiveContent" = "NSFW-Inhalt"; "Common.Controls.Status.ShowPost" = "Beitrag anzeigen"; "Common.Controls.Status.ShowUserProfile" = "Benutzerprofil anzeigen"; "Common.Controls.Status.Tag.Email" = "E-Mail"; @@ -199,18 +199,25 @@ kann nicht auf Mastodon hochgeladen werden."; "Scene.ConfirmEmail.OpenEmailApp.Mail" = "Mail"; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "E-Mail-Client öffnen"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Überprüfe deinen Posteingang."; -"Scene.ConfirmEmail.Subtitle" = "Wir haben gerade eine E-Mail an %@ gesendet, -tippe darin auf den Link, um Dein Konto zu bestätigen."; +"Scene.ConfirmEmail.Subtitle" = "Schaue kurz in dein E-Mail-Postfach und tippe den Link an, den wir dir gesendet haben."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "Noch eine letzte Sache."; -"Scene.Discovery.Intro" = "These are the posts gaining traction in your corner of Mastodon."; +"Scene.Discovery.Intro" = "Dies sind die Beiträge, die in deiner Umgebung auf Mastodon beliebter werden."; "Scene.Discovery.Tabs.Community" = "Community"; "Scene.Discovery.Tabs.ForYou" = "Für dich"; "Scene.Discovery.Tabs.Hashtags" = "Hashtags"; "Scene.Discovery.Tabs.News" = "Nachrichten"; "Scene.Discovery.Tabs.Posts" = "Beiträge"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Deine Favoriten"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Follower von anderen Servern werden nicht angezeigt."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Wem das Konto folgt wird von anderen Servern werden nicht angezeigt."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Neue Beiträge anzeigen"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Veröffentlicht!"; @@ -252,6 +259,7 @@ tippe darin auf den Link, um Dein Konto zu bestätigen."; "Scene.Profile.SegmentedControl.Posts" = "Beiträge"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Beiträge und Antworten"; "Scene.Profile.SegmentedControl.Replies" = "Antworten"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Vereinbarung"; "Scene.Register.Error.Item.Email" = "E-Mail"; "Scene.Register.Error.Item.Locale" = "Sprache"; @@ -284,6 +292,7 @@ tippe darin auf den Link, um Dein Konto zu bestätigen."; "Scene.Register.Input.Password.Require" = "Anforderungen an dein Passwort:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Dieser Benutzername ist vergeben."; "Scene.Register.Input.Username.Placeholder" = "Benutzername"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "Erzähle uns von dir."; "Scene.Report.Content1" = "Gibt es noch weitere Beiträge, die du der Meldung hinzufügen möchtest?"; "Scene.Report.Content2" = "Gibt es etwas, was die Moderatoren über diese Meldung wissen sollten?"; @@ -293,6 +302,38 @@ tippe darin auf den Link, um Dein Konto zu bestätigen."; "Scene.Report.SkipToSend" = "Ohne Kommentar abschicken"; "Scene.Report.Step1" = "Schritt 1 von 2"; "Scene.Report.Step2" = "Schritt 2 von 2"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Unfollow"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; +"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; +"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; +"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; +"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; +"Scene.Report.StepOne.ItsSpam" = "It’s spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; "Scene.Report.TextPlaceholder" = "Zusätzliche Kommentare eingeben oder einfügen"; "Scene.Report.Title" = "%@ melden"; "Scene.Report.TitleReport" = "Melden"; @@ -332,7 +373,8 @@ tippe darin auf den Link, um Dein Konto zu bestätigen."; "Scene.ServerPicker.EmptyState.BadNetwork" = "Beim Laden der Daten ist etwas schief gelaufen. Überprüfe deine Internetverbindung."; "Scene.ServerPicker.EmptyState.FindingServers" = "Verfügbare Server werden gesucht..."; "Scene.ServerPicker.EmptyState.NoResults" = "Keine Ergebnisse"; -"Scene.ServerPicker.Input.Placeholder" = "Finde einen Server oder trete deinem eigenen bei..."; +"Scene.ServerPicker.Input.Placeholder" = "Nach Server suchen oder URL eingeben"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "KATEGORIE"; "Scene.ServerPicker.Label.Language" = "SPRACHE"; "Scene.ServerPicker.Label.Users" = "BENUTZER"; @@ -385,9 +427,9 @@ beliebigen Server."; "Scene.SuggestionAccount.Title" = "Finde Personen zum Folgen"; "Scene.Thread.BackTitle" = "Beitrag"; "Scene.Thread.Title" = "Beitrag von %@"; -"Scene.Welcome.GetStarted" = "Erste Schritte"; +"Scene.Welcome.GetStarted" = "Registrieren"; "Scene.Welcome.LogIn" = "Anmelden"; "Scene.Welcome.Slogan" = "Soziale Netzwerke wieder in deinen Händen."; "Scene.Wizard.AccessibilityHint" = "Doppeltippen, um diesen Assistenten zu schließen"; -"Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Wechsel zwischen mehreren Konten durch drücken der Profil-Schaltfläche."; +"Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Wechsel zwischen mehreren Konten durch Drücken der Profil-Schaltfläche."; "Scene.Wizard.NewInMastodon" = "Neu in Mastodon"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.stringsdict index 20e8b615e..3ea0fd0e3 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/de.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld Zeichen + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ Beiträge + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings index fe66593f4..4ce7015d7 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.strings @@ -200,6 +200,7 @@ uploaded to Mastodon."; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Open Email Client"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Check your inbox."; "Scene.ConfirmEmail.Subtitle" = "Tap the link we emailed to you to verify your account."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "One last thing."; "Scene.Discovery.Intro" = "These are the posts gaining traction in your corner of Mastodon."; "Scene.Discovery.Tabs.Community" = "Community"; @@ -207,9 +208,16 @@ uploaded to Mastodon."; "Scene.Discovery.Tabs.Hashtags" = "Hashtags"; "Scene.Discovery.Tabs.News" = "News"; "Scene.Discovery.Tabs.Posts" = "Posts"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Your Favorites"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Followers from other servers are not displayed."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; @@ -251,6 +259,7 @@ uploaded to Mastodon."; "Scene.Profile.SegmentedControl.Posts" = "Posts"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Posts and Replies"; "Scene.Profile.SegmentedControl.Replies" = "Replies"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Agreement"; "Scene.Register.Error.Item.Email" = "Email"; "Scene.Register.Error.Item.Locale" = "Locale"; @@ -283,6 +292,7 @@ uploaded to Mastodon."; "Scene.Register.Input.Password.Require" = "Your password needs at least:"; "Scene.Register.Input.Username.DuplicatePrompt" = "This username is taken."; "Scene.Register.Input.Username.Placeholder" = "username"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "Let’s get you set up on %@"; "Scene.Report.Content1" = "Are there any other posts you’d like to add to the report?"; "Scene.Report.Content2" = "Is there anything the moderators should know about this report?"; @@ -292,6 +302,38 @@ uploaded to Mastodon."; "Scene.Report.SkipToSend" = "Send without comment"; "Scene.Report.Step1" = "Step 1 of 2"; "Scene.Report.Step2" = "Step 2 of 2"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Unfollow"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; +"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; +"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; +"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; +"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; +"Scene.Report.StepOne.ItsSpam" = "It’s spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; "Scene.Report.TextPlaceholder" = "Type or paste additional comments"; "Scene.Report.Title" = "Report %@"; "Scene.Report.TitleReport" = "Report"; @@ -332,6 +374,7 @@ uploaded to Mastodon."; "Scene.ServerPicker.EmptyState.FindingServers" = "Finding available servers..."; "Scene.ServerPicker.EmptyState.NoResults" = "No results"; "Scene.ServerPicker.Input.Placeholder" = "Search servers"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "CATEGORY"; "Scene.ServerPicker.Label.Language" = "LANGUAGE"; "Scene.ServerPicker.Label.Users" = "USERS"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.stringsdict index 503ff9dbd..bdcae6ac9 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/en.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld characters + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ posts + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/es-419.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/es-419.lproj/Localizable.strings deleted file mode 100644 index db6cacc37..000000000 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/es-419.lproj/Localizable.strings +++ /dev/null @@ -1,394 +0,0 @@ -"Common.Alerts.BlockDomain.BlockEntireDomain" = "Bloquear dominio"; -"Common.Alerts.BlockDomain.Title" = "¿Estás completamente seguro que querés bloquear el %@ entero? En la mayoría de los casos, unos cuantos bloqueos y silenciados puntuales son suficientes y preferibles. No vas a ver contenido de ese dominio y todos tus seguidores de ese dominio serán quitados."; -"Common.Alerts.CleanCache.Message" = "Se limpió exitosamente %@ de la memoria caché."; -"Common.Alerts.CleanCache.Title" = "Limpiar caché"; -"Common.Alerts.Common.PleaseTryAgain" = "Por favor, intentá de nuevo."; -"Common.Alerts.Common.PleaseTryAgainLater" = "Por favor, intentá de nuevo más tarde."; -"Common.Alerts.DeletePost.Message" = "¿Estás seguro que querés eliminar este mensaje?"; -"Common.Alerts.DeletePost.Title" = "Eliminar mensaje"; -"Common.Alerts.DiscardPostContent.Message" = "Confirmá para descartar el contenido del mensaje redactado."; -"Common.Alerts.DiscardPostContent.Title" = "Descartar borrador"; -"Common.Alerts.EditProfileFailure.Message" = "No se pudo editar el perfil. Por favor, intentá de nuevo."; -"Common.Alerts.EditProfileFailure.Title" = "Error al editar el perfil"; -"Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "No se puede adjuntar más de un video."; -"Common.Alerts.PublishPostFailure.AttachmentsMessage.VideoAttachWithPhoto" = "No se puede adjuntar un video a un mensaje que ya contenga imágenes."; -"Common.Alerts.PublishPostFailure.Message" = "Error al enviar en mensaje. -Por favor, revisá tu conexión a Internet."; -"Common.Alerts.PublishPostFailure.Title" = "Error al enviar el mensaje"; -"Common.Alerts.SavePhotoFailure.Message" = "Por favor, habilitá el permiso de acceso a la biblioteca de fotos para guardar la imagen."; -"Common.Alerts.SavePhotoFailure.Title" = "Error al guardar la imagen"; -"Common.Alerts.ServerError.Title" = "Error del servidor"; -"Common.Alerts.SignOut.Confirm" = "Cerrar sesión"; -"Common.Alerts.SignOut.Message" = "¿Estás seguro que querés cerrar la sesión?"; -"Common.Alerts.SignOut.Title" = "Cerrar sesión"; -"Common.Alerts.SignUpFailure.Title" = "Error al registrarse"; -"Common.Alerts.VoteFailure.PollEnded" = "La encuesta finalizó"; -"Common.Alerts.VoteFailure.Title" = "Error al votar"; -"Common.Controls.Actions.Add" = "Agregar"; -"Common.Controls.Actions.Back" = "Volver"; -"Common.Controls.Actions.BlockDomain" = "Bloquear a %@"; -"Common.Controls.Actions.Cancel" = "Cancelar"; -"Common.Controls.Actions.Compose" = "Redactar"; -"Common.Controls.Actions.Confirm" = "Confirmar"; -"Common.Controls.Actions.Continue" = "Continuar"; -"Common.Controls.Actions.CopyPhoto" = "Copiar foto"; -"Common.Controls.Actions.Delete" = "Eliminar"; -"Common.Controls.Actions.Discard" = "Descartar"; -"Common.Controls.Actions.Done" = "Listo"; -"Common.Controls.Actions.Edit" = "Editar"; -"Common.Controls.Actions.FindPeople" = "Encontrá cuentas para seguir"; -"Common.Controls.Actions.ManuallySearch" = "Buscar manualmente"; -"Common.Controls.Actions.Next" = "Siguiente"; -"Common.Controls.Actions.Ok" = "Aceptar"; -"Common.Controls.Actions.Open" = "Abrir"; -"Common.Controls.Actions.OpenInBrowser" = "Abrir en el navegador"; -"Common.Controls.Actions.OpenInSafari" = "Abrir en Safari"; -"Common.Controls.Actions.Preview" = "Previsualización"; -"Common.Controls.Actions.Previous" = "Anterior"; -"Common.Controls.Actions.Remove" = "Quitar"; -"Common.Controls.Actions.Reply" = "Responder"; -"Common.Controls.Actions.ReportUser" = "Denunciar a %@"; -"Common.Controls.Actions.Save" = "Guardar"; -"Common.Controls.Actions.SavePhoto" = "Guardar foto"; -"Common.Controls.Actions.SeeMore" = "Ver más"; -"Common.Controls.Actions.Settings" = "Configuración"; -"Common.Controls.Actions.Share" = "Compartir"; -"Common.Controls.Actions.SharePost" = "Compartir mensaje"; -"Common.Controls.Actions.ShareUser" = "Compartir %@"; -"Common.Controls.Actions.SignIn" = "Iniciar sesión"; -"Common.Controls.Actions.SignUp" = "Registrarse"; -"Common.Controls.Actions.Skip" = "Omitir"; -"Common.Controls.Actions.TakePhoto" = "Tomar foto"; -"Common.Controls.Actions.TryAgain" = "Intentá de nuevo"; -"Common.Controls.Actions.UnblockDomain" = "Desbloquear a %@"; -"Common.Controls.Friendship.Block" = "Bloquear"; -"Common.Controls.Friendship.BlockDomain" = "Bloquear %@"; -"Common.Controls.Friendship.BlockUser" = "Bloquear a %@"; -"Common.Controls.Friendship.Blocked" = "Bloqueado"; -"Common.Controls.Friendship.EditInfo" = "Editar información"; -"Common.Controls.Friendship.Follow" = "Seguir"; -"Common.Controls.Friendship.Following" = "Siguiendo"; -"Common.Controls.Friendship.Mute" = "Silenciar"; -"Common.Controls.Friendship.MuteUser" = "Silenciar a %@"; -"Common.Controls.Friendship.Muted" = "Silenciado"; -"Common.Controls.Friendship.Pending" = "Pendientes"; -"Common.Controls.Friendship.Request" = "Solicitar"; -"Common.Controls.Friendship.Unblock" = "Desbloquear"; -"Common.Controls.Friendship.UnblockUser" = "Desbloquear a %@"; -"Common.Controls.Friendship.Unmute" = "Dejar de silenciar"; -"Common.Controls.Friendship.UnmuteUser" = "Dejar de silenciar a %@"; -"Common.Controls.Keyboard.Common.ComposeNewPost" = "Redactar un nuevo mensaje"; -"Common.Controls.Keyboard.Common.OpenSettings" = "Abrir Configuración"; -"Common.Controls.Keyboard.Common.ShowFavorites" = "Mostrar favoritos"; -"Common.Controls.Keyboard.Common.SwitchToTab" = "Cambiar a %@"; -"Common.Controls.Keyboard.SegmentedControl.NextSection" = "Sección siguiente"; -"Common.Controls.Keyboard.SegmentedControl.PreviousSection" = "Sección anterior"; -"Common.Controls.Keyboard.Timeline.NextStatus" = "Mensaje siguiente"; -"Common.Controls.Keyboard.Timeline.OpenAuthorProfile" = "Abrir perfil del autor"; -"Common.Controls.Keyboard.Timeline.OpenRebloggerProfile" = "Abrir perfil del adherente"; -"Common.Controls.Keyboard.Timeline.OpenStatus" = "Abrir mensaje"; -"Common.Controls.Keyboard.Timeline.PreviewImage" = "Previsualizar imagen"; -"Common.Controls.Keyboard.Timeline.PreviousStatus" = "Mensaje anterior"; -"Common.Controls.Keyboard.Timeline.ReplyStatus" = "Responder al mensaje"; -"Common.Controls.Keyboard.Timeline.ToggleContentWarning" = "Cambiar modo de advertencia de contenido"; -"Common.Controls.Keyboard.Timeline.ToggleFavorite" = "Cambiar marca de favorito del mensaje"; -"Common.Controls.Keyboard.Timeline.ToggleReblog" = "Cambiar adhesión al mensaje"; -"Common.Controls.Status.Actions.Favorite" = "Marcar como favorito"; -"Common.Controls.Status.Actions.Hide" = "Ocultar"; -"Common.Controls.Status.Actions.Menu" = "Menú"; -"Common.Controls.Status.Actions.Reblog" = "Adherir"; -"Common.Controls.Status.Actions.Reply" = "Responder"; -"Common.Controls.Status.Actions.ShowGif" = "Mostrar GIF"; -"Common.Controls.Status.Actions.ShowImage" = "Mostrar imagen"; -"Common.Controls.Status.Actions.ShowVideoPlayer" = "Mostrar reproductor de video"; -"Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Tocá y mantené presionado para mostrar el menú"; -"Common.Controls.Status.Actions.Unfavorite" = "Dejar de marcar como favorito"; -"Common.Controls.Status.Actions.Unreblog" = "Deshacer adhesión"; -"Common.Controls.Status.ContentWarning" = "Advertencia de contenido"; -"Common.Controls.Status.MediaContentWarning" = "Tocá en cualquier parte para mostrar"; -"Common.Controls.Status.Poll.Closed" = "Cerrada"; -"Common.Controls.Status.Poll.Vote" = "Votar"; -"Common.Controls.Status.SensitiveContent" = "Contenido sensible"; -"Common.Controls.Status.ShowPost" = "Mostrar mensaje"; -"Common.Controls.Status.ShowUserProfile" = "Mostrar perfil de usuario"; -"Common.Controls.Status.Tag.Email" = "Correo electrónico"; -"Common.Controls.Status.Tag.Emoji" = "Emoji"; -"Common.Controls.Status.Tag.Hashtag" = "Etiqueta"; -"Common.Controls.Status.Tag.Link" = "Enlace"; -"Common.Controls.Status.Tag.Mention" = "Mención"; -"Common.Controls.Status.Tag.Url" = "Dirección web"; -"Common.Controls.Status.TapToReveal" = "Tocá para mostrar"; -"Common.Controls.Status.UserReblogged" = "%@ adhirió"; -"Common.Controls.Status.UserRepliedTo" = "Respondió a %@"; -"Common.Controls.Status.Visibility.Direct" = "Sólo el usuario mencionado puede ver este mensaje."; -"Common.Controls.Status.Visibility.Private" = "Sólo sus seguidores pueden ver este mensaje."; -"Common.Controls.Status.Visibility.PrivateFromMe" = "Sólo mis seguidores pueden ver este mensaje."; -"Common.Controls.Status.Visibility.Unlisted" = "Todo el mundo puede ver este mensaje pero no mostrarse en la línea temporal pública."; -"Common.Controls.Tabs.Home" = "Principal"; -"Common.Controls.Tabs.Notification" = "Notificación"; -"Common.Controls.Tabs.Profile" = "Perfil"; -"Common.Controls.Tabs.Search" = "Buscar"; -"Common.Controls.Timeline.Filtered" = "Filtrado"; -"Common.Controls.Timeline.Header.BlockedWarning" = "No podés ver el perfil de este usuario - hasta que dicho usuario te desbloquee."; -"Common.Controls.Timeline.Header.BlockingWarning" = "No podés ver el perfil de este usuario - hasta que lo desbloquees. -Tu perfil le aparece así a este usuario."; -"Common.Controls.Timeline.Header.NoStatusFound" = "Mensaje no encontrado"; -"Common.Controls.Timeline.Header.SuspendedWarning" = "Este usuario está suspendido."; -"Common.Controls.Timeline.Header.UserBlockedWarning" = "No podés ver el perfil de %@ - hasta que dicho usuario te desbloquee."; -"Common.Controls.Timeline.Header.UserBlockingWarning" = "No podés ver el perfil de %@ - hasta que lo desbloquees. -Tu perfil le aparece así a este usuario."; -"Common.Controls.Timeline.Header.UserSuspendedWarning" = "La cuenta de %@ está suspendida."; -"Common.Controls.Timeline.Loader.LoadMissingPosts" = "Cargar mensajes faltantes"; -"Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Cargando mensajes faltantes…"; -"Common.Controls.Timeline.Loader.ShowMoreReplies" = "Mostrar más respuestas"; -"Common.Controls.Timeline.Timestamp.Now" = "Ahora"; -"Scene.AccountList.AddAccount" = "Agregar cuenta"; -"Scene.AccountList.DismissAccountSwitcher" = "Descartar cambio de cuenta"; -"Scene.AccountList.TabBarHint" = "Perfil seleccionado actualmente: %@. Tocá dos veces y mantenelo presionado para cambiar de cuenta"; -"Scene.Compose.Accessibility.AppendAttachment" = "Agregar archivo adjunto"; -"Scene.Compose.Accessibility.AppendPoll" = "Agregar encuesta"; -"Scene.Compose.Accessibility.CustomEmojiPicker" = "Selector de emoji personalizado"; -"Scene.Compose.Accessibility.DisableContentWarning" = "Deshabilitar advertencia de contenido"; -"Scene.Compose.Accessibility.EnableContentWarning" = "Habilitar advertencia de contenido"; -"Scene.Compose.Accessibility.PostVisibilityMenu" = "Menú de visibilidad del mensaje"; -"Scene.Compose.Accessibility.RemovePoll" = "Quitar encuesta"; -"Scene.Compose.Attachment.AttachmentBroken" = "Este archivo de %@ está roto -y no se puede subir a Mastodon."; -"Scene.Compose.Attachment.DescriptionPhoto" = "Describí la foto para personas con dificultades visuales…"; -"Scene.Compose.Attachment.DescriptionVideo" = "Describí el video para personas con dificultades visuales…"; -"Scene.Compose.Attachment.Photo" = "foto"; -"Scene.Compose.Attachment.Video" = "video"; -"Scene.Compose.AutoComplete.SpaceToAdd" = "Espacio para agregar"; -"Scene.Compose.ComposeAction" = "Enviar"; -"Scene.Compose.ContentInputPlaceholder" = "¿Qué onda?"; -"Scene.Compose.ContentWarning.Placeholder" = "Escribí una advertencia precisa acá…"; -"Scene.Compose.Keyboard.AppendAttachmentEntry" = "Agregar archivo adjunto - %@"; -"Scene.Compose.Keyboard.DiscardPost" = "Descartar mensaje"; -"Scene.Compose.Keyboard.PublishPost" = "Enviar mensaje"; -"Scene.Compose.Keyboard.SelectVisibilityEntry" = "Seleccionar visibilidad - %@"; -"Scene.Compose.Keyboard.ToggleContentWarning" = "Cambiar advertencia de contenido"; -"Scene.Compose.Keyboard.TogglePoll" = "Cambiar encuesta"; -"Scene.Compose.MediaSelection.Browse" = "Explorar"; -"Scene.Compose.MediaSelection.Camera" = "Tomar foto"; -"Scene.Compose.MediaSelection.PhotoLibrary" = "Biblioteca de fotos"; -"Scene.Compose.Poll.DurationTime" = "Duración: %@"; -"Scene.Compose.Poll.OneDay" = "1 día"; -"Scene.Compose.Poll.OneHour" = "1 hora"; -"Scene.Compose.Poll.OptionNumber" = "Opción %ld"; -"Scene.Compose.Poll.SevenDays" = "7 días"; -"Scene.Compose.Poll.SixHours" = "6 horas"; -"Scene.Compose.Poll.ThirtyMinutes" = "30 minutos"; -"Scene.Compose.Poll.ThreeDays" = "3 días"; -"Scene.Compose.ReplyingToUser" = "respondiendo a %@"; -"Scene.Compose.Title.NewPost" = "Nuevo mensaje"; -"Scene.Compose.Title.NewReply" = "Nueva respuesta"; -"Scene.Compose.Visibility.Direct" = "Sólo a las cuentas que menciono"; -"Scene.Compose.Visibility.Private" = "Sólo para seguidores"; -"Scene.Compose.Visibility.Public" = "Público"; -"Scene.Compose.Visibility.Unlisted" = "No listado"; -"Scene.ConfirmEmail.Button.OpenEmailApp" = "Abrir aplicación de correo electrónico"; -"Scene.ConfirmEmail.Button.Resend" = "Reenviar"; -"Scene.ConfirmEmail.DontReceiveEmail.Description" = "Revisá si tu dirección de correo electrónico es correcta así como tu carpeta de correo basura / correo no deseado / spam, si todavía no lo hiciste."; -"Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Reenviar correo electrónico"; -"Scene.ConfirmEmail.DontReceiveEmail.Title" = "Revisá tu correo electrónico"; -"Scene.ConfirmEmail.OpenEmailApp.Description" = "Te acabamos de enviar un correo electrónico. Revisá tu carpeta de correo basura / correo no deseado / spam, si todavía no lo hiciste."; -"Scene.ConfirmEmail.OpenEmailApp.Mail" = "Correo"; -"Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Abrir cliente de correo electrónico"; -"Scene.ConfirmEmail.OpenEmailApp.Title" = "Revisá tu bandeja de entrada."; -"Scene.ConfirmEmail.Subtitle" = "Acabamos de enviar un correo electrónico a %@, -pulsá en el enlace para confirmar tu cuenta."; -"Scene.ConfirmEmail.Title" = "Una última cosa."; -"Scene.Discovery.Intro" = "Estos son los mensajes que están ganando tracción en tu rincón de Mastodon."; -"Scene.Discovery.Tabs.Community" = "Community"; -"Scene.Discovery.Tabs.ForYou" = "Para vos"; -"Scene.Discovery.Tabs.Hashtags" = "Etiquetas"; -"Scene.Discovery.Tabs.News" = "Novedades"; -"Scene.Discovery.Tabs.Posts" = "Mensajes"; -"Scene.Favorite.Title" = "Tus favoritos"; -"Scene.Follower.Footer" = "No se muestran los seguidores de otros servidores."; -"Scene.Following.Footer" = "No se muestran las cuentas de otros servidores que seguís."; -"Scene.HomeTimeline.NavigationBarState.NewPosts" = "Ver nuevos mensajes"; -"Scene.HomeTimeline.NavigationBarState.Offline" = "Desconectado"; -"Scene.HomeTimeline.NavigationBarState.Published" = "¡Enviado!"; -"Scene.HomeTimeline.NavigationBarState.Publishing" = "Enviando mensaje…"; -"Scene.HomeTimeline.Title" = "Principal"; -"Scene.Notification.Keyobard.ShowEverything" = "Mostrar todo"; -"Scene.Notification.Keyobard.ShowMentions" = "Mostrar menciones"; -"Scene.Notification.NotificationDescription.FavoritedYourPost" = "marcó como favorito tu mensaje"; -"Scene.Notification.NotificationDescription.FollowedYou" = "te sigue"; -"Scene.Notification.NotificationDescription.MentionedYou" = "te mencionó"; -"Scene.Notification.NotificationDescription.PollHasEnded" = "la encuesta terminó"; -"Scene.Notification.NotificationDescription.RebloggedYourPost" = "adhirió a tu mensaje"; -"Scene.Notification.NotificationDescription.RequestToFollowYou" = "solicitó seguirte"; -"Scene.Notification.Title.Everything" = "Todo"; -"Scene.Notification.Title.Mentions" = "Menciones"; -"Scene.Preview.Keyboard.ClosePreview" = "Cerrar previsualización"; -"Scene.Preview.Keyboard.ShowNext" = "Mostrar siguiente"; -"Scene.Preview.Keyboard.ShowPrevious" = "Mostrar anterior"; -"Scene.Profile.Accessibility.DoubleTapToOpenTheList" = "Tocá dos veces para abrir la lista"; -"Scene.Profile.Accessibility.EditAvatarImage" = "Editar imagen de avatar"; -"Scene.Profile.Accessibility.ShowAvatarImage" = "Mostrar imagen de avatar"; -"Scene.Profile.Accessibility.ShowBannerImage" = "Mostrar imagen de banner"; -"Scene.Profile.Dashboard.Followers" = "seguidores"; -"Scene.Profile.Dashboard.Following" = "siguiendo"; -"Scene.Profile.Dashboard.Posts" = "mensajes"; -"Scene.Profile.Fields.AddRow" = "Agregar fila"; -"Scene.Profile.Fields.Placeholder.Content" = "Valor de campo"; -"Scene.Profile.Fields.Placeholder.Label" = "Nombre de campo"; -"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirmá para desbloquear a %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Bloquear cuenta"; -"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirmá para silenciar a %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Silenciar cuenta"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Confirmá para desbloquear a %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Desbloquear cuenta"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Confirmá para dejar de silenciar a %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Title" = "Dejar de silenciar cuenta"; -"Scene.Profile.SegmentedControl.About" = "Información"; -"Scene.Profile.SegmentedControl.Media" = "Medios"; -"Scene.Profile.SegmentedControl.Posts" = "Mensajes"; -"Scene.Profile.SegmentedControl.PostsAndReplies" = "Mensajes y respuestas"; -"Scene.Profile.SegmentedControl.Replies" = "Respuestas"; -"Scene.Register.Error.Item.Agreement" = "Acuerdo"; -"Scene.Register.Error.Item.Email" = "Correo electrónico"; -"Scene.Register.Error.Item.Locale" = "Idioma de la interface"; -"Scene.Register.Error.Item.Password" = "Contraseña"; -"Scene.Register.Error.Item.Reason" = "Motivo"; -"Scene.Register.Error.Item.Username" = "Nombre de usuario"; -"Scene.Register.Error.Reason.Accepted" = "%@ debe ser aceptado"; -"Scene.Register.Error.Reason.Blank" = "%@ es obligatorio"; -"Scene.Register.Error.Reason.Blocked" = "%@ contiene un proveedor de correo electrónico no permitido"; -"Scene.Register.Error.Reason.Inclusion" = "%@ no es un valor soportado"; -"Scene.Register.Error.Reason.Invalid" = "%@ no es válido"; -"Scene.Register.Error.Reason.Reserved" = "%@ es una palabra clave reservada"; -"Scene.Register.Error.Reason.Taken" = "%@ ya está en uso"; -"Scene.Register.Error.Reason.TooLong" = "%@ es demasiado largo"; -"Scene.Register.Error.Reason.TooShort" = "%@ es demasiado corto"; -"Scene.Register.Error.Reason.Unreachable" = "%@ parece no existir"; -"Scene.Register.Error.Special.EmailInvalid" = "Esta no es una dirección de correo electrónico válida"; -"Scene.Register.Error.Special.PasswordTooShort" = "La contraseña es demasiado corta (debe tener al menos 8 caracteres)"; -"Scene.Register.Error.Special.UsernameInvalid" = "El nombre de usuario sólo debe contener caracteres alfanuméricos sin signos diacríticos y subguiones (\"_\")"; -"Scene.Register.Error.Special.UsernameTooLong" = "El nombre de usuario es demasiado largo (no puede tener más de 30 caracteres)"; -"Scene.Register.Input.Avatar.Delete" = "Eliminar"; -"Scene.Register.Input.DisplayName.Placeholder" = "nombre para mostrar"; -"Scene.Register.Input.Email.Placeholder" = "correo electrónico"; -"Scene.Register.Input.Invite.RegistrationUserInviteRequest" = "¿Por qué querés unirte?"; -"Scene.Register.Input.Password.Accessibility.Checked" = "marcado"; -"Scene.Register.Input.Password.Accessibility.Unchecked" = "sin marcar"; -"Scene.Register.Input.Password.CharacterLimit" = "8 caracteres"; -"Scene.Register.Input.Password.Hint" = "Tu contraseña necesita al menos ocho caracteres"; -"Scene.Register.Input.Password.Placeholder" = "contraseña"; -"Scene.Register.Input.Password.Require" = "Tu contraseña necesita al menos:"; -"Scene.Register.Input.Username.DuplicatePrompt" = "Este nombre de usuario ya está en uso."; -"Scene.Register.Input.Username.Placeholder" = "nombre de usuario"; -"Scene.Register.Title" = "Contanos sobre vos."; -"Scene.Report.Content1" = "¿Hay otros mensajes que te gustaría agregar a la denuncia?"; -"Scene.Report.Content2" = "¿Hay algo que los moderadores deban saber sobre esta denuncia?"; -"Scene.Report.ReportSentTitle" = "Gracias por tu denuncia, vamos a revisarla."; -"Scene.Report.Reported" = "DENUNCIADA"; -"Scene.Report.Send" = "Enviar denuncia"; -"Scene.Report.SkipToSend" = "Enviar sin comentarios"; -"Scene.Report.Step1" = "Paso 1 de 2"; -"Scene.Report.Step2" = "Paso 2 de 2"; -"Scene.Report.TextPlaceholder" = "Escribí o pegá comentarios adicionales"; -"Scene.Report.Title" = "Denunciar a %@"; -"Scene.Report.TitleReport" = "Denunciar"; -"Scene.Search.Recommend.Accounts.Description" = "Puede que te guste seguir estas cuentas"; -"Scene.Search.Recommend.Accounts.Follow" = "Seguir"; -"Scene.Search.Recommend.Accounts.Title" = "Cuentas que te pueden gustar"; -"Scene.Search.Recommend.ButtonText" = "Ver todos"; -"Scene.Search.Recommend.HashTag.Description" = "Etiquetas que están recibiendo bastante atención"; -"Scene.Search.Recommend.HashTag.PeopleTalking" = "%@ cuentas están hablando"; -"Scene.Search.Recommend.HashTag.Title" = "Tendencias en Mastodon"; -"Scene.Search.SearchBar.Cancel" = "Cancelar"; -"Scene.Search.SearchBar.Placeholder" = "Buscar etiquetas y cuentas"; -"Scene.Search.Searching.Clear" = "Limpiar"; -"Scene.Search.Searching.EmptyState.NoResults" = "No hay resultados"; -"Scene.Search.Searching.RecentSearch" = "Búsquedas recientes"; -"Scene.Search.Searching.Segment.All" = "Todas"; -"Scene.Search.Searching.Segment.Hashtags" = "Etiquetas"; -"Scene.Search.Searching.Segment.People" = "Cuentas"; -"Scene.Search.Searching.Segment.Posts" = "Mensajes"; -"Scene.Search.Title" = "Buscar"; -"Scene.ServerPicker.Button.Category.Academia" = "académico"; -"Scene.ServerPicker.Button.Category.Activism" = "activismo"; -"Scene.ServerPicker.Button.Category.All" = "Todas"; -"Scene.ServerPicker.Button.Category.AllAccessiblityDescription" = "Categoría: Todas"; -"Scene.ServerPicker.Button.Category.Art" = "arte"; -"Scene.ServerPicker.Button.Category.Food" = "comida"; -"Scene.ServerPicker.Button.Category.Furry" = "furry"; -"Scene.ServerPicker.Button.Category.Games" = "juegos"; -"Scene.ServerPicker.Button.Category.General" = "general"; -"Scene.ServerPicker.Button.Category.Journalism" = "periodismo"; -"Scene.ServerPicker.Button.Category.Lgbt" = "lgbtq+"; -"Scene.ServerPicker.Button.Category.Music" = "música"; -"Scene.ServerPicker.Button.Category.Regional" = "regional"; -"Scene.ServerPicker.Button.Category.Tech" = "tecnología"; -"Scene.ServerPicker.Button.SeeLess" = "Ver menos"; -"Scene.ServerPicker.Button.SeeMore" = "Ver más"; -"Scene.ServerPicker.EmptyState.BadNetwork" = "Algo salió mal al cargar los datos. Revisá tu conexión de Internet."; -"Scene.ServerPicker.EmptyState.FindingServers" = "Buscando servidores disponibles…"; -"Scene.ServerPicker.EmptyState.NoResults" = "No hay resultados"; -"Scene.ServerPicker.Input.Placeholder" = "Encontrá un servidor o unite al tuyo…"; -"Scene.ServerPicker.Label.Category" = "CATEGORÍA"; -"Scene.ServerPicker.Label.Language" = "IDIOMA"; -"Scene.ServerPicker.Label.Users" = "CUENTAS"; -"Scene.ServerPicker.Subtitle" = "Elegí una comunidad basada en tus intereses, región o una de propósitos generales."; -"Scene.ServerPicker.SubtitleExtend" = "Elegí una comunidad basada en tus intereses, región o una de propósitos generales. Cada comunidad es operada por una organización o individuo totalmente independiente."; -"Scene.ServerPicker.Title" = "Elegí un servidor, -el que quieras."; -"Scene.ServerRules.Button.Confirm" = "Estoy de acuerdo"; -"Scene.ServerRules.PrivacyPolicy" = "política de privacidad"; -"Scene.ServerRules.Prompt" = "Al continuar, estás sujeto a los términos de servicio y política de privacidad de %@."; -"Scene.ServerRules.Subtitle" = "Estas reglas son establecidas por los administradores de %@."; -"Scene.ServerRules.TermsOfService" = "términos del servicio"; -"Scene.ServerRules.Title" = "Algunas reglas básicas."; -"Scene.Settings.Footer.MastodonDescription" = "Mastodon es software de código abierto. Podés informar errores en GitHub en %@ (%@)"; -"Scene.Settings.Keyboard.CloseSettingsWindow" = "Cerrar ventana de configuración"; -"Scene.Settings.Section.Appearance.Automatic" = "Automática"; -"Scene.Settings.Section.Appearance.Dark" = "Siempre oscura"; -"Scene.Settings.Section.Appearance.Light" = "Siempre clara"; -"Scene.Settings.Section.Appearance.Title" = "Apariencia"; -"Scene.Settings.Section.BoringZone.AccountSettings" = "Configuración de la cuenta"; -"Scene.Settings.Section.BoringZone.Privacy" = "Política de privacidad"; -"Scene.Settings.Section.BoringZone.Terms" = "Términos del servicio"; -"Scene.Settings.Section.BoringZone.Title" = "La zona aburrida"; -"Scene.Settings.Section.LookAndFeel.Light" = "Claro"; -"Scene.Settings.Section.LookAndFeel.ReallyDark" = "Oscuro de verdad"; -"Scene.Settings.Section.LookAndFeel.SortaDark" = "Algo oscuro"; -"Scene.Settings.Section.LookAndFeel.Title" = "Apariencia"; -"Scene.Settings.Section.LookAndFeel.UseSystem" = "Usar sistema"; -"Scene.Settings.Section.Notifications.Boosts" = "Adhirió a mi mensaje"; -"Scene.Settings.Section.Notifications.Favorites" = "Marcó como favorito mi mensaje"; -"Scene.Settings.Section.Notifications.Follows" = "Me sigue"; -"Scene.Settings.Section.Notifications.Mentions" = "Me mencionó"; -"Scene.Settings.Section.Notifications.Title" = "Notificaciones"; -"Scene.Settings.Section.Notifications.Trigger.Anyone" = "cualquiera"; -"Scene.Settings.Section.Notifications.Trigger.Follow" = "alguien a quien sigo"; -"Scene.Settings.Section.Notifications.Trigger.Follower" = "un seguidor"; -"Scene.Settings.Section.Notifications.Trigger.Noone" = "nadie"; -"Scene.Settings.Section.Notifications.Trigger.Title" = "Notificarme cuando"; -"Scene.Settings.Section.Preference.DisableAvatarAnimation" = "Deshabilitar avatares animados"; -"Scene.Settings.Section.Preference.DisableEmojiAnimation" = "Deshabilitar emojis animados"; -"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "Abrir enlaces en Mastodon"; -"Scene.Settings.Section.Preference.Title" = "Configuración"; -"Scene.Settings.Section.Preference.TrueBlackDarkMode" = "Modo negro oscuro real"; -"Scene.Settings.Section.Preference.UsingDefaultBrowser" = "Usar navegador web predeterminado para abrir enlaces"; -"Scene.Settings.Section.SpicyZone.Clear" = "Limpiar memoria caché multimedia"; -"Scene.Settings.Section.SpicyZone.Signout" = "Cerrar sesión"; -"Scene.Settings.Section.SpicyZone.Title" = "La zona picante"; -"Scene.Settings.Title" = "Configuración"; -"Scene.SuggestionAccount.FollowExplain" = "Cuando sigás a alguien, verás sus mensajes en tu línea temporal principal."; -"Scene.SuggestionAccount.Title" = "Encontrá cuentas para seguir"; -"Scene.Thread.BackTitle" = "Mensaje"; -"Scene.Thread.Title" = "Mensaje de %@"; -"Scene.Welcome.GetStarted" = "Comenzá"; -"Scene.Welcome.LogIn" = "Iniciar sesión"; -"Scene.Welcome.Slogan" = "La red social, -nuevamente en tu poder."; -"Scene.Wizard.AccessibilityHint" = "Tocá dos veces para descartar este asistente"; -"Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Cambiá entre varias cuentas manteniendo presionado el botón del perfil."; -"Scene.Wizard.NewInMastodon" = "Novedad en Mastodon"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings index 09fba0b42..4a883ff45 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.strings @@ -201,6 +201,7 @@ subirse a Mastodon."; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Revisa tu bandeja de entrada."; "Scene.ConfirmEmail.Subtitle" = "Te acabamos de enviar un correo a %@, pulsa en el enlace para confirmar tu cuenta."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "Una última cosa."; "Scene.Discovery.Intro" = "These are the posts gaining traction in your corner of Mastodon."; "Scene.Discovery.Tabs.Community" = "Community"; @@ -208,9 +209,16 @@ pulsa en el enlace para confirmar tu cuenta."; "Scene.Discovery.Tabs.Hashtags" = "Etiquetas"; "Scene.Discovery.Tabs.News" = "Noticias"; "Scene.Discovery.Tabs.Posts" = "Publicaciones"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Tus Favoritos"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "No se muestran los seguidores de otros servidores."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "No se muestran los seguidos de otros servidores."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Ver nuevas publicaciones"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Sin Conexión"; "Scene.HomeTimeline.NavigationBarState.Published" = "¡Publicado!"; @@ -252,6 +260,7 @@ pulsa en el enlace para confirmar tu cuenta."; "Scene.Profile.SegmentedControl.Posts" = "Publicaciones"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Publicaciones y respuestas"; "Scene.Profile.SegmentedControl.Replies" = "Respuestas"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Aceptación"; "Scene.Register.Error.Item.Email" = "Correo electrónico"; "Scene.Register.Error.Item.Locale" = "Idioma"; @@ -284,6 +293,7 @@ pulsa en el enlace para confirmar tu cuenta."; "Scene.Register.Input.Password.Require" = "Tu contraseña debe contener como mínimo:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Este nombre de usuario ya está en uso."; "Scene.Register.Input.Username.Placeholder" = "nombre de usuario"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "Háblanos de ti."; "Scene.Report.Content1" = "¿Hay alguna otra publicación que te gustaría añadir al reporte?"; "Scene.Report.Content2" = "¿Hay algo que los moderadores deberían saber acerca de este reporte?"; @@ -293,6 +303,38 @@ pulsa en el enlace para confirmar tu cuenta."; "Scene.Report.SkipToSend" = "Enviar sin comentarios"; "Scene.Report.Step1" = "Paso 1 de 2"; "Scene.Report.Step2" = "Paso 2 de 2"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Unfollow"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; +"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; +"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; +"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; +"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; +"Scene.Report.StepOne.ItsSpam" = "It’s spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; "Scene.Report.TextPlaceholder" = "Escribe o pega comentarios adicionales"; "Scene.Report.Title" = "Reportar %@"; "Scene.Report.TitleReport" = "Reportar"; @@ -333,6 +375,7 @@ pulsa en el enlace para confirmar tu cuenta."; "Scene.ServerPicker.EmptyState.FindingServers" = "Encontrando servidores disponibles..."; "Scene.ServerPicker.EmptyState.NoResults" = "Sin resultados"; "Scene.ServerPicker.Input.Placeholder" = "Encuentra un servidor o únete al tuyo propio..."; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "CATEGORÍA"; "Scene.ServerPicker.Label.Language" = "IDIOMA"; "Scene.ServerPicker.Label.Users" = "USUARIOS"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.stringsdict index 8f3e94f6b..05bcff142 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/es.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld caracteres + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ publicaciones + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu-ES.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings similarity index 87% rename from MastodonSDK/Sources/MastodonLocalization/Resources/eu-ES.lproj/Localizable.strings rename to MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings index e682977e9..67e1966c9 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu-ES.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.strings @@ -199,8 +199,8 @@ Mastodonera igo."; "Scene.ConfirmEmail.OpenEmailApp.Mail" = "Posta"; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Ireki eposta bezeroa"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Egiaztatu zure sarrerako ontzia."; -"Scene.ConfirmEmail.Subtitle" = "Eposta bat bidali dizugu %@ helbidera, -sakatu kontua berresteko esteka."; +"Scene.ConfirmEmail.Subtitle" = "Sakatu epostaz bidali dizugun loturan zure kontua egiaztatzeko."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "Eta azkenik..."; "Scene.Discovery.Intro" = "These are the posts gaining traction in your corner of Mastodon."; "Scene.Discovery.Tabs.Community" = "Community"; @@ -208,9 +208,16 @@ sakatu kontua berresteko esteka."; "Scene.Discovery.Tabs.Hashtags" = "Traolak"; "Scene.Discovery.Tabs.News" = "Albisteak"; "Scene.Discovery.Tabs.Posts" = "Argitalpenak"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Zure gogokoak"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Beste zerbitzarietako jarraitzaileak ez dira bistaratzen."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Beste zerbitzarietan jarraitutakoak ez dira bistaratzen."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Ikusi bidal. berriak"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Konexio gabe"; "Scene.HomeTimeline.NavigationBarState.Published" = "Argitaratua!"; @@ -252,6 +259,7 @@ sakatu kontua berresteko esteka."; "Scene.Profile.SegmentedControl.Posts" = "Bidalketak"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Bidalketak eta erantzunak"; "Scene.Profile.SegmentedControl.Replies" = "Erantzunak"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Adostasuna"; "Scene.Register.Error.Item.Email" = "Eposta"; "Scene.Register.Error.Item.Locale" = "Eskualdeko ezarpenak"; @@ -284,6 +292,7 @@ sakatu kontua berresteko esteka."; "Scene.Register.Input.Password.Require" = "Zure pasahitzak izan behar ditu gutxienez:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Erabiltzaile-izen hau hartuta dago."; "Scene.Register.Input.Username.Placeholder" = "erabiltzaile-izena"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "Hitz egin iezaguzu zuri buruz."; "Scene.Report.Content1" = "Salaketan beste bidalketarik gehitu nahi duzu?"; "Scene.Report.Content2" = "Moderatzaileek besterik jakin behar dute salaketa honi buruz?"; @@ -293,6 +302,38 @@ sakatu kontua berresteko esteka."; "Scene.Report.SkipToSend" = "Bidali iruzkinik gabe"; "Scene.Report.Step1" = "1. urratsa 2tik"; "Scene.Report.Step2" = "2. urratsa 2tik"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Unfollow"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; +"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; +"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; +"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; +"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; +"Scene.Report.StepOne.ItsSpam" = "It’s spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; "Scene.Report.TextPlaceholder" = "Idatzi edo itsatsi iruzkin gehigarriak"; "Scene.Report.Title" = "Salatu %@"; "Scene.Report.TitleReport" = "Salatu"; @@ -333,6 +374,7 @@ sakatu kontua berresteko esteka."; "Scene.ServerPicker.EmptyState.FindingServers" = "Erabilgarri dauden zerbitzariak bilatzen..."; "Scene.ServerPicker.EmptyState.NoResults" = "Emaitzarik ez"; "Scene.ServerPicker.Input.Placeholder" = "Bilatu zerbitzari bat edo sortu zurea..."; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "KATEGORIA"; "Scene.ServerPicker.Label.Language" = "HIZKUNTZA"; "Scene.ServerPicker.Label.Users" = "ERABILTZAILEAK"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/eu-ES.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.stringsdict similarity index 90% rename from MastodonSDK/Sources/MastodonLocalization/Resources/eu-ES.lproj/Localizable.stringsdict rename to MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.stringsdict index 871fb10bc..0159a7da9 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/eu-ES.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/eu.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld karaktere + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ bidalketa + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sv_FI.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings similarity index 70% rename from MastodonSDK/Sources/MastodonLocalization/Resources/sv_FI.lproj/Localizable.strings rename to MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings index 135e34990..1fb8fbc46 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sv_FI.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.strings @@ -1,21 +1,21 @@ "Common.Alerts.BlockDomain.BlockEntireDomain" = "Estä verkkotunnus"; -"Common.Alerts.BlockDomain.Title" = "Är du verkligen, verkligen säker på att du vill blockera hela %@? I de flesta fall är några riktade blockeringar eller nedtystade konton tillräckligt och att föredra. Du kommer inte se innehåll från den domänen och dina följare från den domänen kommer att tas bort."; +"Common.Alerts.BlockDomain.Title" = "Are you really, really sure you want to block the entire %@? 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."; "Common.Alerts.CleanCache.Message" = "%@ välimuisti tyhjennetty onnistuneesti."; "Common.Alerts.CleanCache.Title" = "Puhdista välimuisti"; "Common.Alerts.Common.PleaseTryAgain" = "Yritä uudelleen."; "Common.Alerts.Common.PleaseTryAgainLater" = "Yritä uudelleen myöhemmin."; -"Common.Alerts.DeletePost.Message" = "Är du säker på att du vill radera detta inlägg?"; +"Common.Alerts.DeletePost.Message" = "Are you sure you want to delete this post?"; "Common.Alerts.DeletePost.Title" = "Haluatko varmasti poistaa tämän julkaisun?"; -"Common.Alerts.DiscardPostContent.Message" = "Bekräfta för att slänga inläggsutkast."; +"Common.Alerts.DiscardPostContent.Message" = "Confirm to discard composed post content."; "Common.Alerts.DiscardPostContent.Title" = "Hylkää luonnos"; "Common.Alerts.EditProfileFailure.Message" = "Profiilia ei voida muoka. Yritä uudelleen."; "Common.Alerts.EditProfileFailure.Title" = "Virhe profiilin muokkauksessa"; "Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Ei voi liittä yhtä videota enempää."; -"Common.Alerts.PublishPostFailure.AttachmentsMessage.VideoAttachWithPhoto" = "Det går inte att bifoga en video till en status som redan innehåller bilder."; +"Common.Alerts.PublishPostFailure.AttachmentsMessage.VideoAttachWithPhoto" = "Cannot attach a video to a post that already contains images."; "Common.Alerts.PublishPostFailure.Message" = "Julkaisun julkaiseminen epäonnistui. Tarkista internet-yhteytesi."; "Common.Alerts.PublishPostFailure.Title" = "Julkaiseminen epäonnistui"; -"Common.Alerts.SavePhotoFailure.Message" = "Aktivera åtkomst till Bilder för att spara bilden."; +"Common.Alerts.SavePhotoFailure.Message" = "Please enable the photo library access permission to save the photo."; "Common.Alerts.SavePhotoFailure.Title" = "Kuvan tallentaminen epäonnistui"; "Common.Alerts.ServerError.Title" = "Palvelinvirhe"; "Common.Alerts.SignOut.Confirm" = "Kirjaudu ulos"; @@ -23,7 +23,7 @@ Tarkista internet-yhteytesi."; "Common.Alerts.SignOut.Title" = "Kirjaudu ulos"; "Common.Alerts.SignUpFailure.Title" = "Rekisteröinti epäonnistui"; "Common.Alerts.VoteFailure.PollEnded" = "Kysely on päättynyt"; -"Common.Alerts.VoteFailure.Title" = "Röstning misslyckades"; +"Common.Alerts.VoteFailure.Title" = "Vote Failure"; "Common.Controls.Actions.Add" = "Lisää"; "Common.Controls.Actions.Back" = "Takaisin"; "Common.Controls.Actions.BlockDomain" = "Estä %@"; @@ -37,11 +37,11 @@ Tarkista internet-yhteytesi."; "Common.Controls.Actions.Done" = "Valmis"; "Common.Controls.Actions.Edit" = "Muokkaa"; "Common.Controls.Actions.FindPeople" = "Löydä tilejä seurattavaksi"; -"Common.Controls.Actions.ManuallySearch" = "Sök manuellt istället"; +"Common.Controls.Actions.ManuallySearch" = "Manually search instead"; "Common.Controls.Actions.Next" = "Seuraava"; "Common.Controls.Actions.Ok" = "OK"; "Common.Controls.Actions.Open" = "Avaa"; -"Common.Controls.Actions.OpenInBrowser" = "Öppna i webbläsare"; +"Common.Controls.Actions.OpenInBrowser" = "Open in Browser"; "Common.Controls.Actions.OpenInSafari" = "Avaa Safarissa"; "Common.Controls.Actions.Preview" = "Esikatselu"; "Common.Controls.Actions.Previous" = "Edellinen"; @@ -74,7 +74,7 @@ Tarkista internet-yhteytesi."; "Common.Controls.Friendship.Pending" = "Pyydetty"; "Common.Controls.Friendship.Request" = "Pyydä"; "Common.Controls.Friendship.Unblock" = "Poista esto"; -"Common.Controls.Friendship.UnblockUser" = "Avblockera %@"; +"Common.Controls.Friendship.UnblockUser" = "Unblock %@"; "Common.Controls.Friendship.Unmute" = "Poista mykistys"; "Common.Controls.Friendship.UnmuteUser" = "Poista mykistys tililtä %@"; "Common.Controls.Keyboard.Common.ComposeNewPost" = "Koosta uusi julkaisu"; @@ -82,48 +82,48 @@ Tarkista internet-yhteytesi."; "Common.Controls.Keyboard.Common.ShowFavorites" = "Näytä suosikit"; "Common.Controls.Keyboard.Common.SwitchToTab" = "Vaihda %@"; "Common.Controls.Keyboard.SegmentedControl.NextSection" = "Seuraava lohko"; -"Common.Controls.Keyboard.SegmentedControl.PreviousSection" = "Föregående avsnitt"; +"Common.Controls.Keyboard.SegmentedControl.PreviousSection" = "Previous Section"; "Common.Controls.Keyboard.Timeline.NextStatus" = "Seuraava julkaisu"; "Common.Controls.Keyboard.Timeline.OpenAuthorProfile" = "Avaa tekijän profiili"; "Common.Controls.Keyboard.Timeline.OpenRebloggerProfile" = "Avaa edelleen jakajan profiili"; "Common.Controls.Keyboard.Timeline.OpenStatus" = "Avaa julkaisu"; -"Common.Controls.Keyboard.Timeline.PreviewImage" = "Förhandsgranska bild"; +"Common.Controls.Keyboard.Timeline.PreviewImage" = "Preview Image"; "Common.Controls.Keyboard.Timeline.PreviousStatus" = "Edellinen julkaisu"; "Common.Controls.Keyboard.Timeline.ReplyStatus" = "Vastaa julkaisuun"; "Common.Controls.Keyboard.Timeline.ToggleContentWarning" = "Vaihda sisältövaroitus"; -"Common.Controls.Keyboard.Timeline.ToggleFavorite" = "Växla favorit på inlägg"; -"Common.Controls.Keyboard.Timeline.ToggleReblog" = "Växla ompostning på inlägg"; -"Common.Controls.Status.Actions.Favorite" = "Favorit"; -"Common.Controls.Status.Actions.Hide" = "Dölj"; +"Common.Controls.Keyboard.Timeline.ToggleFavorite" = "Toggle Favorite on Post"; +"Common.Controls.Keyboard.Timeline.ToggleReblog" = "Toggle Reblog on Post"; +"Common.Controls.Status.Actions.Favorite" = "Favorite"; +"Common.Controls.Status.Actions.Hide" = "Hide"; "Common.Controls.Status.Actions.Menu" = "Valikko"; "Common.Controls.Status.Actions.Reblog" = "Jaa edelleen"; "Common.Controls.Status.Actions.Reply" = "Vastaa"; -"Common.Controls.Status.Actions.ShowGif" = "Visa GIF"; -"Common.Controls.Status.Actions.ShowImage" = "Visa bild"; -"Common.Controls.Status.Actions.ShowVideoPlayer" = "Visa videospelare"; -"Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Tryck och håll ned för att visa menyn"; -"Common.Controls.Status.Actions.Unfavorite" = "Ta bort favorit"; +"Common.Controls.Status.Actions.ShowGif" = "Show GIF"; +"Common.Controls.Status.Actions.ShowImage" = "Show image"; +"Common.Controls.Status.Actions.ShowVideoPlayer" = "Show video player"; +"Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Tap then hold to show menu"; +"Common.Controls.Status.Actions.Unfavorite" = "Unfavorite"; "Common.Controls.Status.Actions.Unreblog" = "Peru edelleen jako"; "Common.Controls.Status.ContentWarning" = "Sisältövaroitus"; "Common.Controls.Status.MediaContentWarning" = "Napauta mistä tahansa paljastaaksesi"; "Common.Controls.Status.Poll.Closed" = "Suljettu"; -"Common.Controls.Status.Poll.Vote" = "Rösta"; -"Common.Controls.Status.SensitiveContent" = "Känsligt innehåll"; +"Common.Controls.Status.Poll.Vote" = "Vote"; +"Common.Controls.Status.SensitiveContent" = "Sensitive Content"; "Common.Controls.Status.ShowPost" = "Näytä julkaisu"; "Common.Controls.Status.ShowUserProfile" = "Näytä tili"; "Common.Controls.Status.Tag.Email" = "Sähköposti"; "Common.Controls.Status.Tag.Emoji" = "Emoji"; "Common.Controls.Status.Tag.Hashtag" = "Hashtagi"; "Common.Controls.Status.Tag.Link" = "Linkki"; -"Common.Controls.Status.Tag.Mention" = "Nämn"; +"Common.Controls.Status.Tag.Mention" = "Mention"; "Common.Controls.Status.Tag.Url" = "URL"; -"Common.Controls.Status.TapToReveal" = "Tryck för att visa"; +"Common.Controls.Status.TapToReveal" = "Tap to reveal"; "Common.Controls.Status.UserReblogged" = "%@ jakoi edelleen"; "Common.Controls.Status.UserRepliedTo" = "Vastasi %@:lle"; -"Common.Controls.Status.Visibility.Direct" = "Endast nämnda användare kan se detta inlägg."; -"Common.Controls.Status.Visibility.Private" = "Endast deras följare kan se detta inlägg."; -"Common.Controls.Status.Visibility.PrivateFromMe" = "Bara mina följare kan se det här inlägget."; -"Common.Controls.Status.Visibility.Unlisted" = "Alla kan se detta inlägg men det visas inte i den offentliga tidslinjen."; +"Common.Controls.Status.Visibility.Direct" = "Only mentioned user can see this post."; +"Common.Controls.Status.Visibility.Private" = "Only their followers can see this post."; +"Common.Controls.Status.Visibility.PrivateFromMe" = "Only my followers can see this post."; +"Common.Controls.Status.Visibility.Unlisted" = "Everyone can see this post but not display in the public timeline."; "Common.Controls.Tabs.Home" = "Koti"; "Common.Controls.Tabs.Notification" = "Ilmoitus"; "Common.Controls.Tabs.Profile" = "Profiili"; @@ -156,13 +156,13 @@ Profiilisi näyttää tältä hänelle."; "Scene.Compose.Accessibility.EnableContentWarning" = "Ota sisältövaroitus käyttöön"; "Scene.Compose.Accessibility.PostVisibilityMenu" = "Julkaisun näkyvyysvalikko"; "Scene.Compose.Accessibility.RemovePoll" = "Poista kysely"; -"Scene.Compose.Attachment.AttachmentBroken" = "Denna %@ är trasig och kan inte -laddas upp till Mastodon."; +"Scene.Compose.Attachment.AttachmentBroken" = "This %@ is broken and can’t be +uploaded to Mastodon."; "Scene.Compose.Attachment.DescriptionPhoto" = "Kuvaile kuva näkövammaisille..."; "Scene.Compose.Attachment.DescriptionVideo" = "Kuvaile video näkövammaisille..."; "Scene.Compose.Attachment.Photo" = "kuva"; "Scene.Compose.Attachment.Video" = "video"; -"Scene.Compose.AutoComplete.SpaceToAdd" = "Mellanslag att lägga till"; +"Scene.Compose.AutoComplete.SpaceToAdd" = "Space to add"; "Scene.Compose.ComposeAction" = "Julkaise"; "Scene.Compose.ContentInputPlaceholder" = "Kirjoita tai liitä, siitä mitä ajattelet"; "Scene.Compose.ContentWarning.Placeholder" = "Kirjoita tarkka varoitus tähän..."; @@ -191,7 +191,7 @@ laddas upp till Mastodon."; "Scene.Compose.Visibility.Public" = "Julkinen"; "Scene.Compose.Visibility.Unlisted" = "Listaamaton"; "Scene.ConfirmEmail.Button.OpenEmailApp" = "Avaa sähköpostisovellus"; -"Scene.ConfirmEmail.Button.Resend" = "Skicka igen"; +"Scene.ConfirmEmail.Button.Resend" = "Resend"; "Scene.ConfirmEmail.DontReceiveEmail.Description" = "Tarkista, että sähköpostiosoitteesi on oikea, sekä roskapostikansiosi, jos et vielä ole."; "Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Lähetä sähköposti uudelleen"; "Scene.ConfirmEmail.DontReceiveEmail.Title" = "Tarkista sähköpostisi"; @@ -200,16 +200,24 @@ laddas upp till Mastodon."; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Avaa sähköpostisovellus"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Tarkasta postilaatikkosi."; "Scene.ConfirmEmail.Subtitle" = "Lähetimme juuri sähköpostin osoitteeseen %@, napauta siinä olevaa linkkiä vahvistaaksesi tilisi."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "Viimeinen asia."; -"Scene.Discovery.Intro" = "Detta är de inlägg som engagerar i ditt hörn av Mastodon."; +"Scene.Discovery.Intro" = "These are the posts gaining traction in your corner of Mastodon."; "Scene.Discovery.Tabs.Community" = "Community"; -"Scene.Discovery.Tabs.ForYou" = "För dig"; -"Scene.Discovery.Tabs.Hashtags" = "Hashtaggar"; -"Scene.Discovery.Tabs.News" = "Nyheter"; -"Scene.Discovery.Tabs.Posts" = "Inlägg"; +"Scene.Discovery.Tabs.ForYou" = "For You"; +"Scene.Discovery.Tabs.Hashtags" = "Hashtags"; +"Scene.Discovery.Tabs.News" = "News"; +"Scene.Discovery.Tabs.Posts" = "Posts"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Omat suosikit"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Seuraajia muilta palvelimilta ei näytetä."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Seurauksia muilta palvelimilta ei näytetä."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Uusia julkaisuja"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Yhteydetön"; "Scene.HomeTimeline.NavigationBarState.Published" = "Julkaistu!"; @@ -217,43 +225,44 @@ laddas upp till Mastodon."; "Scene.HomeTimeline.Title" = "Koti"; "Scene.Notification.Keyobard.ShowEverything" = "Näytä kaikki"; "Scene.Notification.Keyobard.ShowMentions" = "Näytä maininnat"; -"Scene.Notification.NotificationDescription.FavoritedYourPost" = "favoriserade ditt inlägg"; -"Scene.Notification.NotificationDescription.FollowedYou" = "följde dig"; -"Scene.Notification.NotificationDescription.MentionedYou" = "nämnde dig"; -"Scene.Notification.NotificationDescription.PollHasEnded" = "omröstningen har avslutats"; -"Scene.Notification.NotificationDescription.RebloggedYourPost" = "ompostade ditt inlägg"; -"Scene.Notification.NotificationDescription.RequestToFollowYou" = "begär att följa dig"; +"Scene.Notification.NotificationDescription.FavoritedYourPost" = "favorited your post"; +"Scene.Notification.NotificationDescription.FollowedYou" = "followed you"; +"Scene.Notification.NotificationDescription.MentionedYou" = "mentioned you"; +"Scene.Notification.NotificationDescription.PollHasEnded" = "poll has ended"; +"Scene.Notification.NotificationDescription.RebloggedYourPost" = "reblogged your post"; +"Scene.Notification.NotificationDescription.RequestToFollowYou" = "request to follow you"; "Scene.Notification.Title.Everything" = "Kaikki"; "Scene.Notification.Title.Mentions" = "Maininnat"; "Scene.Preview.Keyboard.ClosePreview" = "Sulje esikatselu"; "Scene.Preview.Keyboard.ShowNext" = "Näytä seuraava"; "Scene.Preview.Keyboard.ShowPrevious" = "Näytä edellinen"; -"Scene.Profile.Accessibility.DoubleTapToOpenTheList" = "Dubbeltryck för att öppna listan"; -"Scene.Profile.Accessibility.EditAvatarImage" = "Redigera profilbild"; -"Scene.Profile.Accessibility.ShowAvatarImage" = "Visa profilbild"; -"Scene.Profile.Accessibility.ShowBannerImage" = "Visa banner"; +"Scene.Profile.Accessibility.DoubleTapToOpenTheList" = "Double tap to open the list"; +"Scene.Profile.Accessibility.EditAvatarImage" = "Edit avatar image"; +"Scene.Profile.Accessibility.ShowAvatarImage" = "Show avatar image"; +"Scene.Profile.Accessibility.ShowBannerImage" = "Show banner image"; "Scene.Profile.Dashboard.Followers" = "seuraajat"; "Scene.Profile.Dashboard.Following" = "seurataan"; "Scene.Profile.Dashboard.Posts" = "julkaisut"; "Scene.Profile.Fields.AddRow" = "Lisää rivi"; "Scene.Profile.Fields.Placeholder.Content" = "Sisältö"; "Scene.Profile.Fields.Placeholder.Label" = "Nimi"; -"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Bekräfta för att blockera %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Blockera konto"; -"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Bekräfta för att tysta %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Tysta konto"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Bekräfta för att avblockera %@"; -"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Avblockera konto"; +"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirm to block %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Block Account"; +"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirm to mute %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Mute Account"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Confirm to unblock %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Unblock Account"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Vahvista, että haluat poistaa mykistyksen tililtä %@"; "Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Title" = "Poista tilin mykistys"; -"Scene.Profile.SegmentedControl.About" = "Om"; +"Scene.Profile.SegmentedControl.About" = "About"; "Scene.Profile.SegmentedControl.Media" = "Media"; "Scene.Profile.SegmentedControl.Posts" = "Julkaisut"; -"Scene.Profile.SegmentedControl.PostsAndReplies" = "Inlägg och svar"; +"Scene.Profile.SegmentedControl.PostsAndReplies" = "Posts and Replies"; "Scene.Profile.SegmentedControl.Replies" = "Vastaukset"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Hyväksy"; "Scene.Register.Error.Item.Email" = "Sähköposti"; -"Scene.Register.Error.Item.Locale" = "Språk"; +"Scene.Register.Error.Item.Locale" = "Locale"; "Scene.Register.Error.Item.Password" = "Salasana"; "Scene.Register.Error.Item.Reason" = "Syy"; "Scene.Register.Error.Item.Username" = "Käyttäjänimi"; @@ -262,7 +271,7 @@ laddas upp till Mastodon."; "Scene.Register.Error.Reason.Blocked" = "%@ sisältää estetyn sähköpostipalveluntarjoajan"; "Scene.Register.Error.Reason.Inclusion" = "%@ ei ole tuettu arvo"; "Scene.Register.Error.Reason.Invalid" = "%@ on virheellinen"; -"Scene.Register.Error.Reason.Reserved" = "%@ är ett reserverat nyckelord"; +"Scene.Register.Error.Reason.Reserved" = "%@ is a reserved keyword"; "Scene.Register.Error.Reason.Taken" = "%@ on jo käytössä"; "Scene.Register.Error.Reason.TooLong" = "%@ on liian pitkä"; "Scene.Register.Error.Reason.TooShort" = "%@ on liian lyhyt"; @@ -275,26 +284,59 @@ laddas upp till Mastodon."; "Scene.Register.Input.DisplayName.Placeholder" = "näyttönimi"; "Scene.Register.Input.Email.Placeholder" = "sähköposti"; "Scene.Register.Input.Invite.RegistrationUserInviteRequest" = "Miksi haluat liittyä?"; -"Scene.Register.Input.Password.Accessibility.Checked" = "markerad"; -"Scene.Register.Input.Password.Accessibility.Unchecked" = "avmarkerad"; -"Scene.Register.Input.Password.CharacterLimit" = "8 tecken"; +"Scene.Register.Input.Password.Accessibility.Checked" = "checked"; +"Scene.Register.Input.Password.Accessibility.Unchecked" = "unchecked"; +"Scene.Register.Input.Password.CharacterLimit" = "8 characters"; "Scene.Register.Input.Password.Hint" = "Salasanassasi on oltava vähintään kahdeksan merkkiä"; "Scene.Register.Input.Password.Placeholder" = "salasana"; -"Scene.Register.Input.Password.Require" = "Ditt lösenord behöver minst:"; +"Scene.Register.Input.Password.Require" = "Your password needs at least:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Tämä käyttäjänimi on varattu."; "Scene.Register.Input.Username.Placeholder" = "käyttäjänimi"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "Kerro meille sinusta."; "Scene.Report.Content1" = "Onko julkaisuja, joita haluaisit lisätä ilmiantoon?"; "Scene.Report.Content2" = "Onko valvojien syytä tietää tästä ilmiannosta?"; -"Scene.Report.ReportSentTitle" = "Tack för din rapport, vi ska titta på det."; -"Scene.Report.Reported" = "RAPPORTERAD"; +"Scene.Report.ReportSentTitle" = "Thanks for reporting, we’ll look into this."; +"Scene.Report.Reported" = "REPORTED"; "Scene.Report.Send" = "Lähetä ilmianto"; "Scene.Report.SkipToSend" = "Lähetä ilman kommentteja"; "Scene.Report.Step1" = "Vaihe 1/2"; "Scene.Report.Step2" = "Vaihe 2/2"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Unfollow"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; +"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; +"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; +"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; +"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; +"Scene.Report.StepOne.ItsSpam" = "It’s spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; "Scene.Report.TextPlaceholder" = "Kirjoita tai liitä lisäkommentteja"; "Scene.Report.Title" = "Ilmianna %@"; -"Scene.Report.TitleReport" = "Rapportera"; +"Scene.Report.TitleReport" = "Report"; "Scene.Search.Recommend.Accounts.Description" = "Haluta ehkä seurata näitä tilejä"; "Scene.Search.Recommend.Accounts.Follow" = "Seuraa"; "Scene.Search.Recommend.Accounts.Title" = "Saatat pitää näistä tileistä"; @@ -332,11 +374,12 @@ laddas upp till Mastodon."; "Scene.ServerPicker.EmptyState.FindingServers" = "Etsistään saatavilla olevia palvelimia..."; "Scene.ServerPicker.EmptyState.NoResults" = "Ei hakutuloksia"; "Scene.ServerPicker.Input.Placeholder" = "Etsi palvelin tai liity omaan..."; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "KATEGORIA"; "Scene.ServerPicker.Label.Language" = "KIELI"; "Scene.ServerPicker.Label.Users" = "TILIÄ"; -"Scene.ServerPicker.Subtitle" = "Välj en gemenskap baserad på dina intressen, region eller ett allmänt syfte."; -"Scene.ServerPicker.SubtitleExtend" = "Välj en gemenskap baserad på dina intressen, region eller ett allmänt syfte. Varje gemenskap drivs av en helt oberoende organisation eller individ."; +"Scene.ServerPicker.Subtitle" = "Pick a server based on your interests, region, or a general purpose one."; +"Scene.ServerPicker.SubtitleExtend" = "Pick a server based on your interests, region, or a general purpose one. Each server is operated by an entirely independent organization or individual."; "Scene.ServerPicker.Title" = "Valitse palvelin, mikä tahansa palvelin."; "Scene.ServerRules.Button.Confirm" = "Hyväksyn"; @@ -355,13 +398,13 @@ mikä tahansa palvelin."; "Scene.Settings.Section.BoringZone.Privacy" = "Tietosuojakäytäntö"; "Scene.Settings.Section.BoringZone.Terms" = "Palveluehdot"; "Scene.Settings.Section.BoringZone.Title" = "Tylsä alue"; -"Scene.Settings.Section.LookAndFeel.Light" = "Ljust"; -"Scene.Settings.Section.LookAndFeel.ReallyDark" = "Verkligen mörk"; -"Scene.Settings.Section.LookAndFeel.SortaDark" = "Ganska mörk"; -"Scene.Settings.Section.LookAndFeel.Title" = "Utseende och känsla"; -"Scene.Settings.Section.LookAndFeel.UseSystem" = "Följ systeminställningarna"; +"Scene.Settings.Section.LookAndFeel.Light" = "Light"; +"Scene.Settings.Section.LookAndFeel.ReallyDark" = "Really Dark"; +"Scene.Settings.Section.LookAndFeel.SortaDark" = "Sorta Dark"; +"Scene.Settings.Section.LookAndFeel.Title" = "Look and Feel"; +"Scene.Settings.Section.LookAndFeel.UseSystem" = "Use System"; "Scene.Settings.Section.Notifications.Boosts" = "Omien julkaisujen edelleen jaot"; -"Scene.Settings.Section.Notifications.Favorites" = "Favoriserar mitt inlägg"; +"Scene.Settings.Section.Notifications.Favorites" = "Favorites my post"; "Scene.Settings.Section.Notifications.Follows" = "Seuraa minua"; "Scene.Settings.Section.Notifications.Mentions" = "Mainitsee minut"; "Scene.Settings.Section.Notifications.Title" = "Ilmoitukset"; @@ -372,7 +415,7 @@ mikä tahansa palvelin."; "Scene.Settings.Section.Notifications.Trigger.Title" = "Ilmoita minulle, kun"; "Scene.Settings.Section.Preference.DisableAvatarAnimation" = "Poista käytöstä animoidut avatarit"; "Scene.Settings.Section.Preference.DisableEmojiAnimation" = "Poista käytöstä animoidut emojit"; -"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "Öppna länkar i Mastodon"; +"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "Open links in Mastodon"; "Scene.Settings.Section.Preference.Title" = "Lisäasetukset"; "Scene.Settings.Section.Preference.TrueBlackDarkMode" = "Todellinen mustan tumma tila"; "Scene.Settings.Section.Preference.UsingDefaultBrowser" = "Käytä oletusselainta linkkien avaamiseen"; @@ -384,8 +427,8 @@ mikä tahansa palvelin."; "Scene.SuggestionAccount.Title" = "Löydä tilejä seurattavaksi"; "Scene.Thread.BackTitle" = "Julkaisu"; "Scene.Thread.Title" = "Julkaisu tililtä %@"; -"Scene.Welcome.GetStarted" = "Kom igång"; -"Scene.Welcome.LogIn" = "Logga in"; +"Scene.Welcome.GetStarted" = "Get Started"; +"Scene.Welcome.LogIn" = "Log In"; "Scene.Welcome.Slogan" = "Sosiaalinen verkostoituminen takaisin käsissäsi."; "Scene.Wizard.AccessibilityHint" = "Hylkää tämä ohjattu toiminto kaksoisnapauttamalla"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sv_FI.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.stringsdict similarity index 89% rename from MastodonSDK/Sources/MastodonLocalization/Resources/sv_FI.lproj/Localizable.stringsdict rename to MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.stringsdict index 091c8555e..8048edf2d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/sv_FI.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fi.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld merkkiä + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ julkaisut + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey @@ -125,9 +168,9 @@ NSStringFormatValueTypeKey ld one - 1 svar + 1 reply other - %ld svar + %ld replies plural.count.vote diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings index 880612b29..1706ad363 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.strings @@ -101,14 +101,14 @@ Veuillez vérifier votre accès à Internet."; "Common.Controls.Status.Actions.ShowGif" = "Afficher le GIF"; "Common.Controls.Status.Actions.ShowImage" = "Afficher l’image"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Afficher le lecteur vidéo"; -"Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Tap then hold to show menu"; +"Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Appuyez et maintenez pour afficher le menu"; "Common.Controls.Status.Actions.Unfavorite" = "Retirer des favoris"; "Common.Controls.Status.Actions.Unreblog" = "Annuler le reblog"; "Common.Controls.Status.ContentWarning" = "Avertissement de contenu"; "Common.Controls.Status.MediaContentWarning" = "Tapotez n’importe où pour révéler la publication"; "Common.Controls.Status.Poll.Closed" = "Fermé"; "Common.Controls.Status.Poll.Vote" = "Voter"; -"Common.Controls.Status.SensitiveContent" = "Sensitive Content"; +"Common.Controls.Status.SensitiveContent" = "Contenu sensible"; "Common.Controls.Status.ShowPost" = "Montrer la publication"; "Common.Controls.Status.ShowUserProfile" = "Montrer le profil de l’utilisateur·rice"; "Common.Controls.Status.Tag.Email" = "Courriel"; @@ -199,18 +199,25 @@ téléversé sur Mastodon."; "Scene.ConfirmEmail.OpenEmailApp.Mail" = "Courriel"; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Ouvrir le client de messagerie"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Vérifier votre boîte aux lettres."; -"Scene.ConfirmEmail.Subtitle" = "Nous venons d’envoyer un courriel à %@, -tapotez le lien pour confirmer votre compte."; +"Scene.ConfirmEmail.Subtitle" = "Appuyez sur le lien que nous vous avons envoyé par courriel pour vérifier votre compte."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Appuyez sur le lien que nous vous avons envoyé par courriel pour vérifier votre compte"; "Scene.ConfirmEmail.Title" = "Une dernière chose."; -"Scene.Discovery.Intro" = "These are the posts gaining traction in your corner of Mastodon."; -"Scene.Discovery.Tabs.Community" = "Community"; +"Scene.Discovery.Intro" = "Ce sont les messages qui gagnent en popularité sur votre serveur Mastodon."; +"Scene.Discovery.Tabs.Community" = "Communauté"; "Scene.Discovery.Tabs.ForYou" = "Pour vous"; "Scene.Discovery.Tabs.Hashtags" = "Hashtags"; "Scene.Discovery.Tabs.News" = "Actualité"; "Scene.Discovery.Tabs.Posts" = "Messages"; +"Scene.Familiarfollowers.FollowedByNames" = "Suivi·e par %@"; +"Scene.Familiarfollowers.Title" = "Abonné·e·s que vous connaissez"; "Scene.Favorite.Title" = "Vos favoris"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Les abonné·e·s issus des autres serveurs ne sont pas affiché·e·s."; +"Scene.Follower.Title" = "abonné·e"; "Scene.Following.Footer" = "Les abonnés issus des autres serveurs ne sont pas affichés."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Bouton logo"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Voir les nouvelles publications"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Hors ligne"; "Scene.HomeTimeline.NavigationBarState.Published" = "Publié!"; @@ -252,6 +259,7 @@ tapotez le lien pour confirmer votre compte."; "Scene.Profile.SegmentedControl.Posts" = "Publications"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Messages et réponses"; "Scene.Profile.SegmentedControl.Replies" = "Réponses"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Accord"; "Scene.Register.Error.Item.Email" = "Courriel"; "Scene.Register.Error.Item.Locale" = "Lieu"; @@ -284,6 +292,7 @@ tapotez le lien pour confirmer votre compte."; "Scene.Register.Input.Password.Require" = "Votre mot de passe doit être composé d’au moins :"; "Scene.Register.Input.Username.DuplicatePrompt" = "Ce nom d'utilisateur est déjà pris."; "Scene.Register.Input.Username.Placeholder" = "nom d'utilisateur"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Mettons les choses en place pour %@"; "Scene.Register.Title" = "Parlez-nous de vous."; "Scene.Report.Content1" = "Y a-t-il d’autres messages que vous aimeriez ajouter au signalement?"; "Scene.Report.Content2" = "Y a-t-il quelque chose que les modérateurs devraient savoir sur ce rapport ?"; @@ -293,6 +302,38 @@ tapotez le lien pour confirmer votre compte."; "Scene.Report.SkipToSend" = "Envoyer sans commentaire"; "Scene.Report.Step1" = "Étape 1 de 2"; "Scene.Report.Step2" = "Étape 2 de 2"; +"Scene.Report.StepFinal.BlockUser" = "Bloquer %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Vous ne voulez pas voir cela ?"; +"Scene.Report.StepFinal.MuteUser" = "Masquer %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Se désabonner"; +"Scene.Report.StepFinal.UnfollowUser" = "Ne plus suivre %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Quand vous voyez quelque chose que vous n’aimez pas sur Mastodon, vous pouvez retirer la personne de votre expérience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "Vous ne verrez plus leurs messages ou leurs partages dans votre flux personnel. Iels ne sauront pas qu’iels ont été mis en sourdine."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Y a-t-il autre chose que nous devrions savoir ?"; +"Scene.Report.StepFour.Step4Of4" = "Étape 4 sur 4"; +"Scene.Report.StepOne.IDontLikeIt" = "Je n’aime pas"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "C’est quelque chose que vous ne souhaitez pas voir"; +"Scene.Report.StepOne.ItViolatesServerRules" = "Enfreint les règles du serveur"; +"Scene.Report.StepOne.ItsSomethingElse" = "Pour une autre raison"; +"Scene.Report.StepOne.ItsSpam" = "C’est du spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Liens malveillants, engagement mensonger ou réponses répétitives"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Étape 1 sur 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "Le problème ne correspond à aucune des catégories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Qu’est-ce qui ne va pas avec ce compte ?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Qu’est-ce qui ne va pas avec ce message ?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Qu’est-ce qui ne va pas avec %@ ?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Vous savez qu’il enfreint des règles spécifiques"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Existe-t-il des messages pour étayer ce rapport ?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Sélectionnez toutes les réponses qui s’appliquent"; +"Scene.Report.StepThree.Step3Of4" = "Étape 3 sur 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "Ça ne me plaît tout simplement pas"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Sélectionnez toutes les réponses appropriées"; +"Scene.Report.StepTwo.Step2Of4" = "Étape 2 sur 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Quelles règles sont enfreintes ?"; "Scene.Report.TextPlaceholder" = "Tapez ou collez des informations supplémentaires"; "Scene.Report.Title" = "Signaler %@"; "Scene.Report.TitleReport" = "Signalement"; @@ -333,6 +374,7 @@ tapotez le lien pour confirmer votre compte."; "Scene.ServerPicker.EmptyState.FindingServers" = "Recherche des serveurs disponibles..."; "Scene.ServerPicker.EmptyState.NoResults" = "Aucun résultat"; "Scene.ServerPicker.Input.Placeholder" = "Trouvez un serveur ou rejoignez le vôtre..."; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "CATÉGORIE"; "Scene.ServerPicker.Label.Language" = "LANGUE"; "Scene.ServerPicker.Label.Users" = "UTILISATEUR·RICE·S"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.stringsdict index 5c2b14978..d9d860a47 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/fr.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld caractères + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Suivi·e par %1$@ et un·e autre en commun + other + Suivi·e par %1$@ et %ld autres en commun + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ publications + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 média + other + %ld médias + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gd-GB.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings similarity index 88% rename from MastodonSDK/Sources/MastodonLocalization/Resources/gd-GB.lproj/Localizable.strings rename to MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings index 586258e5a..9638d561a 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gd-GB.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.strings @@ -201,16 +201,24 @@ a luchdadh suas gu Mastodon."; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Thoir sùil air a’ bhogsa a-steach agad."; "Scene.ConfirmEmail.Subtitle" = "Tha sinn air post-d a chur gu %@, thoir gnogag air a’ chunntas a dhearbhadh a’ chunntais agad."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "Aon rud eile."; "Scene.Discovery.Intro" = "Seo na postaichean fèillmhor ’nad cheàrnaidh de Mhastodon."; -"Scene.Discovery.Tabs.Community" = "Community"; +"Scene.Discovery.Tabs.Community" = "Coimhearsnachd"; "Scene.Discovery.Tabs.ForYou" = "Dhut-sa"; "Scene.Discovery.Tabs.Hashtags" = "Tagaichean hais"; "Scene.Discovery.Tabs.News" = "Naidheachdan"; "Scene.Discovery.Tabs.Posts" = "Postaichean"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Na h-annsachdan agad"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Cha dèid luchd-leantainn o fhrithealaichean eile a shealltainn."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Cha dèid cò air a leanas tu air frithealaichean eile a shealltainn."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Seall na postaichean ùra"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Far loidhne"; "Scene.HomeTimeline.NavigationBarState.Published" = "Chaidh fhoillseachadh!"; @@ -218,7 +226,7 @@ thoir gnogag air a’ chunntas a dhearbhadh a’ chunntais agad."; "Scene.HomeTimeline.Title" = "Dachaigh"; "Scene.Notification.Keyobard.ShowEverything" = "Seall a h-uile càil"; "Scene.Notification.Keyobard.ShowMentions" = "Seall na h-iomraidhean"; -"Scene.Notification.NotificationDescription.FavoritedYourPost" = "– ’s iad air am post agad a chur ris na h-annsachdan aca"; +"Scene.Notification.NotificationDescription.FavoritedYourPost" = "– is annsa leotha am post agad"; "Scene.Notification.NotificationDescription.FollowedYou" = "– ’s iad ’gad leantainn a-nis"; "Scene.Notification.NotificationDescription.MentionedYou" = "– ’s iad air iomradh a thoirt ort"; "Scene.Notification.NotificationDescription.PollHasEnded" = "thàinig cunntas-bheachd gu crìoch"; @@ -252,6 +260,7 @@ thoir gnogag air a’ chunntas a dhearbhadh a’ chunntais agad."; "Scene.Profile.SegmentedControl.Posts" = "Postaichean"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Postaichean ’s freagairtean"; "Scene.Profile.SegmentedControl.Replies" = "Freagairtean"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Aonta"; "Scene.Register.Error.Item.Email" = "Post-d"; "Scene.Register.Error.Item.Locale" = "Sgeama ionadail"; @@ -284,6 +293,7 @@ thoir gnogag air a’ chunntas a dhearbhadh a’ chunntais agad."; "Scene.Register.Input.Password.Require" = "Feumaidh am facal-faire agad co-dhiù:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Tha an t-ainm-cleachdaiche seo aig cuideigin eile."; "Scene.Register.Input.Username.Placeholder" = "ainm-cleachdaiche"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "Innis dhuinn mu do dhèidhinn."; "Scene.Report.Content1" = "A bheil post sam bith eile ann a bu mhiann leat cur ris a’ ghearan?"; "Scene.Report.Content2" = "A bheil rud sam bith ann a bu mhiann leat innse dha na maoir mun ghearan seo?"; @@ -293,6 +303,38 @@ thoir gnogag air a’ chunntas a dhearbhadh a’ chunntais agad."; "Scene.Report.SkipToSend" = "Cuir gun bheachd ris"; "Scene.Report.Step1" = "Ceum 1 à 2"; "Scene.Report.Step2" = "Ceum 2 à 2"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Unfollow"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; +"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; +"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; +"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; +"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; +"Scene.Report.StepOne.ItsSpam" = "It’s spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; "Scene.Report.TextPlaceholder" = "Sgrìobh no cuir ann beachdan a bharrachd"; "Scene.Report.Title" = "Dèan gearan mu %@"; "Scene.Report.TitleReport" = "Dèan gearan"; @@ -333,6 +375,7 @@ thoir gnogag air a’ chunntas a dhearbhadh a’ chunntais agad."; "Scene.ServerPicker.EmptyState.FindingServers" = "A’ lorg nam frithealaichean ri am faighinn…"; "Scene.ServerPicker.EmptyState.NoResults" = "Gun toradh"; "Scene.ServerPicker.Input.Placeholder" = "Lorg frithealaiche no gabh pàirt san fhear agad fhèin…"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "ROINN-SEÒRSA"; "Scene.ServerPicker.Label.Language" = "CÀNAN"; "Scene.ServerPicker.Label.Users" = "CLEACHDAICHEAN"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gd-GB.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.stringsdict similarity index 90% rename from MastodonSDK/Sources/MastodonLocalization/Resources/gd-GB.lproj/Localizable.stringsdict rename to MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.stringsdict index b149323eb..f041677fa 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gd-GB.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gd.lproj/Localizable.stringsdict @@ -62,6 +62,41 @@ %ld caractar + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + two + + few + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + two + Followed by %1$@, and %ld mutuals + few + Followed by %1$@, and %ld mutuals + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -82,6 +117,26 @@ post + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + two + %ld media + few + %ld media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings index a0a33a58f..d5ddb239d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.strings @@ -129,26 +129,26 @@ Comproba a conexión a internet."; "Common.Controls.Tabs.Profile" = "Perfil"; "Common.Controls.Tabs.Search" = "Busca"; "Common.Controls.Timeline.Filtered" = "Filtrado"; -"Common.Controls.Timeline.Header.BlockedWarning" = "You can’t view this user’s profile -until they unblock you."; +"Common.Controls.Timeline.Header.BlockedWarning" = "Non podes ver o perfil desta usuaria +ata que te desbloquee."; "Common.Controls.Timeline.Header.BlockingWarning" = "Non podes ver o perfil da usuaria ata que a desbloquees. Así ven outras o teu perfil."; "Common.Controls.Timeline.Header.NoStatusFound" = "Non se atopa a publicación"; -"Common.Controls.Timeline.Header.SuspendedWarning" = "This user has been suspended."; -"Common.Controls.Timeline.Header.UserBlockedWarning" = "You can’t view %@’s profile -until they unblock you."; -"Common.Controls.Timeline.Header.UserBlockingWarning" = "You can’t view %@’s profile -until you unblock them. -Your profile looks like this to them."; -"Common.Controls.Timeline.Header.UserSuspendedWarning" = "%@’s account has been suspended."; +"Common.Controls.Timeline.Header.SuspendedWarning" = "Esta usuaria foi suspendida."; +"Common.Controls.Timeline.Header.UserBlockedWarning" = "Non podes ver o perfil de %@ +ata que te desbloquee."; +"Common.Controls.Timeline.Header.UserBlockingWarning" = "Non podes ver o perfil de %@ +ata que o desbloquees. +Así se ve o teu perfil."; +"Common.Controls.Timeline.Header.UserSuspendedWarning" = "A conta de %@ foi suspendida."; "Common.Controls.Timeline.Loader.LoadMissingPosts" = "Cargar publicacións que faltan"; "Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Cargando as publicacións que faltan..."; "Common.Controls.Timeline.Loader.ShowMoreReplies" = "Mostrar máis respostas"; "Common.Controls.Timeline.Timestamp.Now" = "Agora"; -"Scene.AccountList.AddAccount" = "Add Account"; -"Scene.AccountList.DismissAccountSwitcher" = "Dismiss Account Switcher"; -"Scene.AccountList.TabBarHint" = "Current selected profile: %@. Double tap then hold to show account switcher"; +"Scene.AccountList.AddAccount" = "Engadir conta"; +"Scene.AccountList.DismissAccountSwitcher" = "Desbotar intercambiador de contas"; +"Scene.AccountList.TabBarHint" = "Perfil seleccionado: %@. Dobre toque e manter para mostrar o intercambiador de contas"; "Scene.Compose.Accessibility.AppendAttachment" = "Engadir anexo"; "Scene.Compose.Accessibility.AppendPoll" = "Engadir enquisa"; "Scene.Compose.Accessibility.CustomEmojiPicker" = "Selector emoji personalizado"; @@ -156,15 +156,15 @@ Your profile looks like this to them."; "Scene.Compose.Accessibility.EnableContentWarning" = "Marcar con Aviso sobre o contido"; "Scene.Compose.Accessibility.PostVisibilityMenu" = "Visibilidade da publicación"; "Scene.Compose.Accessibility.RemovePoll" = "Eliminar enquisa"; -"Scene.Compose.Attachment.AttachmentBroken" = "This %@ is broken and can’t be -uploaded to Mastodon."; -"Scene.Compose.Attachment.DescriptionPhoto" = "Describe the photo for the visually-impaired..."; -"Scene.Compose.Attachment.DescriptionVideo" = "Describe the video for the visually-impaired..."; -"Scene.Compose.Attachment.Photo" = "photo"; -"Scene.Compose.Attachment.Video" = "video"; +"Scene.Compose.Attachment.AttachmentBroken" = "Este %@ está estragado e non pode +ser subido a Mastodon."; +"Scene.Compose.Attachment.DescriptionPhoto" = "Describe a foto para persoas con problemas visuais..."; +"Scene.Compose.Attachment.DescriptionVideo" = "Describe o vídeo para persoas con problemas visuais..."; +"Scene.Compose.Attachment.Photo" = "foto"; +"Scene.Compose.Attachment.Video" = "vídeo"; "Scene.Compose.AutoComplete.SpaceToAdd" = "Barra de espazo engade"; -"Scene.Compose.ComposeAction" = "Publish"; -"Scene.Compose.ContentInputPlaceholder" = "Type or paste what’s on your mind"; +"Scene.Compose.ComposeAction" = "Publicar"; +"Scene.Compose.ContentInputPlaceholder" = "Escribe o que che apeteza"; "Scene.Compose.ContentWarning.Placeholder" = "Escribe o teu aviso aquí..."; "Scene.Compose.Keyboard.AppendAttachmentEntry" = "Engadir anexo - %@"; "Scene.Compose.Keyboard.DiscardPost" = "Descartar publicación"; @@ -172,59 +172,67 @@ uploaded to Mastodon."; "Scene.Compose.Keyboard.SelectVisibilityEntry" = "Elexir visibilidade - %@"; "Scene.Compose.Keyboard.ToggleContentWarning" = "Marcar con Aviso sobre o contido"; "Scene.Compose.Keyboard.TogglePoll" = "Activar enquisa"; -"Scene.Compose.MediaSelection.Browse" = "Browse"; -"Scene.Compose.MediaSelection.Camera" = "Take Photo"; -"Scene.Compose.MediaSelection.PhotoLibrary" = "Photo Library"; -"Scene.Compose.Poll.DurationTime" = "Duration: %@"; +"Scene.Compose.MediaSelection.Browse" = "Explorar"; +"Scene.Compose.MediaSelection.Camera" = "Facer foto"; +"Scene.Compose.MediaSelection.PhotoLibrary" = "Biblioteca de fotos"; +"Scene.Compose.Poll.DurationTime" = "Duración: %@"; "Scene.Compose.Poll.OneDay" = "1 Día"; -"Scene.Compose.Poll.OneHour" = "1 Hour"; +"Scene.Compose.Poll.OneHour" = "1 Hora"; "Scene.Compose.Poll.OptionNumber" = "Opción %ld"; "Scene.Compose.Poll.SevenDays" = "7 Días"; -"Scene.Compose.Poll.SixHours" = "6 Hours"; -"Scene.Compose.Poll.ThirtyMinutes" = "30 minutes"; +"Scene.Compose.Poll.SixHours" = "6 Horas"; +"Scene.Compose.Poll.ThirtyMinutes" = "30 minutos"; "Scene.Compose.Poll.ThreeDays" = "3 Días"; -"Scene.Compose.ReplyingToUser" = "replying to %@"; -"Scene.Compose.Title.NewPost" = "New Post"; -"Scene.Compose.Title.NewReply" = "New Reply"; +"Scene.Compose.ReplyingToUser" = "en resposta a %@"; +"Scene.Compose.Title.NewPost" = "Nova publicación"; +"Scene.Compose.Title.NewReply" = "Nova resposta"; "Scene.Compose.Visibility.Direct" = "Só para persoas mencionadas"; "Scene.Compose.Visibility.Private" = "Só para seguidoras"; "Scene.Compose.Visibility.Public" = "Público"; "Scene.Compose.Visibility.Unlisted" = "Non listado"; -"Scene.ConfirmEmail.Button.OpenEmailApp" = "Open Email App"; -"Scene.ConfirmEmail.Button.Resend" = "Resend"; -"Scene.ConfirmEmail.DontReceiveEmail.Description" = "Check if your email address is correct as well as your junk folder if you haven’t."; -"Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Resend Email"; -"Scene.ConfirmEmail.DontReceiveEmail.Title" = "Check your email"; -"Scene.ConfirmEmail.OpenEmailApp.Description" = "We just sent you an email. Check your junk folder if you haven’t."; -"Scene.ConfirmEmail.OpenEmailApp.Mail" = "Mail"; -"Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Open Email Client"; -"Scene.ConfirmEmail.OpenEmailApp.Title" = "Check your inbox."; -"Scene.ConfirmEmail.Subtitle" = "Tap the link we emailed to you to verify your account."; -"Scene.ConfirmEmail.Title" = "One last thing."; -"Scene.Discovery.Intro" = "These are the posts gaining traction in your corner of Mastodon."; +"Scene.ConfirmEmail.Button.OpenEmailApp" = "Abrir app de email"; +"Scene.ConfirmEmail.Button.Resend" = "Reenviar"; +"Scene.ConfirmEmail.DontReceiveEmail.Description" = "Comproba que o enderezo de email é correcto e que non vaia directo ao cartafol de spam."; +"Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Volver enviar o correo"; +"Scene.ConfirmEmail.DontReceiveEmail.Title" = "Revisa o teu correo"; +"Scene.ConfirmEmail.OpenEmailApp.Description" = "Enviámosche un email. Se non aparece, mira no cartafol do lixo."; +"Scene.ConfirmEmail.OpenEmailApp.Mail" = "Correo"; +"Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Abrir cliente de email"; +"Scene.ConfirmEmail.OpenEmailApp.Title" = "Mira na caixa de correo."; +"Scene.ConfirmEmail.Subtitle" = "Preme na ligazón que che enviamos ao email para verificar a conta."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Preme na ligazón que che enviamos ao email para verificar a conta"; +"Scene.ConfirmEmail.Title" = "O último detalle."; +"Scene.Discovery.Intro" = "Estas son as publicacións en voga no teu recuncho de Mastodon."; "Scene.Discovery.Tabs.Community" = "Comunidade"; -"Scene.Discovery.Tabs.ForYou" = "For You"; +"Scene.Discovery.Tabs.ForYou" = "Para ti"; "Scene.Discovery.Tabs.Hashtags" = "Cancelos"; "Scene.Discovery.Tabs.News" = "Novas"; "Scene.Discovery.Tabs.Posts" = "Publicacións"; -"Scene.Favorite.Title" = "Your Favorites"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; +"Scene.Favorite.Title" = "Publicacións Favoritas"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Non se mostran seguidoras desde outros servidores."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Non se mostran os seguimentos desde outros servidores."; -"Scene.HomeTimeline.NavigationBarState.NewPosts" = "See new posts"; -"Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; -"Scene.HomeTimeline.NavigationBarState.Published" = "Published!"; -"Scene.HomeTimeline.NavigationBarState.Publishing" = "Publishing post..."; -"Scene.HomeTimeline.Title" = "Home"; -"Scene.Notification.Keyobard.ShowEverything" = "Show Everything"; -"Scene.Notification.Keyobard.ShowMentions" = "Show Mentions"; -"Scene.Notification.NotificationDescription.FavoritedYourPost" = "favorited your post"; -"Scene.Notification.NotificationDescription.FollowedYou" = "followed you"; -"Scene.Notification.NotificationDescription.MentionedYou" = "mentioned you"; -"Scene.Notification.NotificationDescription.PollHasEnded" = "poll has ended"; -"Scene.Notification.NotificationDescription.RebloggedYourPost" = "reblogged your post"; -"Scene.Notification.NotificationDescription.RequestToFollowYou" = "request to follow you"; -"Scene.Notification.Title.Everything" = "Everything"; -"Scene.Notification.Title.Mentions" = "Mentions"; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Toca para ir arriba e toca outra vez para volver ao mesmo lugar"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Botón do logo"; +"Scene.HomeTimeline.NavigationBarState.NewPosts" = "Novas publicacións"; +"Scene.HomeTimeline.NavigationBarState.Offline" = "Sen conexión"; +"Scene.HomeTimeline.NavigationBarState.Published" = "Publicado!"; +"Scene.HomeTimeline.NavigationBarState.Publishing" = "Publicando..."; +"Scene.HomeTimeline.Title" = "Inicio"; +"Scene.Notification.Keyobard.ShowEverything" = "Mostrar Todo"; +"Scene.Notification.Keyobard.ShowMentions" = "Mostrar mencións"; +"Scene.Notification.NotificationDescription.FavoritedYourPost" = "marcou a túa publicación como favorita"; +"Scene.Notification.NotificationDescription.FollowedYou" = "séguete"; +"Scene.Notification.NotificationDescription.MentionedYou" = "mencionoute"; +"Scene.Notification.NotificationDescription.PollHasEnded" = "a enquisa rematou"; +"Scene.Notification.NotificationDescription.RebloggedYourPost" = "compartiu a túa publicación"; +"Scene.Notification.NotificationDescription.RequestToFollowYou" = "solicitou seguirte"; +"Scene.Notification.Title.Everything" = "Todo"; +"Scene.Notification.Title.Mentions" = "Mencións"; "Scene.Preview.Keyboard.ClosePreview" = "Pechar vista previa"; "Scene.Preview.Keyboard.ShowNext" = "Mostrar Seguinte"; "Scene.Preview.Keyboard.ShowPrevious" = "Mostar Anterior"; @@ -251,6 +259,7 @@ uploaded to Mastodon."; "Scene.Profile.SegmentedControl.Posts" = "Publicacións"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Publicacións e respostas"; "Scene.Profile.SegmentedControl.Replies" = "Respostas"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Acordo"; "Scene.Register.Error.Item.Email" = "Email"; "Scene.Register.Error.Item.Locale" = "Locale"; @@ -267,10 +276,10 @@ uploaded to Mastodon."; "Scene.Register.Error.Reason.TooLong" = "%@ é demasiado longo"; "Scene.Register.Error.Reason.TooShort" = "%@ é demasiado curto"; "Scene.Register.Error.Reason.Unreachable" = "%@ semella que non existe"; -"Scene.Register.Error.Special.EmailInvalid" = "This is not a valid email address"; -"Scene.Register.Error.Special.PasswordTooShort" = "Password is too short (must be at least 8 characters)"; +"Scene.Register.Error.Special.EmailInvalid" = "Este non é un enderezo válido de email"; +"Scene.Register.Error.Special.PasswordTooShort" = "O contrasinal é demasiado curto (debe ter 8 caracteres como mínimo)"; "Scene.Register.Error.Special.UsernameInvalid" = "O nome de usuaria só pode ter caracteres alfanuméricos e trazos baixos"; -"Scene.Register.Error.Special.UsernameTooLong" = "Username is too long (can’t be longer than 30 characters)"; +"Scene.Register.Error.Special.UsernameTooLong" = "O nome de usuaria é demasiado longo (maior de 30 caracteres)"; "Scene.Register.Input.Avatar.Delete" = "Eliminar"; "Scene.Register.Input.DisplayName.Placeholder" = "nome público"; "Scene.Register.Input.Email.Placeholder" = "email"; @@ -283,6 +292,7 @@ uploaded to Mastodon."; "Scene.Register.Input.Password.Require" = "O contrasinal debe ter polo menos:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Este nome de usuaria xa está en uso."; "Scene.Register.Input.Username.Placeholder" = "identificador"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Imos crear a túa conta en %@"; "Scene.Register.Title" = "Imos crear a túa conta en %@"; "Scene.Report.Content1" = "Hai outras publicacións que desexes engadir á denuncia?"; "Scene.Report.Content2" = "Hai algo que a moderación deba saber acerca desta denuncia?"; @@ -292,6 +302,38 @@ uploaded to Mastodon."; "Scene.Report.SkipToSend" = "Enviar sen comentarios"; "Scene.Report.Step1" = "Paso 1 de 2"; "Scene.Report.Step2" = "Paso 2 de 2"; +"Scene.Report.StepFinal.BlockUser" = "Bloquear a %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Non queres ver esto?"; +"Scene.Report.StepFinal.MuteUser" = "Acalar a %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "Non poderá seguirte nin ver o que publicas, pero pode ver se foi bloqueada."; +"Scene.Report.StepFinal.Unfollow" = "Deixar de seguir"; +"Scene.Report.StepFinal.UnfollowUser" = "Deixar de seguir a %@"; +"Scene.Report.StepFinal.Unfollowed" = "Deixaches de seguir"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Cando ves en Mastodon algo que non che gusta podes retirar a esa persoa da túa experiencia como usuaria."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Mentras revisamos esto, podes tomar accións contra %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "Non verás as súas publicacións ou repeticións na túa cronoloxía. Non saberá que foi acalada."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Hai algo máis que creas debamos saber?"; +"Scene.Report.StepFour.Step4Of4" = "Paso 4 de 4"; +"Scene.Report.StepOne.IDontLikeIt" = "Non me gusta"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "Non é algo que queiras ver"; +"Scene.Report.StepOne.ItViolatesServerRules" = "Viola as regras do servidor"; +"Scene.Report.StepOne.ItsSomethingElse" = "É outra cousa"; +"Scene.Report.StepOne.ItsSpam" = "É spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Ligazóns perigosas, relacións falsas, ou respostas repetitivas"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Elixe a mellor coincidencia"; +"Scene.Report.StepOne.Step1Of4" = "Paso 1 de 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "O problema non cae dentro de outras categorías"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Cal é o problema con esta conta?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Cal é o problema con esta publicación?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Cal é o problema con %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Décheste conta de que quebra unhas normas en concreto"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Hai algunha publicación que apoie esta denuncia?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Elixe todo o que sexa de aplicación"; +"Scene.Report.StepThree.Step3Of4" = "Paso 3 de 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "Non me gusta"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Elixe todo o que sexa de aplicación"; +"Scene.Report.StepTwo.Step2Of4" = "Paso 2 de 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Que regras foron incumpridas?"; "Scene.Report.TextPlaceholder" = "Escribe ou pega comentarios adicionais"; "Scene.Report.Title" = "Denunciar a %@"; "Scene.Report.TitleReport" = "Denunciar"; @@ -332,61 +374,62 @@ uploaded to Mastodon."; "Scene.ServerPicker.EmptyState.FindingServers" = "Buscando servidores dispoñibles..."; "Scene.ServerPicker.EmptyState.NoResults" = "Sen resultados"; "Scene.ServerPicker.Input.Placeholder" = "Buscar comunidades"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "CATEGORÍA"; "Scene.ServerPicker.Label.Language" = "IDIOMA"; "Scene.ServerPicker.Label.Users" = "USUARIAS"; "Scene.ServerPicker.Subtitle" = "Elixe unha comunidade en función dos teus intereses, rexión ou unha de propósito xeral."; "Scene.ServerPicker.SubtitleExtend" = "Elixe unha comunidade en función dos teus intereses, rexión ou unha de propósito xeral. Cada comunidade está xestionada por unha organización totalmente independente ou unha única persoa."; "Scene.ServerPicker.Title" = "Mastodon fórmano as persoas das diferentes comunidades."; -"Scene.ServerRules.Button.Confirm" = "I Agree"; -"Scene.ServerRules.PrivacyPolicy" = "privacy policy"; -"Scene.ServerRules.Prompt" = "By continuing, you’re subject to the terms of service and privacy policy for %@."; -"Scene.ServerRules.Subtitle" = "These are set and enforced by the %@ moderators."; -"Scene.ServerRules.TermsOfService" = "terms of service"; -"Scene.ServerRules.Title" = "Some ground rules."; -"Scene.Settings.Footer.MastodonDescription" = "Mastodon is open source software. You can report issues on GitHub at %@ (%@)"; -"Scene.Settings.Keyboard.CloseSettingsWindow" = "Close Settings Window"; -"Scene.Settings.Section.Appearance.Automatic" = "Automatic"; -"Scene.Settings.Section.Appearance.Dark" = "Always Dark"; -"Scene.Settings.Section.Appearance.Light" = "Always Light"; -"Scene.Settings.Section.Appearance.Title" = "Appearance"; -"Scene.Settings.Section.BoringZone.AccountSettings" = "Account Settings"; -"Scene.Settings.Section.BoringZone.Privacy" = "Privacy Policy"; -"Scene.Settings.Section.BoringZone.Terms" = "Terms of Service"; -"Scene.Settings.Section.BoringZone.Title" = "The Boring Zone"; -"Scene.Settings.Section.LookAndFeel.Light" = "Light"; -"Scene.Settings.Section.LookAndFeel.ReallyDark" = "Really Dark"; -"Scene.Settings.Section.LookAndFeel.SortaDark" = "Sorta Dark"; -"Scene.Settings.Section.LookAndFeel.Title" = "Look and Feel"; -"Scene.Settings.Section.LookAndFeel.UseSystem" = "Use System"; -"Scene.Settings.Section.Notifications.Boosts" = "Reblogs my post"; -"Scene.Settings.Section.Notifications.Favorites" = "Favorites my post"; -"Scene.Settings.Section.Notifications.Follows" = "Follows me"; -"Scene.Settings.Section.Notifications.Mentions" = "Mentions me"; -"Scene.Settings.Section.Notifications.Title" = "Notifications"; -"Scene.Settings.Section.Notifications.Trigger.Anyone" = "anyone"; -"Scene.Settings.Section.Notifications.Trigger.Follow" = "anyone I follow"; -"Scene.Settings.Section.Notifications.Trigger.Follower" = "a follower"; -"Scene.Settings.Section.Notifications.Trigger.Noone" = "no one"; -"Scene.Settings.Section.Notifications.Trigger.Title" = "Notify me when"; -"Scene.Settings.Section.Preference.DisableAvatarAnimation" = "Disable animated avatars"; -"Scene.Settings.Section.Preference.DisableEmojiAnimation" = "Disable animated emojis"; -"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "Open links in Mastodon"; -"Scene.Settings.Section.Preference.Title" = "Preferences"; -"Scene.Settings.Section.Preference.TrueBlackDarkMode" = "True black dark mode"; -"Scene.Settings.Section.Preference.UsingDefaultBrowser" = "Use default browser to open links"; -"Scene.Settings.Section.SpicyZone.Clear" = "Clear Media Cache"; -"Scene.Settings.Section.SpicyZone.Signout" = "Sign Out"; -"Scene.Settings.Section.SpicyZone.Title" = "The Spicy Zone"; -"Scene.Settings.Title" = "Settings"; -"Scene.SuggestionAccount.FollowExplain" = "When you follow someone, you’ll see their posts in your home feed."; -"Scene.SuggestionAccount.Title" = "Find People to Follow"; -"Scene.Thread.BackTitle" = "Post"; -"Scene.Thread.Title" = "Post from %@"; -"Scene.Welcome.GetStarted" = "Comezar"; +"Scene.ServerRules.Button.Confirm" = "Acepto"; +"Scene.ServerRules.PrivacyPolicy" = "polícica de privacidade"; +"Scene.ServerRules.Prompt" = "Ao continuar, acatas os termos do servizo e a política de privacidade para %@."; +"Scene.ServerRules.Subtitle" = "Son establecidas e aplicadas pola moderación de %@."; +"Scene.ServerRules.TermsOfService" = "termos do servizo"; +"Scene.ServerRules.Title" = "Algunhas regras básicas."; +"Scene.Settings.Footer.MastodonDescription" = "Mastodon é software de código aberto. Podes informar de fallos en GitHub en %@ (%@)"; +"Scene.Settings.Keyboard.CloseSettingsWindow" = "Pechar ventá de axustes"; +"Scene.Settings.Section.Appearance.Automatic" = "Automático"; +"Scene.Settings.Section.Appearance.Dark" = "Sempre escuro"; +"Scene.Settings.Section.Appearance.Light" = "Sempre claro"; +"Scene.Settings.Section.Appearance.Title" = "Aparencia"; +"Scene.Settings.Section.BoringZone.AccountSettings" = "Axustes da conta"; +"Scene.Settings.Section.BoringZone.Privacy" = "Política de Privacidade"; +"Scene.Settings.Section.BoringZone.Terms" = "Termos do Servizo"; +"Scene.Settings.Section.BoringZone.Title" = "A zona aburrida"; +"Scene.Settings.Section.LookAndFeel.Light" = "Claro"; +"Scene.Settings.Section.LookAndFeel.ReallyDark" = "Realmente escuro"; +"Scene.Settings.Section.LookAndFeel.SortaDark" = "Algo escuro"; +"Scene.Settings.Section.LookAndFeel.Title" = "Aparencia"; +"Scene.Settings.Section.LookAndFeel.UseSystem" = "Seguir o sistema"; +"Scene.Settings.Section.Notifications.Boosts" = "Promove a miña publicación"; +"Scene.Settings.Section.Notifications.Favorites" = "Favorece a miña publicación"; +"Scene.Settings.Section.Notifications.Follows" = "Me segue"; +"Scene.Settings.Section.Notifications.Mentions" = "Me menciona"; +"Scene.Settings.Section.Notifications.Title" = "Notificacións"; +"Scene.Settings.Section.Notifications.Trigger.Anyone" = "calquera"; +"Scene.Settings.Section.Notifications.Trigger.Follow" = "alguén a quen sigo"; +"Scene.Settings.Section.Notifications.Trigger.Follower" = "unha seguidora"; +"Scene.Settings.Section.Notifications.Trigger.Noone" = "ninguén"; +"Scene.Settings.Section.Notifications.Trigger.Title" = "Avisarme cando"; +"Scene.Settings.Section.Preference.DisableAvatarAnimation" = "Desactivar avatares animados"; +"Scene.Settings.Section.Preference.DisableEmojiAnimation" = "Desactivar emojis animados"; +"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "Abrir ligazóns en Mastodon"; +"Scene.Settings.Section.Preference.Title" = "Preferencias"; +"Scene.Settings.Section.Preference.TrueBlackDarkMode" = "Modo negro verdadeiro"; +"Scene.Settings.Section.Preference.UsingDefaultBrowser" = "Usar navegador por defecto para as ligazóns"; +"Scene.Settings.Section.SpicyZone.Clear" = "Limpar caché multimedia"; +"Scene.Settings.Section.SpicyZone.Signout" = "Pechar sesión"; +"Scene.Settings.Section.SpicyZone.Title" = "A zona picante"; +"Scene.Settings.Title" = "Axustes"; +"Scene.SuggestionAccount.FollowExplain" = "Cando sigas a alguén verás as súas publicacións na cronoloxía de inicio."; +"Scene.SuggestionAccount.Title" = "Atopar persoas para seguir"; +"Scene.Thread.BackTitle" = "Publicación"; +"Scene.Thread.Title" = "Publicación de %@"; +"Scene.Welcome.GetStarted" = "Crear conta"; "Scene.Welcome.LogIn" = "Acceder"; -"Scene.Welcome.Slogan" = "Social networking -back in your hands."; -"Scene.Wizard.AccessibilityHint" = "Double tap to dismiss this wizard"; -"Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Switch between multiple accounts by holding the profile button."; -"Scene.Wizard.NewInMastodon" = "New in Mastodon"; \ No newline at end of file +"Scene.Welcome.Slogan" = "Comunicación social +de volta ás túas mans."; +"Scene.Wizard.AccessibilityHint" = "Dobre toque para desbotar este asistente"; +"Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Cambia dunha conta a outra mantendo preso o botón do perfil."; +"Scene.Wizard.NewInMastodon" = "Novidade en Mastodon"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.stringsdict index 503ff9dbd..ff9d87c18 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/gl.lproj/Localizable.stringsdict @@ -13,15 +13,15 @@ NSStringFormatValueTypeKey ld one - 1 unread notification + 1 notificación non lida other - %ld unread notification + %ld notificacións non lidas a11y.plural.count.input_limit_exceeds NSStringLocalizedFormatKey - Input limit exceeds %#@character_count@ + O límite supera %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -29,15 +29,15 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 caracter other - %ld characters + %ld caracteres a11y.plural.count.input_limit_remains NSStringLocalizedFormatKey - Input limit remains %#@character_count@ + O límite de entrada mantense en %#@character_count@ character_count NSStringFormatSpecTypeKey @@ -45,9 +45,36 @@ NSStringFormatValueTypeKey ld one - 1 character + 1 caracter other - %ld characters + %ld caracteres + + + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Seguida por %1$@, e outro común + other + Seguida por %1$@, e %ld comúns plural.count.metric_formatted.post @@ -61,9 +88,25 @@ NSStringFormatValueTypeKey ld one - post + publicación other - posts + publicacións + + + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 mutlimedia + other + %ld multimedias plural.count.post @@ -77,9 +120,9 @@ NSStringFormatValueTypeKey ld one - 1 post + 1 publicación other - %ld posts + %ld publicacións plural.count.favorite @@ -93,9 +136,9 @@ NSStringFormatValueTypeKey ld one - 1 favorite + 1 favorito other - %ld favorites + %ld favoritos plural.count.reblog @@ -109,9 +152,9 @@ NSStringFormatValueTypeKey ld one - 1 reblog + 1 promoción other - %ld reblogs + %ld promocións plural.count.reply @@ -125,9 +168,9 @@ NSStringFormatValueTypeKey ld one - 1 reply + 1 resposta other - %ld replies + %ld respostas plural.count.vote @@ -141,9 +184,9 @@ NSStringFormatValueTypeKey ld one - 1 vote + 1 voto other - %ld votes + %ld votos plural.count.voter @@ -157,9 +200,9 @@ NSStringFormatValueTypeKey ld one - 1 voter + 1 votante other - %ld voters + %ld votantes plural.people_talking @@ -173,9 +216,9 @@ NSStringFormatValueTypeKey ld one - 1 people talking + 1 persoa comentando other - %ld people talking + %ld persoas comentando plural.count.following @@ -189,9 +232,9 @@ NSStringFormatValueTypeKey ld one - 1 following + 1 seguimento other - %ld following + %ld seguimentos plural.count.follower @@ -205,9 +248,9 @@ NSStringFormatValueTypeKey ld one - 1 follower + 1 seguidora other - %ld followers + %ld seguidoras date.year.left @@ -221,9 +264,9 @@ NSStringFormatValueTypeKey ld one - 1 year left + Queda 1 ano other - %ld years left + Quedan %ld anos date.month.left @@ -237,9 +280,9 @@ NSStringFormatValueTypeKey ld one - 1 months left + Queda 1 mes other - %ld months left + Quedan %ld meses date.day.left @@ -253,9 +296,9 @@ NSStringFormatValueTypeKey ld one - 1 day left + Queda 1 día other - %ld days left + Quedan %ld días date.hour.left @@ -269,9 +312,9 @@ NSStringFormatValueTypeKey ld one - 1 hour left + Queda 1 hora other - %ld hours left + Quedan %ld horas date.minute.left @@ -285,9 +328,9 @@ NSStringFormatValueTypeKey ld one - 1 minute left + Queda 1 minuto other - %ld minutes left + Quedan %ld minutos date.second.left @@ -301,9 +344,9 @@ NSStringFormatValueTypeKey ld one - 1 second left + Queda 1 segundo other - %ld seconds left + Quedan %ld segundos date.year.ago.abbr @@ -317,9 +360,9 @@ NSStringFormatValueTypeKey ld one - 1y ago + hai 1 ano other - %ldy ago + hai %ld anos date.month.ago.abbr @@ -333,9 +376,9 @@ NSStringFormatValueTypeKey ld one - 1M ago + hai 1 mes other - %ldM ago + hai %ld meses date.day.ago.abbr @@ -349,9 +392,9 @@ NSStringFormatValueTypeKey ld one - 1d ago + hai 1 día other - %ldd ago + hai %ld días date.hour.ago.abbr @@ -365,9 +408,9 @@ NSStringFormatValueTypeKey ld one - 1h ago + fai 1 hora other - %ldh ago + fai %ld horas date.minute.ago.abbr @@ -381,9 +424,9 @@ NSStringFormatValueTypeKey ld one - 1m ago + fai 1 minuto other - %ldm ago + fai %ld minutos date.second.ago.abbr @@ -397,9 +440,9 @@ NSStringFormatValueTypeKey ld one - 1s ago + fai 1 seg. other - %lds ago + fai %ld seg. diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings index 8a80b11da..6e4e5589f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.strings @@ -200,6 +200,7 @@ caricato su Mastodon."; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Apri client Email"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Controlla la tua posta in arrivo."; "Scene.ConfirmEmail.Subtitle" = "Tocca il link che ti abbiamo inviato per verificare il tuo account."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tocca sul collegamento che ti abbiamo inviato, per verificare il tuo account"; "Scene.ConfirmEmail.Title" = "Un'ultima cosa."; "Scene.Discovery.Intro" = "Questi sono i post che stanno guadagnando popolarità nel tuo angolo di Mastodon."; "Scene.Discovery.Tabs.Community" = "Comunità"; @@ -207,9 +208,16 @@ caricato su Mastodon."; "Scene.Discovery.Tabs.Hashtags" = "Hashtag"; "Scene.Discovery.Tabs.News" = "Notizie"; "Scene.Discovery.Tabs.Posts" = "Post"; +"Scene.Familiarfollowers.FollowedByNames" = "Seguito da %@"; +"Scene.Familiarfollowers.Title" = "Seguaci che conosci"; "Scene.Favorite.Title" = "I tuoi preferiti"; +"Scene.FavoritedBy.Title" = "Preferito Da"; "Scene.Follower.Footer" = "I seguaci da altri server non vengono visualizzati."; +"Scene.Follower.Title" = "seguace"; "Scene.Following.Footer" = "I follow da altri server non vengono visualizzati."; +"Scene.Following.Title" = "seguendo"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tocca per scorrere verso l'alto e tocca di nuovo verso la posizione precedente"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Pulsante Logo"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Vedi nuovi post"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Non in linea"; "Scene.HomeTimeline.NavigationBarState.Published" = "Pubblicato!"; @@ -251,6 +259,7 @@ caricato su Mastodon."; "Scene.Profile.SegmentedControl.Posts" = "Post"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Post e risposte"; "Scene.Profile.SegmentedControl.Replies" = "Risposte"; +"Scene.RebloggedBy.Title" = "Condiviso Da"; "Scene.Register.Error.Item.Agreement" = "Accordo"; "Scene.Register.Error.Item.Email" = "Email"; "Scene.Register.Error.Item.Locale" = "Locale"; @@ -283,6 +292,7 @@ caricato su Mastodon."; "Scene.Register.Input.Password.Require" = "La tua password ha bisogno di almeno:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Questo nome utente è già stato preso."; "Scene.Register.Input.Username.Placeholder" = "nome utente"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Facciamo in modo che sia configurato su %@"; "Scene.Register.Title" = "Facciamo in modo che sia configurato il %@"; "Scene.Report.Content1" = "Ci sono altri post che vorresti aggiungere alla segnalazione?"; "Scene.Report.Content2" = "C'è qualcosa che i moderatori dovrebbero sapere su questa segnalazione?"; @@ -292,6 +302,38 @@ caricato su Mastodon."; "Scene.Report.SkipToSend" = "Invia senza commento"; "Scene.Report.Step1" = "Fase 1 di 2"; "Scene.Report.Step2" = "Fase 2 di 2"; +"Scene.Report.StepFinal.BlockUser" = "Blocca %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Non vuoi vedere questo?"; +"Scene.Report.StepFinal.MuteUser" = "Silenzia %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "Non saranno più in grado di seguire o vedere i tuoi post, ma possono vedere se sono stati bloccati."; +"Scene.Report.StepFinal.Unfollow" = "Smetti di seguire"; +"Scene.Report.StepFinal.UnfollowUser" = "Smetti di seguire %@"; +"Scene.Report.StepFinal.Unfollowed" = "Non seguito"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Quando vedi qualcosa che non ti piace su Mastodon, puoi rimuovere la persona dalla tua esperienza."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Mentre controlliamo, puoi agire contro %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "Non vedrai i loro post o le condivisioni nel tuo feed. Non sapranno di essere stati silenziati."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "C'è altro che dovremmo sapere?"; +"Scene.Report.StepFour.Step4Of4" = "Fase 4 di 4"; +"Scene.Report.StepOne.IDontLikeIt" = "Non mi piace"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "È qualcosa che non vuoi vedere"; +"Scene.Report.StepOne.ItViolatesServerRules" = "Viola le regole del server"; +"Scene.Report.StepOne.ItsSomethingElse" = "È qualcos'altro"; +"Scene.Report.StepOne.ItsSpam" = "È spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Collegamenti malevoli, false interazioni o risposte ripetitive"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Scegli la migliore corrispondenza"; +"Scene.Report.StepOne.Step1Of4" = "Fase 1 di 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "Il problema non rientra in altre categorie"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Cosa c'è che non va con questo account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Cosa c'è che non va con questo post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Cosa c'è che non va con %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Sei consapevole che violi regole specifiche"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Ci sono post a sostegno di questa segnalazione?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Seleziona tutte le risposte pertinenti"; +"Scene.Report.StepThree.Step3Of4" = "Fase 3 di 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "Non mi piace"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Seleziona tutte le risposte pertinenti"; +"Scene.Report.StepTwo.Step2Of4" = "Fase 2 di 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Quali regole vengono violate?"; "Scene.Report.TextPlaceholder" = "Digita o incolla commenti aggiuntivi"; "Scene.Report.Title" = "Segnala %@"; "Scene.Report.TitleReport" = "Segnala"; @@ -332,6 +374,7 @@ caricato su Mastodon."; "Scene.ServerPicker.EmptyState.FindingServers" = "Ricerca server disponibili..."; "Scene.ServerPicker.EmptyState.NoResults" = "Nessun risultato"; "Scene.ServerPicker.Input.Placeholder" = "Cerca comunità"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Cerca i server o inserisci l'URL"; "Scene.ServerPicker.Label.Category" = "CATEGORIA"; "Scene.ServerPicker.Label.Language" = "LINGUA"; "Scene.ServerPicker.Label.Users" = "UTENTI"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.stringsdict index 710980608..38f986521 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/it.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld caratteri + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Seguito da %1$@ e un altro amico in comune + other + Seguito da %1$@ e %ld amici in comune + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ post + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 contenuto multimediale + other + %ld contenuti multimediali + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings index 19056cf5a..ea59763b1 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.strings @@ -4,8 +4,8 @@ "Common.Alerts.CleanCache.Title" = "キャッシュを消去"; "Common.Alerts.Common.PleaseTryAgain" = "もう一度お試しください。"; "Common.Alerts.Common.PleaseTryAgainLater" = "後でもう一度お試しください。"; -"Common.Alerts.DeletePost.Message" = "本当に削除しますか?"; -"Common.Alerts.DeletePost.Title" = "この投稿を消去しますか?"; +"Common.Alerts.DeletePost.Message" = "本当にこの投稿を削除しますか?"; +"Common.Alerts.DeletePost.Title" = "投稿を削除"; "Common.Alerts.DiscardPostContent.Message" = "この操作は取り消しできません。下書きは失われます。"; "Common.Alerts.DiscardPostContent.Title" = "投稿を破棄しますか?"; "Common.Alerts.EditProfileFailure.Message" = "プロフィールを編集できません。もう一度お試しください。"; @@ -32,13 +32,13 @@ "Common.Controls.Actions.Confirm" = "確認"; "Common.Controls.Actions.Continue" = "続ける"; "Common.Controls.Actions.CopyPhoto" = "写真をコピー"; -"Common.Controls.Actions.Delete" = "消去"; +"Common.Controls.Actions.Delete" = "削除"; "Common.Controls.Actions.Discard" = "破棄"; "Common.Controls.Actions.Done" = "完了"; "Common.Controls.Actions.Edit" = "編集"; "Common.Controls.Actions.FindPeople" = "フォローする人を見つける"; "Common.Controls.Actions.ManuallySearch" = "手動で検索する"; -"Common.Controls.Actions.Next" = "次"; +"Common.Controls.Actions.Next" = "次へ"; "Common.Controls.Actions.Ok" = "OK"; "Common.Controls.Actions.Open" = "開く"; "Common.Controls.Actions.OpenInBrowser" = "ブラウザで開く"; @@ -98,8 +98,8 @@ "Common.Controls.Status.Actions.Menu" = "メニュー"; "Common.Controls.Status.Actions.Reblog" = "ブースト"; "Common.Controls.Status.Actions.Reply" = "返信"; -"Common.Controls.Status.Actions.ShowGif" = "Show GIF"; -"Common.Controls.Status.Actions.ShowImage" = "Show image"; +"Common.Controls.Status.Actions.ShowGif" = "GIFを表示"; +"Common.Controls.Status.Actions.ShowImage" = "画像を表示"; "Common.Controls.Status.Actions.ShowVideoPlayer" = "Show video player"; "Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Tap then hold to show menu"; "Common.Controls.Status.Actions.Unfavorite" = "お気に入り登録を取り消す"; @@ -117,7 +117,7 @@ "Common.Controls.Status.Tag.Link" = "リンク"; "Common.Controls.Status.Tag.Mention" = "メンション"; "Common.Controls.Status.Tag.Url" = "URL"; -"Common.Controls.Status.TapToReveal" = "Tap to reveal"; +"Common.Controls.Status.TapToReveal" = "タップして表示"; "Common.Controls.Status.UserReblogged" = "%@がブースト"; "Common.Controls.Status.UserRepliedTo" = "%@に返信"; "Common.Controls.Status.Visibility.Direct" = "この投稿はメンションされたユーザーに限り見ることができます。"; @@ -195,16 +195,24 @@ "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "メールアプリを開く"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "メールを確認"; "Scene.ConfirmEmail.Subtitle" = "先程 %@ にメールを送信しました。リンクをタップしてアカウントを確認してください。"; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "さいごにもうひとつ。"; -"Scene.Discovery.Intro" = "These are the posts gaining traction in your corner of Mastodon."; -"Scene.Discovery.Tabs.Community" = "Community"; -"Scene.Discovery.Tabs.ForYou" = "For You"; +"Scene.Discovery.Intro" = "あなたのMastodonサーバーで注目を集めている投稿がここに表示されます。"; +"Scene.Discovery.Tabs.Community" = "コミュニティ"; +"Scene.Discovery.Tabs.ForYou" = "おすすめ"; "Scene.Discovery.Tabs.Hashtags" = "ハッシュタグ"; "Scene.Discovery.Tabs.News" = "ニュース"; "Scene.Discovery.Tabs.Posts" = "投稿"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "お気に入り"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "他のサーバーからのフォロワーは表示されません。"; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "他のサーバーにいるフォローは表示されません。"; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "新しい投稿を見る"; "Scene.HomeTimeline.NavigationBarState.Offline" = "オフライン"; "Scene.HomeTimeline.NavigationBarState.Published" = "投稿しました!"; @@ -212,12 +220,12 @@ "Scene.HomeTimeline.Title" = "ホーム"; "Scene.Notification.Keyobard.ShowEverything" = "すべて見る"; "Scene.Notification.Keyobard.ShowMentions" = "メンションを見る"; -"Scene.Notification.NotificationDescription.FavoritedYourPost" = "favorited your post"; -"Scene.Notification.NotificationDescription.FollowedYou" = "followed you"; -"Scene.Notification.NotificationDescription.MentionedYou" = "mentioned you"; -"Scene.Notification.NotificationDescription.PollHasEnded" = "poll has ended"; -"Scene.Notification.NotificationDescription.RebloggedYourPost" = "reblogged your post"; -"Scene.Notification.NotificationDescription.RequestToFollowYou" = "request to follow you"; +"Scene.Notification.NotificationDescription.FavoritedYourPost" = "さんがあなたの投稿をお気に入りに登録しました"; +"Scene.Notification.NotificationDescription.FollowedYou" = "さんにフォローされました"; +"Scene.Notification.NotificationDescription.MentionedYou" = "さんがあなたに返信しました"; +"Scene.Notification.NotificationDescription.PollHasEnded" = "アンケートが終了しました"; +"Scene.Notification.NotificationDescription.RebloggedYourPost" = "さんがあなたの投稿をブーストしました"; +"Scene.Notification.NotificationDescription.RequestToFollowYou" = "さんがあなたにフォローリクエストしました"; "Scene.Notification.Title.Everything" = "すべて"; "Scene.Notification.Title.Mentions" = "メンション"; "Scene.Preview.Keyboard.ClosePreview" = "プレビューを閉じる"; @@ -246,6 +254,7 @@ "Scene.Profile.SegmentedControl.Posts" = "投稿"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "投稿と返信"; "Scene.Profile.SegmentedControl.Replies" = "返信"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "契約"; "Scene.Register.Error.Item.Email" = "メール"; "Scene.Register.Error.Item.Locale" = "地域"; @@ -266,7 +275,7 @@ "Scene.Register.Error.Special.PasswordTooShort" = "パスワードが短すぎます(8文字以上)"; "Scene.Register.Error.Special.UsernameInvalid" = "ユーザーネームには、英数字とアンダースコアのみを使用してください。"; "Scene.Register.Error.Special.UsernameTooLong" = "ユーザー名が長すぎます(30文字以内)"; -"Scene.Register.Input.Avatar.Delete" = "消去"; +"Scene.Register.Input.Avatar.Delete" = "削除"; "Scene.Register.Input.DisplayName.Placeholder" = "表示名"; "Scene.Register.Input.Email.Placeholder" = "メール"; "Scene.Register.Input.Invite.RegistrationUserInviteRequest" = "なぜ参加したいと思ったのですか?"; @@ -278,6 +287,7 @@ "Scene.Register.Input.Password.Require" = "Your password needs at least:"; "Scene.Register.Input.Username.DuplicatePrompt" = "このユーザー名は使用されています"; "Scene.Register.Input.Username.Placeholder" = "ユーザー名"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "あなたのことを教えてください"; "Scene.Report.Content1" = "他に通報したい投稿はありますか?"; "Scene.Report.Content2" = "この通報についてモデレーターに伝達しておきたい事項はありますか?"; @@ -287,6 +297,38 @@ "Scene.Report.SkipToSend" = "コメントなしで送信"; "Scene.Report.Step1" = "ステップ 1/2"; "Scene.Report.Step2" = "ステップ 2/2"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Unfollow"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; +"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; +"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; +"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; +"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; +"Scene.Report.StepOne.ItsSpam" = "It’s spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; "Scene.Report.TextPlaceholder" = "追加コメントを入力"; "Scene.Report.Title" = "%@を通報"; "Scene.Report.TitleReport" = "報告する"; @@ -327,6 +369,7 @@ "Scene.ServerPicker.EmptyState.FindingServers" = "利用可能なサーバーの検索..."; "Scene.ServerPicker.EmptyState.NoResults" = "なし"; "Scene.ServerPicker.Input.Placeholder" = "サーバーを探す"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "カテゴリー"; "Scene.ServerPicker.Label.Language" = "言語"; "Scene.ServerPicker.Label.Users" = "ユーザー"; @@ -349,11 +392,11 @@ "Scene.Settings.Section.BoringZone.Privacy" = "プライバシーポリシー"; "Scene.Settings.Section.BoringZone.Terms" = "利用規約"; "Scene.Settings.Section.BoringZone.Title" = "アプリについて"; -"Scene.Settings.Section.LookAndFeel.Light" = "Light"; -"Scene.Settings.Section.LookAndFeel.ReallyDark" = "Really Dark"; -"Scene.Settings.Section.LookAndFeel.SortaDark" = "Sorta Dark"; -"Scene.Settings.Section.LookAndFeel.Title" = "Look and Feel"; -"Scene.Settings.Section.LookAndFeel.UseSystem" = "Use System"; +"Scene.Settings.Section.LookAndFeel.Light" = "ライト"; +"Scene.Settings.Section.LookAndFeel.ReallyDark" = "ブラック"; +"Scene.Settings.Section.LookAndFeel.SortaDark" = "ダーク"; +"Scene.Settings.Section.LookAndFeel.Title" = "テーマ"; +"Scene.Settings.Section.LookAndFeel.UseSystem" = "端末の設定を使う"; "Scene.Settings.Section.Notifications.Boosts" = "ブースト"; "Scene.Settings.Section.Notifications.Favorites" = "お気に入り登録"; "Scene.Settings.Section.Notifications.Follows" = "フォロー"; @@ -366,7 +409,7 @@ "Scene.Settings.Section.Notifications.Trigger.Title" = "通知を受け取る"; "Scene.Settings.Section.Preference.DisableAvatarAnimation" = "アバターのアニメーションを無効化する"; "Scene.Settings.Section.Preference.DisableEmojiAnimation" = "絵文字のアニメーションを無効化する"; -"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "Open links in Mastodon"; +"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "Mastodonでリンクを開く"; "Scene.Settings.Section.Preference.Title" = "環境設定"; "Scene.Settings.Section.Preference.TrueBlackDarkMode" = "真っ黒なダークテーマを使用する"; "Scene.Settings.Section.Preference.UsingDefaultBrowser" = "既定のブラウザでリンクを開く"; @@ -378,7 +421,7 @@ "Scene.SuggestionAccount.Title" = "フォローする人を探す"; "Scene.Thread.BackTitle" = "投稿"; "Scene.Thread.Title" = "%@の投稿"; -"Scene.Welcome.GetStarted" = "Get Started"; +"Scene.Welcome.GetStarted" = "はじめる"; "Scene.Welcome.LogIn" = "ログイン"; "Scene.Welcome.Slogan" = "ソーシャルネットワーキングを、あなたの手の中に."; "Scene.Wizard.AccessibilityHint" = "チュートリアルを閉じるには、ダブルタップしてください"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.stringsdict index 8dfc95079..054b8cded 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ja.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld 文字 + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ 投稿 + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld media + + plural.count.post NSStringLocalizedFormatKey @@ -153,7 +190,7 @@ NSStringFormatValueTypeKey ld other - %ld people talking + %ld人が投稿 plural.count.following diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings index 3ea1700cd..fc7c720ae 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.strings @@ -200,6 +200,7 @@ Ad d-yettwasali ɣef Mastodon."; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Ldi amsaɣ n yimayl"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Sefqed Tanaka-inek."; "Scene.ConfirmEmail.Subtitle" = "Sit ɣef useɣwen i ak-n-uznen i wakken ad tesneqdeḍ amiḍan-ik."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "Taɣawsa taneggarut."; "Scene.Discovery.Intro" = "Tigi d tisuffaɣ i d-ijebbden s waṭas deg tama-inek•inem n Mastodon."; "Scene.Discovery.Tabs.Community" = "Community"; @@ -207,9 +208,16 @@ Ad d-yettwasali ɣef Mastodon."; "Scene.Discovery.Tabs.Hashtags" = "Ihacṭagen"; "Scene.Discovery.Tabs.News" = "Isallen"; "Scene.Discovery.Tabs.Posts" = "Tisuffaɣ"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Ismenyifen-ik·im"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Ineḍfaren seg yiqeddacen-nniḍen ur d-ttwaskanen ara."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Ineḍfaren seg yiqeddacen-nniḍen ur d-ttwaskanen ara."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Tissufaɣ timaynutin"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Beṛṛa n tuqqna"; "Scene.HomeTimeline.NavigationBarState.Published" = "Yettwasuffeɣ!"; @@ -251,6 +259,7 @@ Ad d-yettwasali ɣef Mastodon."; "Scene.Profile.SegmentedControl.Posts" = "Imagraden"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Tisuffaɣ d tririyin"; "Scene.Profile.SegmentedControl.Replies" = "Tiririyin"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Amtawa"; "Scene.Register.Error.Item.Email" = "Imayl"; "Scene.Register.Error.Item.Locale" = "Tadigant"; @@ -283,6 +292,7 @@ Ad d-yettwasali ɣef Mastodon."; "Scene.Register.Input.Password.Require" = "Awal-ik uffir yesra ma drus:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Isem-ayi n umseqdac yettwaṭṭef yakan."; "Scene.Register.Input.Username.Placeholder" = "isem n useqdac"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "Aha ad nebdu asbadu ɣef %@"; "Scene.Report.Content1" = "Tebɣiḍ ad ternuḍ tisuffaɣ-nniḍen ɣer uneqqis?"; "Scene.Report.Content2" = "Yella wayen i ilaqen ad teẓren yimḍebbren ɣef uneqqis-a?"; @@ -292,6 +302,38 @@ Ad d-yettwasali ɣef Mastodon."; "Scene.Report.SkipToSend" = "Azen s war awennit"; "Scene.Report.Step1" = "Aḥric 1 seg 2"; "Scene.Report.Step2" = "Aḥric 2 seg 2"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Unfollow"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; +"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; +"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; +"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; +"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; +"Scene.Report.StepOne.ItsSpam" = "It’s spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; "Scene.Report.TextPlaceholder" = "Aru neɣ senteḍ iwenniten-nniḍen"; "Scene.Report.Title" = "Aneqqis %@"; "Scene.Report.TitleReport" = "Aneqqis"; @@ -332,6 +374,7 @@ Ad d-yettwasali ɣef Mastodon."; "Scene.ServerPicker.EmptyState.FindingServers" = "Tifin n yiqeddacen yellan..."; "Scene.ServerPicker.EmptyState.NoResults" = "Ulac igemmaḍ"; "Scene.ServerPicker.Input.Placeholder" = "Nadi timɣiwnin"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "TAGGAYT"; "Scene.ServerPicker.Label.Language" = "TUTLAYT"; "Scene.ServerPicker.Label.Users" = "ISEQDACEN"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.stringsdict index 4ccb271fa..09e3645f3 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/kab.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld yisekkilen + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ tisuffaɣ + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings index 7f2e7ef48..472bc9403 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.strings @@ -201,6 +201,7 @@ Profîla te ji wan ra wiha xuya dike."; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Nameyên xwe yên wergirtî kontrol bike."; "Scene.ConfirmEmail.Subtitle" = "Me tenê e-nameyek ji %@ re şand, girêdanê bitikne da ku ajimêra xwe bidî piştrastkirin."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Girêdana e-nameyê ku me ji te re şand bitikîne da ku ajimêra xwe bidî piştrastkirin"; "Scene.ConfirmEmail.Title" = "Tiştekî dawî."; "Scene.Discovery.Intro" = "Ev şandiyên ku di quncika Mastodon balê dikişîne."; "Scene.Discovery.Tabs.Community" = "Civak"; @@ -208,9 +209,16 @@ girêdanê bitikne da ku ajimêra xwe bidî piştrastkirin."; "Scene.Discovery.Tabs.Hashtags" = "Hashtag"; "Scene.Discovery.Tabs.News" = "Nûçe"; "Scene.Discovery.Tabs.Posts" = "Şandî"; +"Scene.Familiarfollowers.FollowedByNames" = "Ji aliyêm%@ hatiye şopandin"; +"Scene.Familiarfollowers.Title" = "Şopînerên ku tu wan nas dikî"; "Scene.Favorite.Title" = "Bijarteyên te"; +"Scene.FavoritedBy.Title" = "Hatiye hezkirin ji aliyê"; "Scene.Follower.Footer" = "Şopîner ji rajekerên din nayê dîtin."; +"Scene.Follower.Title" = "şopîner"; "Scene.Following.Footer" = "Şopandin ji rajekerên din nayê dîtin."; +"Scene.Following.Title" = "dişopîne"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Ji bo şemitandina jor û dîsa li cihê berê vegerî bitikîne"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Bişkoka Logo"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Şandiyên nû bibîne"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Derhêl"; "Scene.HomeTimeline.NavigationBarState.Published" = "Hate weşandin!"; @@ -252,6 +260,7 @@ girêdanê bitikne da ku ajimêra xwe bidî piştrastkirin."; "Scene.Profile.SegmentedControl.Posts" = "Şandî"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Şandî û bersiv"; "Scene.Profile.SegmentedControl.Replies" = "Bersiv"; +"Scene.RebloggedBy.Title" = "Ji nû ve hatiye nivîsandin ji aliyê"; "Scene.Register.Error.Item.Agreement" = "Peyman"; "Scene.Register.Error.Item.Email" = "E-name"; "Scene.Register.Error.Item.Locale" = "Zimanê navrûyê"; @@ -284,6 +293,7 @@ girêdanê bitikne da ku ajimêra xwe bidî piştrastkirin."; "Scene.Register.Input.Password.Require" = "Pêdiviya pêborîna te ya herî kêm:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Navê vê bikarhêner tê girtin."; "Scene.Register.Input.Username.Placeholder" = "navê bikarhêner"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Ka em te bi rê bixin li ser %@"; "Scene.Register.Title" = "Ji me re hinekî qala xwe bike %@"; "Scene.Report.Content1" = "Şandiyên din hene ku tu dixwazî tevlî ragihandinê bikî?"; "Scene.Report.Content2" = "Derbarê vê ragihandinê de tiştek heye ku divê çavdêr bizanin?"; @@ -293,6 +303,38 @@ girêdanê bitikne da ku ajimêra xwe bidî piştrastkirin."; "Scene.Report.SkipToSend" = "Bêyî şirove bişîne"; "Scene.Report.Step1" = "Gav 1 ji 2"; "Scene.Report.Step2" = "Gav 2 ji 2"; +"Scene.Report.StepFinal.BlockUser" = "%@ asteng bike"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Tu naxwazî vê bibînî?"; +"Scene.Report.StepFinal.MuteUser" = "%@ bêdeng bike"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "Êdî nikarin şandiyên te bişopînin an jî bibînin, lê ew dikarin bibînin ka hatine astengkirin an na."; +"Scene.Report.StepFinal.Unfollow" = "Neşopîne"; +"Scene.Report.StepFinal.UnfollowUser" = "%@ neşopîne"; +"Scene.Report.StepFinal.Unfollowed" = "Ji şopê hate derketin"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Dema li ser Mastodonê tiştekî ku tu jê hez nakî bibînî, tu dikarî ew kes ji navrûya xwe derxî."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Dema ku em vê yekê dinirxînin, tu dikarî li dijî %@ tedbîran bigirî"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "Tu yê şandî an jî bilindkirinên wan di rojeva xwe de nebînî. Ew ê nizanibin ku hatine bêdengkirin."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Tiştek din heye ku tu difikirî ku divê em zanibin?"; +"Scene.Report.StepFour.Step4Of4" = "Gav 4 ji 4"; +"Scene.Report.StepOne.IDontLikeIt" = "Ez jê hez nakim"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "Ew ne tiştek e ku tu dixwazî bibînî"; +"Scene.Report.StepOne.ItViolatesServerRules" = "Ew rêzikên rajekar binpê dike"; +"Scene.Report.StepOne.ItsSomethingElse" = "Tiştekî din e"; +"Scene.Report.StepOne.ItsSpam" = "Ew spam e"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Girêdanên xerab, tevlêbûna sexte, an jî bersivên dubarekirî"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Baştirîn lihevhatina hilbijêre"; +"Scene.Report.StepOne.Step1Of4" = "Gav 1 ji 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "Pirsgirêk di kategoriyên din de cih nagire"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Çi çewt e di vê ajimêrê de?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Çi çewt e di vê şandiyê de?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Çi çewt e bi %@ re?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Tu dizanî ku ew rêzikên taybetiyê binpê dike"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Tu şandiyên ku vê ragihandinê piştgirî dikin hene?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Hemûyên ku têne sepandin hilbijêre"; +"Scene.Report.StepThree.Step3Of4" = "Gav 3 ji 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "Tenê ez jê hez nakim"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Hemûyên ku têne sepandin hilbijêre"; +"Scene.Report.StepTwo.Step2Of4" = "Gav 2 ji 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Kîjan rêzik têne binpêkirin?"; "Scene.Report.TextPlaceholder" = "Şiroveyên daxwazkirê binivîsine an jî pê ve bike"; "Scene.Report.Title" = "%@ ragihîne"; "Scene.Report.TitleReport" = "Ragihandin"; @@ -332,14 +374,14 @@ girêdanê bitikne da ku ajimêra xwe bidî piştrastkirin."; "Scene.ServerPicker.EmptyState.BadNetwork" = "Di dema barkirina daneyan da çewtî derket. Girêdana xwe ya înternetê kontrol bike."; "Scene.ServerPicker.EmptyState.FindingServers" = "Peydakirina rajekarên berdest..."; "Scene.ServerPicker.EmptyState.NoResults" = "Encam tune"; -"Scene.ServerPicker.Input.Placeholder" = "Rajekarekî bibîne an jî beşdarî ya xwe bibe..."; +"Scene.ServerPicker.Input.Placeholder" = "Li rajekaran bigere"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "BEŞ"; "Scene.ServerPicker.Label.Language" = "ZIMAN"; "Scene.ServerPicker.Label.Users" = "BIKARHÊNER"; "Scene.ServerPicker.Subtitle" = "Li gorî berjewendî, herêm, an jî armancek gelemperî civakekê hilbijêre."; "Scene.ServerPicker.SubtitleExtend" = "Li gorî berjewendî, herêm, an jî armancek gelemperî civakekê hilbijêre. Her civakek ji hêla rêxistinek an kesek bi tevahî serbixwe ve tê xebitandin."; -"Scene.ServerPicker.Title" = "Rajekarekê hilbijêre, -Her kîjan rajekar be."; +"Scene.ServerPicker.Title" = "Mastodon ji bikarhênerên di civakên cuda de pêk tê."; "Scene.ServerRules.Button.Confirm" = "Ez dipejirînim"; "Scene.ServerRules.PrivacyPolicy" = "polîtikaya nihêniyê"; "Scene.ServerRules.Prompt" = "Bi domandinê, tu ji bo %@ di bin mercên bikaranînê û polîtîkaya nepenîtiyê dipejirînî."; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.stringsdict index 0fa7d8214..77571439f 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ku.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld tîp + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Ji aliyê %1$@, û hevaleke hevpar tê şopandin + other + Ji aliyê %1$@, û %ld hevalên hevpar tê şopandin + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ şandî + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 medya + other + %ld medya + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings index 63586def9..cddb4be04 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.strings @@ -195,6 +195,7 @@ Uw profiel ziet er zo uit voor hen."; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Ga naar uw inbox."; "Scene.ConfirmEmail.Subtitle" = "We hebben een e-mail gestuurd naar %@, klik op de link om uw account te bevestigen."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "Nog één ding."; "Scene.Discovery.Intro" = "Dit zijn de berichten die populair zijn in jouw Mastodon-kringen."; "Scene.Discovery.Tabs.Community" = "Community"; @@ -202,9 +203,16 @@ klik op de link om uw account te bevestigen."; "Scene.Discovery.Tabs.Hashtags" = "Hashtags"; "Scene.Discovery.Tabs.News" = "Nieuws"; "Scene.Discovery.Tabs.Posts" = "Berichten"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Uw favorieten"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Volgers van andere servers worden niet weergegeven."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Volgers van andere servers worden niet weergegeven."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Bekijk nieuwe berichten"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; "Scene.HomeTimeline.NavigationBarState.Published" = "Gepubliceerd!"; @@ -246,6 +254,7 @@ klik op de link om uw account te bevestigen."; "Scene.Profile.SegmentedControl.Posts" = "Berichten"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Berichten en reacties"; "Scene.Profile.SegmentedControl.Replies" = "Reacties"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Overeenkomst"; "Scene.Register.Error.Item.Email" = "Email"; "Scene.Register.Error.Item.Locale" = "Taal"; @@ -278,6 +287,7 @@ klik op de link om uw account te bevestigen."; "Scene.Register.Input.Password.Require" = "Je wachtwoord moet ten minste:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Deze gebruikersnaam is al in gebruik."; "Scene.Register.Input.Username.Placeholder" = "gebruikersnaam"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "Vertel ons over uzelf."; "Scene.Report.Content1" = "Zijn er nog meer berichten die u aan het rapport wilt toevoegen?"; "Scene.Report.Content2" = "Is er iets anders over dit rapport dat de moderators zouden moeten weten?"; @@ -287,6 +297,38 @@ klik op de link om uw account te bevestigen."; "Scene.Report.SkipToSend" = "Verstuur zonder opmerkingen"; "Scene.Report.Step1" = "Stap 1 van 2"; "Scene.Report.Step2" = "Stap 2 van 2"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Unfollow"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; +"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; +"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; +"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; +"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; +"Scene.Report.StepOne.ItsSpam" = "It’s spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; "Scene.Report.TextPlaceholder" = "Schrijf of plak aanvullende opmerkingen"; "Scene.Report.Title" = "Rapporteer %@"; "Scene.Report.TitleReport" = "Rapporteer"; @@ -327,6 +369,7 @@ klik op de link om uw account te bevestigen."; "Scene.ServerPicker.EmptyState.FindingServers" = "Beschikbare servers zoeken..."; "Scene.ServerPicker.EmptyState.NoResults" = "Geen resultaten"; "Scene.ServerPicker.Input.Placeholder" = "Zoek uw server of sluit u bij een nieuwe server aan..."; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "CATEGORIE"; "Scene.ServerPicker.Label.Language" = "TAAL"; "Scene.ServerPicker.Label.Users" = "GEBRUIKERS"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.stringsdict index 5ae33cbef..314600ff7 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/nl.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld tekens + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ berichten + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings index 7353b6209..a9438e23d 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.strings @@ -211,6 +211,7 @@ %@. Нажмите на ссылку в нём, чтобы подтвердить свою учётную запись."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "И ещё кое-что."; "Scene.Discovery.Intro" = "These are the posts gaining traction in your corner of Mastodon."; "Scene.Discovery.Tabs.Community" = "Сообщество"; @@ -218,9 +219,16 @@ "Scene.Discovery.Tabs.Hashtags" = "Hashtags"; "Scene.Discovery.Tabs.News" = "News"; "Scene.Discovery.Tabs.Posts" = "Posts"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Ваше избранное"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Followers from other servers are not displayed."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Follows from other servers are not displayed."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Показать новые"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Не в сети"; "Scene.HomeTimeline.NavigationBarState.Published" = "Опубликовано!"; @@ -262,6 +270,7 @@ "Scene.Profile.SegmentedControl.Posts" = "Посты"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Посты и ответы"; "Scene.Profile.SegmentedControl.Replies" = "Ответы"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Соглашение"; "Scene.Register.Error.Item.Email" = "E-mail"; "Scene.Register.Error.Item.Locale" = "Язык"; @@ -294,6 +303,7 @@ "Scene.Register.Input.Password.Require" = "Your password needs at least:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Это имя пользователя занято."; "Scene.Register.Input.Username.Placeholder" = "имя пользователя"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "Расскажите нам о себе."; "Scene.Report.Content1" = "Есть ли другие сообщения, которые вы хотите добавить в отчёт?"; "Scene.Report.Content2" = "Есть ли что-то, что модераторы должны знать об этом сообщении?"; @@ -303,6 +313,38 @@ "Scene.Report.SkipToSend" = "Отправить без комментария"; "Scene.Report.Step1" = "Шаг 1 из 2"; "Scene.Report.Step2" = "Шаг 2 из 2"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Don’t want to see this?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Unfollow"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Пока мы рассматриваем его, вот действия, которые вы можете предпринять лично против %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Is there anything else we should know?"; +"Scene.Report.StepFour.Step4Of4" = "Step 4 of 4"; +"Scene.Report.StepOne.IDontLikeIt" = "I don’t like it"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "It is not something you want to see"; +"Scene.Report.StepOne.ItViolatesServerRules" = "It violates server rules"; +"Scene.Report.StepOne.ItsSomethingElse" = "It’s something else"; +"Scene.Report.StepOne.ItsSpam" = "It’s spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Select the best match"; +"Scene.Report.StepOne.Step1Of4" = "Step 1 of 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "The issue does not fit into other categories"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "What's wrong with this post?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "What's wrong with %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Are there any posts that back up this report?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepThree.Step3Of4" = "Step 3 of 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "I just don’t like it"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Select all that apply"; +"Scene.Report.StepTwo.Step2Of4" = "Step 2 of 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Which rules are being violated?"; "Scene.Report.TextPlaceholder" = "Дополнительные комментарии"; "Scene.Report.Title" = "Пожаловаться на %@"; "Scene.Report.TitleReport" = "Жалоба"; @@ -343,6 +385,7 @@ "Scene.ServerPicker.EmptyState.FindingServers" = "Ищем доступные сервера..."; "Scene.ServerPicker.EmptyState.NoResults" = "Нет результатов"; "Scene.ServerPicker.Input.Placeholder" = "Найдите сервер или присоединитесь к своему..."; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Поиск по серверам или ссылке"; "Scene.ServerPicker.Label.Category" = "КАТЕГОРИЯ"; "Scene.ServerPicker.Label.Language" = "ЯЗЫК"; "Scene.ServerPicker.Label.Users" = "ПОЛЬЗОВАТЕЛИ"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.stringsdict index 626a10d75..afb29a6aa 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/ru.lproj/Localizable.stringsdict @@ -62,6 +62,41 @@ %ld символа осталось + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + few + + many + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %1$@ и ещё %ld человек подписаны + few + %1$@ и ещё %ld человека подписаны + many + %1$@ и ещё %ld человек подписаны + other + %1$@ и ещё %ld человека подписаны + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -82,6 +117,26 @@ поста + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld медиафайл + few + %ld медиафайла + many + %ld медиафайлов + other + %ld медиафайла + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings new file mode 100644 index 000000000..7c9f2890f --- /dev/null +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.strings @@ -0,0 +1,435 @@ +"Common.Alerts.BlockDomain.BlockEntireDomain" = "Blockera domän"; +"Common.Alerts.BlockDomain.Title" = "Är du verkligen, verkligen säker på att du vill blockera hela %@? I de flesta fall är några riktade blockeringar eller nedtystade konton tillräckligt och att föredra. Du kommer inte se innehåll från den domänen och dina följare från den domänen kommer att tas bort."; +"Common.Alerts.CleanCache.Message" = "Rensade %@ cache."; +"Common.Alerts.CleanCache.Title" = "Rensa cache"; +"Common.Alerts.Common.PleaseTryAgain" = "Var god försök igen."; +"Common.Alerts.Common.PleaseTryAgainLater" = "Var god försök igen senare."; +"Common.Alerts.DeletePost.Message" = "Är du säker på att du vill radera detta inlägg?"; +"Common.Alerts.DeletePost.Title" = "Radera inlägg"; +"Common.Alerts.DiscardPostContent.Message" = "Bekräfta för att slänga inläggsutkast."; +"Common.Alerts.DiscardPostContent.Title" = "Släng utkast"; +"Common.Alerts.EditProfileFailure.Message" = "Kan inte redigera profil. Var god försök igen."; +"Common.Alerts.EditProfileFailure.Title" = "Profilredigering misslyckades"; +"Common.Alerts.PublishPostFailure.AttachmentsMessage.MoreThanOneVideo" = "Det går inte att bifoga mer än en video."; +"Common.Alerts.PublishPostFailure.AttachmentsMessage.VideoAttachWithPhoto" = "Det går inte att bifoga en video till ett inlägg som redan innehåller bilder."; +"Common.Alerts.PublishPostFailure.Message" = "Det gick inte att publicera inlägget. +Kontrollera din internetanslutning."; +"Common.Alerts.PublishPostFailure.Title" = "Publicering misslyckades"; +"Common.Alerts.SavePhotoFailure.Message" = "Aktivera åtkomst till Bilder för att spara bilden."; +"Common.Alerts.SavePhotoFailure.Title" = "Spara foto misslyckades"; +"Common.Alerts.ServerError.Title" = "Serverfel"; +"Common.Alerts.SignOut.Confirm" = "Logga ut"; +"Common.Alerts.SignOut.Message" = "Är du säker på att du vill logga ut?"; +"Common.Alerts.SignOut.Title" = "Logga ut"; +"Common.Alerts.SignUpFailure.Title" = "Registrering misslyckades"; +"Common.Alerts.VoteFailure.PollEnded" = "Omröstningen har avslutats"; +"Common.Alerts.VoteFailure.Title" = "Röstning misslyckades"; +"Common.Controls.Actions.Add" = "Lägg till"; +"Common.Controls.Actions.Back" = "Tillbaka"; +"Common.Controls.Actions.BlockDomain" = "Blockera %@"; +"Common.Controls.Actions.Cancel" = "Avbryt"; +"Common.Controls.Actions.Compose" = "Skriv"; +"Common.Controls.Actions.Confirm" = "Bekräfta"; +"Common.Controls.Actions.Continue" = "Fortsätt"; +"Common.Controls.Actions.CopyPhoto" = "Kopiera foto"; +"Common.Controls.Actions.Delete" = "Radera"; +"Common.Controls.Actions.Discard" = "Släng"; +"Common.Controls.Actions.Done" = "Klar"; +"Common.Controls.Actions.Edit" = "Redigera"; +"Common.Controls.Actions.FindPeople" = "Hitta personer att följa"; +"Common.Controls.Actions.ManuallySearch" = "Sök manuellt istället"; +"Common.Controls.Actions.Next" = "Nästa"; +"Common.Controls.Actions.Ok" = "OK"; +"Common.Controls.Actions.Open" = "Öppna"; +"Common.Controls.Actions.OpenInBrowser" = "Öppna i webbläsare"; +"Common.Controls.Actions.OpenInSafari" = "Öppna i Safari"; +"Common.Controls.Actions.Preview" = "Förhandsvisa"; +"Common.Controls.Actions.Previous" = "Föregående"; +"Common.Controls.Actions.Remove" = "Radera"; +"Common.Controls.Actions.Reply" = "Svara"; +"Common.Controls.Actions.ReportUser" = "Rapportera %@"; +"Common.Controls.Actions.Save" = "Spara"; +"Common.Controls.Actions.SavePhoto" = "Spara foto"; +"Common.Controls.Actions.SeeMore" = "Visa mer"; +"Common.Controls.Actions.Settings" = "Inställningar"; +"Common.Controls.Actions.Share" = "Dela"; +"Common.Controls.Actions.SharePost" = "Dela inlägg"; +"Common.Controls.Actions.ShareUser" = "Dela %@"; +"Common.Controls.Actions.SignIn" = "Logga in"; +"Common.Controls.Actions.SignUp" = "Registrera dig"; +"Common.Controls.Actions.Skip" = "Hoppa över"; +"Common.Controls.Actions.TakePhoto" = "Ta foto"; +"Common.Controls.Actions.TryAgain" = "Försök igen"; +"Common.Controls.Actions.UnblockDomain" = "Avblockera %@"; +"Common.Controls.Friendship.Block" = "Blockera"; +"Common.Controls.Friendship.BlockDomain" = "Blockera %@"; +"Common.Controls.Friendship.BlockUser" = "Blockera %@"; +"Common.Controls.Friendship.Blocked" = "Blockerad"; +"Common.Controls.Friendship.EditInfo" = "Redigera info"; +"Common.Controls.Friendship.Follow" = "Följ"; +"Common.Controls.Friendship.Following" = "Följer"; +"Common.Controls.Friendship.Mute" = "Tysta"; +"Common.Controls.Friendship.MuteUser" = "Tysta %@"; +"Common.Controls.Friendship.Muted" = "Tystad"; +"Common.Controls.Friendship.Pending" = "Väntande"; +"Common.Controls.Friendship.Request" = "Följ"; +"Common.Controls.Friendship.Unblock" = "Avblockera"; +"Common.Controls.Friendship.UnblockUser" = "Avblockera %@"; +"Common.Controls.Friendship.Unmute" = "Avtysta"; +"Common.Controls.Friendship.UnmuteUser" = "Avtysta %@"; +"Common.Controls.Keyboard.Common.ComposeNewPost" = "Skriv nytt inlägg"; +"Common.Controls.Keyboard.Common.OpenSettings" = "Öppna inställningar"; +"Common.Controls.Keyboard.Common.ShowFavorites" = "Visa favoriter"; +"Common.Controls.Keyboard.Common.SwitchToTab" = "Växla till %@"; +"Common.Controls.Keyboard.SegmentedControl.NextSection" = "Nästa avsnitt"; +"Common.Controls.Keyboard.SegmentedControl.PreviousSection" = "Föregående avsnitt"; +"Common.Controls.Keyboard.Timeline.NextStatus" = "Nästa inlägg"; +"Common.Controls.Keyboard.Timeline.OpenAuthorProfile" = "Öppna författarens profil"; +"Common.Controls.Keyboard.Timeline.OpenRebloggerProfile" = "Öppna ompostarens profil"; +"Common.Controls.Keyboard.Timeline.OpenStatus" = "Öppna inlägg"; +"Common.Controls.Keyboard.Timeline.PreviewImage" = "Förhandsgranska bild"; +"Common.Controls.Keyboard.Timeline.PreviousStatus" = "Föregående inlägg"; +"Common.Controls.Keyboard.Timeline.ReplyStatus" = "Svara på inlägg"; +"Common.Controls.Keyboard.Timeline.ToggleContentWarning" = "Växla innehållsvarning"; +"Common.Controls.Keyboard.Timeline.ToggleFavorite" = "Växla favorit på inlägg"; +"Common.Controls.Keyboard.Timeline.ToggleReblog" = "Växla ompostning på inlägg"; +"Common.Controls.Status.Actions.Favorite" = "Favorit"; +"Common.Controls.Status.Actions.Hide" = "Dölj"; +"Common.Controls.Status.Actions.Menu" = "Meny"; +"Common.Controls.Status.Actions.Reblog" = "Omposta"; +"Common.Controls.Status.Actions.Reply" = "Svara"; +"Common.Controls.Status.Actions.ShowGif" = "Visa GIF"; +"Common.Controls.Status.Actions.ShowImage" = "Visa bild"; +"Common.Controls.Status.Actions.ShowVideoPlayer" = "Visa videospelare"; +"Common.Controls.Status.Actions.TapThenHoldToShowMenu" = "Tryck och håll ned för att visa menyn"; +"Common.Controls.Status.Actions.Unfavorite" = "Ta bort favorit"; +"Common.Controls.Status.Actions.Unreblog" = "Ångra ompostning"; +"Common.Controls.Status.ContentWarning" = "Innehållsvarning"; +"Common.Controls.Status.MediaContentWarning" = "Tryck var som helst för att visa"; +"Common.Controls.Status.Poll.Closed" = "Stängd"; +"Common.Controls.Status.Poll.Vote" = "Rösta"; +"Common.Controls.Status.SensitiveContent" = "Känsligt innehåll"; +"Common.Controls.Status.ShowPost" = "Visa inlägg"; +"Common.Controls.Status.ShowUserProfile" = "Visa användarprofil"; +"Common.Controls.Status.Tag.Email" = "E-post"; +"Common.Controls.Status.Tag.Emoji" = "Emoji"; +"Common.Controls.Status.Tag.Hashtag" = "Hashtagg"; +"Common.Controls.Status.Tag.Link" = "Länk"; +"Common.Controls.Status.Tag.Mention" = "Omnämn"; +"Common.Controls.Status.Tag.Url" = "URL"; +"Common.Controls.Status.TapToReveal" = "Tryck för att visa"; +"Common.Controls.Status.UserReblogged" = "%@ ompostade"; +"Common.Controls.Status.UserRepliedTo" = "Svarade på %@"; +"Common.Controls.Status.Visibility.Direct" = "Endast omnämnda användare kan se detta inlägg."; +"Common.Controls.Status.Visibility.Private" = "Endast deras följare kan se detta inlägg."; +"Common.Controls.Status.Visibility.PrivateFromMe" = "Bara mina följare kan se det här inlägget."; +"Common.Controls.Status.Visibility.Unlisted" = "Alla kan se detta inlägg men det visas inte i den offentliga tidslinjen."; +"Common.Controls.Tabs.Home" = "Hem"; +"Common.Controls.Tabs.Notification" = "Notis"; +"Common.Controls.Tabs.Profile" = "Profil"; +"Common.Controls.Tabs.Search" = "Sök"; +"Common.Controls.Timeline.Filtered" = "Filtrerat"; +"Common.Controls.Timeline.Header.BlockedWarning" = "Du kan inte visa den här användarens profil +förrän de avblockerar dig."; +"Common.Controls.Timeline.Header.BlockingWarning" = "Du kan inte visa användarens profil +förrän du avblockerar dem. +Din profil ser ut så här för dem."; +"Common.Controls.Timeline.Header.NoStatusFound" = "Inga inlägg hittades"; +"Common.Controls.Timeline.Header.SuspendedWarning" = "Denna användare har blivit avstängd."; +"Common.Controls.Timeline.Header.UserBlockedWarning" = "Du kan inte visa %@s profil +förrän de avblockerar dig."; +"Common.Controls.Timeline.Header.UserBlockingWarning" = "Du kan inte visa %@s profil +förrän du avblockerar dem. +Din profil ser ut så här för dem."; +"Common.Controls.Timeline.Header.UserSuspendedWarning" = "%@s konto har blivit avstängt."; +"Common.Controls.Timeline.Loader.LoadMissingPosts" = "Ladda saknade inlägg"; +"Common.Controls.Timeline.Loader.LoadingMissingPosts" = "Laddar saknade inlägg..."; +"Common.Controls.Timeline.Loader.ShowMoreReplies" = "Visa fler svar"; +"Common.Controls.Timeline.Timestamp.Now" = "Nu"; +"Scene.AccountList.AddAccount" = "Lägg till konto"; +"Scene.AccountList.DismissAccountSwitcher" = "Stäng kontoväxlare"; +"Scene.AccountList.TabBarHint" = "Nuvarande vald profil: %@. Dubbeltryck och håll för att visa kontoväxlare"; +"Scene.Compose.Accessibility.AppendAttachment" = "Lägg till bilaga"; +"Scene.Compose.Accessibility.AppendPoll" = "Lägg till omröstning"; +"Scene.Compose.Accessibility.CustomEmojiPicker" = "Anpassad emoji-väljare"; +"Scene.Compose.Accessibility.DisableContentWarning" = "Inaktivera innehållsvarning"; +"Scene.Compose.Accessibility.EnableContentWarning" = "Aktivera innehållsvarning"; +"Scene.Compose.Accessibility.PostVisibilityMenu" = "Inläggssynlighetsmeny"; +"Scene.Compose.Accessibility.RemovePoll" = "Ta bort omröstning"; +"Scene.Compose.Attachment.AttachmentBroken" = "Denna %@ är trasig och kan inte +laddas upp till Mastodon."; +"Scene.Compose.Attachment.DescriptionPhoto" = "Beskriv fotot för synskadade..."; +"Scene.Compose.Attachment.DescriptionVideo" = "Beskriv videon för de synskadade..."; +"Scene.Compose.Attachment.Photo" = "foto"; +"Scene.Compose.Attachment.Video" = "video"; +"Scene.Compose.AutoComplete.SpaceToAdd" = "Mellanslag för att lägga till"; +"Scene.Compose.ComposeAction" = "Publicera"; +"Scene.Compose.ContentInputPlaceholder" = "Skriv eller klistra in vad du har på hjärtat"; +"Scene.Compose.ContentWarning.Placeholder" = "Skriv en noggrann varning här..."; +"Scene.Compose.Keyboard.AppendAttachmentEntry" = "Lägg till bilaga - %@"; +"Scene.Compose.Keyboard.DiscardPost" = "Släng inlägget"; +"Scene.Compose.Keyboard.PublishPost" = "Publicera inlägget"; +"Scene.Compose.Keyboard.SelectVisibilityEntry" = "Välj synlighet - %@"; +"Scene.Compose.Keyboard.ToggleContentWarning" = "Växla innehållsvarning"; +"Scene.Compose.Keyboard.TogglePoll" = "Växla omröstning"; +"Scene.Compose.MediaSelection.Browse" = "Bläddra"; +"Scene.Compose.MediaSelection.Camera" = "Ta foto"; +"Scene.Compose.MediaSelection.PhotoLibrary" = "Fotobibliotek"; +"Scene.Compose.Poll.DurationTime" = "Längd: %@"; +"Scene.Compose.Poll.OneDay" = "1 dag"; +"Scene.Compose.Poll.OneHour" = "1 timme"; +"Scene.Compose.Poll.OptionNumber" = "Alternativ %ld"; +"Scene.Compose.Poll.SevenDays" = "7 dagar"; +"Scene.Compose.Poll.SixHours" = "6 timmar"; +"Scene.Compose.Poll.ThirtyMinutes" = "30 minuter"; +"Scene.Compose.Poll.ThreeDays" = "3 dagar"; +"Scene.Compose.ReplyingToUser" = "svarar %@"; +"Scene.Compose.Title.NewPost" = "Nytt inlägg"; +"Scene.Compose.Title.NewReply" = "Nytt svar"; +"Scene.Compose.Visibility.Direct" = "Bara personer jag nämner"; +"Scene.Compose.Visibility.Private" = "Endast följare"; +"Scene.Compose.Visibility.Public" = "Offentlig"; +"Scene.Compose.Visibility.Unlisted" = "Olistad"; +"Scene.ConfirmEmail.Button.OpenEmailApp" = "Öppna e-postappen"; +"Scene.ConfirmEmail.Button.Resend" = "Skicka igen"; +"Scene.ConfirmEmail.DontReceiveEmail.Description" = "Kontrollera om din e-postadress är korrekt samt din skräppostmapp om du inte har gjort det."; +"Scene.ConfirmEmail.DontReceiveEmail.ResendEmail" = "Skicka e-postmeddelande igen"; +"Scene.ConfirmEmail.DontReceiveEmail.Title" = "Kolla din e-post"; +"Scene.ConfirmEmail.OpenEmailApp.Description" = "Vi har precis skickat ett e-postmeddelande till dig. Kontrollera din skräpmapp om du inte har gjort det."; +"Scene.ConfirmEmail.OpenEmailApp.Mail" = "E-post"; +"Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Öppna e-postklient"; +"Scene.ConfirmEmail.OpenEmailApp.Title" = "Kolla din inkorg."; +"Scene.ConfirmEmail.Subtitle" = "Tryck på länken vi e-postade till dig för att verifiera ditt konto."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tryck på länken vi e-postade till dig för att verifiera ditt konto"; +"Scene.ConfirmEmail.Title" = "En sista sak."; +"Scene.Discovery.Intro" = "Detta är de inlägg som engagerar i ditt hörn av Mastodon."; +"Scene.Discovery.Tabs.Community" = "Server"; +"Scene.Discovery.Tabs.ForYou" = "För dig"; +"Scene.Discovery.Tabs.Hashtags" = "Hashtaggar"; +"Scene.Discovery.Tabs.News" = "Nyheter"; +"Scene.Discovery.Tabs.Posts" = "Inlägg"; +"Scene.Familiarfollowers.FollowedByNames" = "Följs av %@"; +"Scene.Familiarfollowers.Title" = "Följare du liknar"; +"Scene.Favorite.Title" = "Dina favoriter"; +"Scene.FavoritedBy.Title" = "Favoriserad av"; +"Scene.Follower.Footer" = "Följare från andra servrar visas inte."; +"Scene.Follower.Title" = "följare"; +"Scene.Following.Footer" = "Följda på andra servrar visas inte."; +"Scene.Following.Title" = "följer"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tryck för att bläddra till toppen och tryck igen för föregående plats"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo-knapp"; +"Scene.HomeTimeline.NavigationBarState.NewPosts" = "Nya inlägg"; +"Scene.HomeTimeline.NavigationBarState.Offline" = "Offline"; +"Scene.HomeTimeline.NavigationBarState.Published" = "Publicerat!"; +"Scene.HomeTimeline.NavigationBarState.Publishing" = "Publicerar inlägget..."; +"Scene.HomeTimeline.Title" = "Hem"; +"Scene.Notification.Keyobard.ShowEverything" = "Visa allt"; +"Scene.Notification.Keyobard.ShowMentions" = "Visa omnämningar"; +"Scene.Notification.NotificationDescription.FavoritedYourPost" = "favoriserade ditt inlägg"; +"Scene.Notification.NotificationDescription.FollowedYou" = "följde dig"; +"Scene.Notification.NotificationDescription.MentionedYou" = "nämnde dig"; +"Scene.Notification.NotificationDescription.PollHasEnded" = "omröstningen har avslutats"; +"Scene.Notification.NotificationDescription.RebloggedYourPost" = "ompostade ditt inlägg"; +"Scene.Notification.NotificationDescription.RequestToFollowYou" = "begär att följa dig"; +"Scene.Notification.Title.Everything" = "Allting"; +"Scene.Notification.Title.Mentions" = "Omnämningar"; +"Scene.Preview.Keyboard.ClosePreview" = "Stäng förhandsvisning"; +"Scene.Preview.Keyboard.ShowNext" = "Visa nästa"; +"Scene.Preview.Keyboard.ShowPrevious" = "Visa föregående"; +"Scene.Profile.Accessibility.DoubleTapToOpenTheList" = "Dubbeltryck för att öppna listan"; +"Scene.Profile.Accessibility.EditAvatarImage" = "Redigera profilbild"; +"Scene.Profile.Accessibility.ShowAvatarImage" = "Visa profilbild"; +"Scene.Profile.Accessibility.ShowBannerImage" = "Visa banner"; +"Scene.Profile.Dashboard.Followers" = "följare"; +"Scene.Profile.Dashboard.Following" = "följer"; +"Scene.Profile.Dashboard.Posts" = "inlägg"; +"Scene.Profile.Fields.AddRow" = "Lägg till rad"; +"Scene.Profile.Fields.Placeholder.Content" = "Innehåll"; +"Scene.Profile.Fields.Placeholder.Label" = "Etikett"; +"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Bekräfta för att blockera %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Blockera konto"; +"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Bekräfta för att tysta %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Title" = "Tysta konto"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Message" = "Bekräfta för att avblockera %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.Title" = "Avblockera konto"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Message" = "Bekräfta för att avtysta %@"; +"Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.Title" = "Avtysta konto"; +"Scene.Profile.SegmentedControl.About" = "Om"; +"Scene.Profile.SegmentedControl.Media" = "Media"; +"Scene.Profile.SegmentedControl.Posts" = "Inlägg"; +"Scene.Profile.SegmentedControl.PostsAndReplies" = "Inlägg och svar"; +"Scene.Profile.SegmentedControl.Replies" = "Svar"; +"Scene.RebloggedBy.Title" = "Ompostat av"; +"Scene.Register.Error.Item.Agreement" = "Avtal"; +"Scene.Register.Error.Item.Email" = "E-post"; +"Scene.Register.Error.Item.Locale" = "Språk"; +"Scene.Register.Error.Item.Password" = "Lösenord"; +"Scene.Register.Error.Item.Reason" = "Anledning"; +"Scene.Register.Error.Item.Username" = "Användarnamn"; +"Scene.Register.Error.Reason.Accepted" = "%@ måste godkännas"; +"Scene.Register.Error.Reason.Blank" = "%@ krävs"; +"Scene.Register.Error.Reason.Blocked" = "%@ innehåller en icke tillåten e-postleverantör"; +"Scene.Register.Error.Reason.Inclusion" = "%@ är inte ett värde som stöds"; +"Scene.Register.Error.Reason.Invalid" = "%@ är ogiltig"; +"Scene.Register.Error.Reason.Reserved" = "%@ är ett reserverat nyckelord"; +"Scene.Register.Error.Reason.Taken" = "%@ används redan"; +"Scene.Register.Error.Reason.TooLong" = "%@ är för långt"; +"Scene.Register.Error.Reason.TooShort" = "%@ är för kort"; +"Scene.Register.Error.Reason.Unreachable" = "%@ verkar inte existera"; +"Scene.Register.Error.Special.EmailInvalid" = "Detta är inte en giltig e-postadress"; +"Scene.Register.Error.Special.PasswordTooShort" = "Lösenordet är för kort (det måste vara minst 8 tecken)"; +"Scene.Register.Error.Special.UsernameInvalid" = "Användarnamnet kan bara innehålla alfanumeriska tecken och understreck"; +"Scene.Register.Error.Special.UsernameTooLong" = "Användarnamnet är för långt (kan inte vara längre än 30 tecken)"; +"Scene.Register.Input.Avatar.Delete" = "Radera"; +"Scene.Register.Input.DisplayName.Placeholder" = "visningsnamn"; +"Scene.Register.Input.Email.Placeholder" = "e-post"; +"Scene.Register.Input.Invite.RegistrationUserInviteRequest" = "Varför vill du gå med?"; +"Scene.Register.Input.Password.Accessibility.Checked" = "markerad"; +"Scene.Register.Input.Password.Accessibility.Unchecked" = "avmarkerad"; +"Scene.Register.Input.Password.CharacterLimit" = "8 tecken"; +"Scene.Register.Input.Password.Hint" = "Ditt lösenord måste bestå av minst 8 tecken"; +"Scene.Register.Input.Password.Placeholder" = "lösenord"; +"Scene.Register.Input.Password.Require" = "Ditt lösenord behöver minst:"; +"Scene.Register.Input.Username.DuplicatePrompt" = "Det här användarnamnet är redan taget."; +"Scene.Register.Input.Username.Placeholder" = "användarnamn"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Låt oss få igång dig på %@"; +"Scene.Register.Title" = "Låt oss få igång dig på %@"; +"Scene.Report.Content1" = "Finns det några andra inlägg du vill lägga till i rapporten?"; +"Scene.Report.Content2" = "Finns det något som moderatorerna borde känna till om denna rapport?"; +"Scene.Report.ReportSentTitle" = "Tack för din rapport, vi ska titta på det."; +"Scene.Report.Reported" = "RAPPORTERAD"; +"Scene.Report.Send" = "Skicka rapport"; +"Scene.Report.SkipToSend" = "Skicka utan kommentar"; +"Scene.Report.Step1" = "Steg 1 av 2"; +"Scene.Report.Step2" = "Steg 2 av 2"; +"Scene.Report.StepFinal.BlockUser" = "Blockera %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Vill du inte se det här?"; +"Scene.Report.StepFinal.MuteUser" = "Tysta %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "De kommer inte längre att kunna följa eller se dina inlägg, men de kan se om de har blockerats."; +"Scene.Report.StepFinal.Unfollow" = "Avfölj"; +"Scene.Report.StepFinal.UnfollowUser" = "Avfölj %@"; +"Scene.Report.StepFinal.Unfollowed" = "Slutade följa"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "När du ser något som du inte gillar på Mastodon kan du ta bort personen från din upplevelse."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Medan vi granskar detta kan du vidta åtgärder mot %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "Du kommer inte att se deras inlägg eller ompostningar i ditt hemflöde. De kommer inte att veta att de har blivit tystade."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Finns det något annat vi borde veta?"; +"Scene.Report.StepFour.Step4Of4" = "Steg 4 av 4"; +"Scene.Report.StepOne.IDontLikeIt" = "Jag tycker inte om det"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "Det är inget som du vill se"; +"Scene.Report.StepOne.ItViolatesServerRules" = "Det bryter mot serverns regler"; +"Scene.Report.StepOne.ItsSomethingElse" = "Det är något annat"; +"Scene.Report.StepOne.ItsSpam" = "Det är skräppost"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Skadliga länkar, bedrägligt beteende eller repetitiva svar"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Välj den bästa träffen"; +"Scene.Report.StepOne.Step1Of4" = "Steg 1 av 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "Frågan passar inte in i andra kategorier"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Vad är fel med det här kontot?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Vad är fel med det här inlägget?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Vad är fel med %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Du är medveten om att det bryter mot specifika regler"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Finns det några inlägg som stöder denna rapport?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Välj allt som stämmer"; +"Scene.Report.StepThree.Step3Of4" = "Steg 3 av 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "Jag tycker bara inte om det"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Välj allt som stämmer"; +"Scene.Report.StepTwo.Step2Of4" = "Steg 2 av 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Vilka regler överträds?"; +"Scene.Report.TextPlaceholder" = "Skriv eller klistra in ytterligare kommentarer"; +"Scene.Report.Title" = "Rapportera %@"; +"Scene.Report.TitleReport" = "Rapportera"; +"Scene.Search.Recommend.Accounts.Description" = "Du kanske vill följa dessa konton"; +"Scene.Search.Recommend.Accounts.Follow" = "Följ"; +"Scene.Search.Recommend.Accounts.Title" = "Konton som du kanske gillar"; +"Scene.Search.Recommend.ButtonText" = "Visa alla"; +"Scene.Search.Recommend.HashTag.Description" = "Hashtaggar som får en hel del uppmärksamhet"; +"Scene.Search.Recommend.HashTag.PeopleTalking" = "%@ personer diskuterar"; +"Scene.Search.Recommend.HashTag.Title" = "Trendar på Mastodon"; +"Scene.Search.SearchBar.Cancel" = "Avbryt"; +"Scene.Search.SearchBar.Placeholder" = "Sök hashtaggar och användare"; +"Scene.Search.Searching.Clear" = "Rensa"; +"Scene.Search.Searching.EmptyState.NoResults" = "Inga resultat"; +"Scene.Search.Searching.RecentSearch" = "Senaste sökningarna"; +"Scene.Search.Searching.Segment.All" = "Allt"; +"Scene.Search.Searching.Segment.Hashtags" = "Hashtaggar"; +"Scene.Search.Searching.Segment.People" = "Personer"; +"Scene.Search.Searching.Segment.Posts" = "Inlägg"; +"Scene.Search.Title" = "Sök"; +"Scene.ServerPicker.Button.Category.Academia" = "vetenskap"; +"Scene.ServerPicker.Button.Category.Activism" = "aktivism"; +"Scene.ServerPicker.Button.Category.All" = "Alla"; +"Scene.ServerPicker.Button.Category.AllAccessiblityDescription" = "Kategori: Alla"; +"Scene.ServerPicker.Button.Category.Art" = "konst"; +"Scene.ServerPicker.Button.Category.Food" = "mat"; +"Scene.ServerPicker.Button.Category.Furry" = "furry"; +"Scene.ServerPicker.Button.Category.Games" = "spel"; +"Scene.ServerPicker.Button.Category.General" = "allmänt"; +"Scene.ServerPicker.Button.Category.Journalism" = "journalistik"; +"Scene.ServerPicker.Button.Category.Lgbt" = "lgbt"; +"Scene.ServerPicker.Button.Category.Music" = "musik"; +"Scene.ServerPicker.Button.Category.Regional" = "regionalt"; +"Scene.ServerPicker.Button.Category.Tech" = "teknik"; +"Scene.ServerPicker.Button.SeeLess" = "Visa mindre"; +"Scene.ServerPicker.Button.SeeMore" = "Visa mer"; +"Scene.ServerPicker.EmptyState.BadNetwork" = "Något gick fel när data laddades. Försök igen eller kontrollera din internetanslutning."; +"Scene.ServerPicker.EmptyState.FindingServers" = "Söker tillgängliga servrar..."; +"Scene.ServerPicker.EmptyState.NoResults" = "Inga resultat"; +"Scene.ServerPicker.Input.Placeholder" = "Sök gemenskaper"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Sök servrar eller ange URL"; +"Scene.ServerPicker.Label.Category" = "KATEGORI"; +"Scene.ServerPicker.Label.Language" = "SPRÅK"; +"Scene.ServerPicker.Label.Users" = "ANVÄNDARE"; +"Scene.ServerPicker.Subtitle" = "Välj en server baserat på dina intressen, region eller ett allmänt syfte."; +"Scene.ServerPicker.SubtitleExtend" = "Välj en server baserat på dina intressen, region eller ett allmänt syfte. Varje server drivs av en helt oberoende organisation eller individ."; +"Scene.ServerPicker.Title" = "Mastodon utgörs av användare på olika servrar."; +"Scene.ServerRules.Button.Confirm" = "Jag godkänner"; +"Scene.ServerRules.PrivacyPolicy" = "integritetspolicy"; +"Scene.ServerRules.Prompt" = "Genom att fortsätta omfattas du av villkoren för tjänsten och sekretesspolicyn för %@."; +"Scene.ServerRules.Subtitle" = "Dessa sätts och verkställs av moderatorerna på %@."; +"Scene.ServerRules.TermsOfService" = "användarvillkor"; +"Scene.ServerRules.Title" = "Några grundregler."; +"Scene.Settings.Footer.MastodonDescription" = "Mastodon är programvara med öppen källkod. Du kan rapportera problem via GitHub på %@ (%@)"; +"Scene.Settings.Keyboard.CloseSettingsWindow" = "Stäng inställningsfönstret"; +"Scene.Settings.Section.Appearance.Automatic" = "Automatisk"; +"Scene.Settings.Section.Appearance.Dark" = "Alltid mörk"; +"Scene.Settings.Section.Appearance.Light" = "Alltid ljus"; +"Scene.Settings.Section.Appearance.Title" = "Utseende"; +"Scene.Settings.Section.BoringZone.AccountSettings" = "Kontoinställningar"; +"Scene.Settings.Section.BoringZone.Privacy" = "Integritetspolicy"; +"Scene.Settings.Section.BoringZone.Terms" = "Användarvillkor"; +"Scene.Settings.Section.BoringZone.Title" = "Den tråkiga zonen"; +"Scene.Settings.Section.LookAndFeel.Light" = "Ljust"; +"Scene.Settings.Section.LookAndFeel.ReallyDark" = "Verkligen mörk"; +"Scene.Settings.Section.LookAndFeel.SortaDark" = "Ganska mörk"; +"Scene.Settings.Section.LookAndFeel.Title" = "Utseende och känsla"; +"Scene.Settings.Section.LookAndFeel.UseSystem" = "Följ systeminställningarna"; +"Scene.Settings.Section.Notifications.Boosts" = "Ompostar mitt inlägg"; +"Scene.Settings.Section.Notifications.Favorites" = "Favoriserar mitt inlägg"; +"Scene.Settings.Section.Notifications.Follows" = "Följer mig"; +"Scene.Settings.Section.Notifications.Mentions" = "Omnämner mig"; +"Scene.Settings.Section.Notifications.Title" = "Notiser"; +"Scene.Settings.Section.Notifications.Trigger.Anyone" = "alla"; +"Scene.Settings.Section.Notifications.Trigger.Follow" = "någon jag följer"; +"Scene.Settings.Section.Notifications.Trigger.Follower" = "en följare"; +"Scene.Settings.Section.Notifications.Trigger.Noone" = "ingen"; +"Scene.Settings.Section.Notifications.Trigger.Title" = "Meddela mig när"; +"Scene.Settings.Section.Preference.DisableAvatarAnimation" = "Inaktivera animerade avatarer"; +"Scene.Settings.Section.Preference.DisableEmojiAnimation" = "Inaktivera animerade emojis"; +"Scene.Settings.Section.Preference.OpenLinksInMastodon" = "Öppna länkar i Mastodon"; +"Scene.Settings.Section.Preference.Title" = "Inställningar"; +"Scene.Settings.Section.Preference.TrueBlackDarkMode" = "True black-mörkt läge"; +"Scene.Settings.Section.Preference.UsingDefaultBrowser" = "Använd standardwebbläsare för att öppna länkar"; +"Scene.Settings.Section.SpicyZone.Clear" = "Rensa mediacache"; +"Scene.Settings.Section.SpicyZone.Signout" = "Logga ut"; +"Scene.Settings.Section.SpicyZone.Title" = "Den spännande zonen"; +"Scene.Settings.Title" = "Inställningar"; +"Scene.SuggestionAccount.FollowExplain" = "När du följer någon, kommer du att se deras inlägg i ditt hemflöde."; +"Scene.SuggestionAccount.Title" = "Hitta personer att följa"; +"Scene.Thread.BackTitle" = "Inlägg"; +"Scene.Thread.Title" = "Inlägg från %@"; +"Scene.Welcome.GetStarted" = "Kom igång"; +"Scene.Welcome.LogIn" = "Logga in"; +"Scene.Welcome.Slogan" = "Socialt nätverkande +tillbaka i dina händer."; +"Scene.Wizard.AccessibilityHint" = "Dubbeltryck för att avvisa den här guiden"; +"Scene.Wizard.MultipleAccountSwitchIntroDescription" = "Växla mellan flera konton genom att hålla inne profilknappen."; +"Scene.Wizard.NewInMastodon" = "Nytt i Mastodon"; \ No newline at end of file diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.stringsdict new file mode 100644 index 000000000..27ef9fb53 --- /dev/null +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/sv.lproj/Localizable.stringsdict @@ -0,0 +1,449 @@ + + + + + a11y.plural.count.unread.notification + + NSStringLocalizedFormatKey + %#@notification_count_unread_notification@ + notification_count_unread_notification + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 oläst notis + other + %ld olästa notiser + + + a11y.plural.count.input_limit_exceeds + + NSStringLocalizedFormatKey + Inmatningsgränsen överskrider %#@character_count@ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 tecken + other + %ld tecken + + + a11y.plural.count.input_limit_remains + + NSStringLocalizedFormatKey + Inmatningsgränsen återstår %#@character_count@ + character_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 tecken + other + %ld tecken + + + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Följs av %1$@ och en annan gemensam + other + Följs av %1$@ och %ld gemensamma + + + plural.count.metric_formatted.post + + NSStringLocalizedFormatKey + %@ %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + inlägg + other + inläggen + + + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld media + other + %ld media + + + plural.count.post + + NSStringLocalizedFormatKey + %#@post_count@ + post_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 inlägg + other + %ld inlägg + + + plural.count.favorite + + NSStringLocalizedFormatKey + %#@favorite_count@ + favorite_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 favorit + other + %ld favoriter + + + plural.count.reblog + + NSStringLocalizedFormatKey + %#@reblog_count@ + reblog_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld ompostning + other + %ld ompostningar + + + plural.count.reply + + NSStringLocalizedFormatKey + %#@reply_count@ + reply_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 svar + other + %ld svar + + + plural.count.vote + + NSStringLocalizedFormatKey + %#@vote_count@ + vote_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 röst + other + %ld röster + + + plural.count.voter + + NSStringLocalizedFormatKey + %#@voter_count@ + voter_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld röstare + other + %ld röster + + + plural.people_talking + + NSStringLocalizedFormatKey + %#@count_people_talking@ + count_people_talking + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld person diskuterar + other + %ld personer diskuterar + + + plural.count.following + + NSStringLocalizedFormatKey + %#@count_following@ + count_following + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld följer + other + %ld följer + + + plural.count.follower + + NSStringLocalizedFormatKey + %#@count_follower@ + count_follower + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 följare + other + %ld följare + + + date.year.left + + NSStringLocalizedFormatKey + %#@count_year_left@ + count_year_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld år kvar + other + %ld år kvar + + + date.month.left + + NSStringLocalizedFormatKey + %#@count_month_left@ + count_month_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld månad kvar + other + %ld månader kvar + + + date.day.left + + NSStringLocalizedFormatKey + %#@count_day_left@ + count_day_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld dag kvar + other + %ld dagar kvar + + + date.hour.left + + NSStringLocalizedFormatKey + %#@count_hour_left@ + count_hour_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld timme kvar + other + %ld timmar kvar + + + date.minute.left + + NSStringLocalizedFormatKey + %#@count_minute_left@ + count_minute_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld minut kvar + other + %ld minuter kvar + + + date.second.left + + NSStringLocalizedFormatKey + %#@count_second_left@ + count_second_left + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld sekund kvar + other + %ld sekunder kvar + + + date.year.ago.abbr + + NSStringLocalizedFormatKey + %#@count_year_ago_abbr@ + count_year_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld år sedan + other + %ldå sedan + + + date.month.ago.abbr + + NSStringLocalizedFormatKey + %#@count_month_ago_abbr@ + count_month_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld mån sedan + other + %ld mån sedan + + + date.day.ago.abbr + + NSStringLocalizedFormatKey + %#@count_day_ago_abbr@ + count_day_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ldd sedan + other + %ldd sedan + + + date.hour.ago.abbr + + NSStringLocalizedFormatKey + %#@count_hour_ago_abbr@ + count_hour_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ldt sedan + other + %ldt sedan + + + date.minute.ago.abbr + + NSStringLocalizedFormatKey + %#@count_minute_ago_abbr@ + count_minute_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %ld min sedan + other + %ld min sedan + + + date.second.ago.abbr + + NSStringLocalizedFormatKey + %#@count_second_ago_abbr@ + count_second_ago_abbr + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + %lds sedan + other + %lds sedan + + + + diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings index 1ceff03a2..9ae1abc81 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.strings @@ -200,16 +200,24 @@ "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "เปิดไคลเอ็นต์อีเมล"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "ตรวจสอบกล่องขาเข้าของคุณ"; "Scene.ConfirmEmail.Subtitle" = "แตะลิงก์ที่เราส่งอีเมลถึงคุณเพื่อยืนยันบัญชีของคุณ"; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "แตะลิงก์ที่เราส่งอีเมลถึงคุณเพื่อยืนยันบัญชีของคุณ"; "Scene.ConfirmEmail.Title" = "หนึ่งสิ่งสุดท้าย"; "Scene.Discovery.Intro" = "นี่คือโพสต์ที่กำลังได้รับความสนใจในมุมของ Mastodon ของคุณ"; -"Scene.Discovery.Tabs.Community" = "Community"; +"Scene.Discovery.Tabs.Community" = "ชุมชน"; "Scene.Discovery.Tabs.ForYou" = "สำหรับคุณ"; "Scene.Discovery.Tabs.Hashtags" = "แฮชแท็ก"; "Scene.Discovery.Tabs.News" = "ข่าว"; "Scene.Discovery.Tabs.Posts" = "โพสต์"; +"Scene.Familiarfollowers.FollowedByNames" = "ติดตามโดย %@"; +"Scene.Familiarfollowers.Title" = "ผู้ติดตามที่คุณคุ้นเคย"; "Scene.Favorite.Title" = "รายการโปรดของคุณ"; +"Scene.FavoritedBy.Title" = "ชื่นชอบโดย"; "Scene.Follower.Footer" = "ไม่ได้แสดงผู้ติดตามจากเซิร์ฟเวอร์อื่น ๆ"; +"Scene.Follower.Title" = "ผู้ติดตาม"; "Scene.Following.Footer" = "ไม่ได้แสดงการติดตามจากเซิร์ฟเวอร์อื่น ๆ"; +"Scene.Following.Title" = "กำลังติดตาม"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "แตะเพื่อเลื่อนไปยังด้านบนสุดและแตะอีกครั้งไปยังตำแหน่งที่ตั้งก่อนหน้า"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "ปุ่มโลโก้"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "ดูโพสต์ใหม่"; "Scene.HomeTimeline.NavigationBarState.Offline" = "ออฟไลน์"; "Scene.HomeTimeline.NavigationBarState.Published" = "เผยแพร่แล้ว!"; @@ -251,6 +259,7 @@ "Scene.Profile.SegmentedControl.Posts" = "โพสต์"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "โพสต์และการตอบกลับ"; "Scene.Profile.SegmentedControl.Replies" = "การตอบกลับ"; +"Scene.RebloggedBy.Title" = "ดันโดย"; "Scene.Register.Error.Item.Agreement" = "ข้อตกลง"; "Scene.Register.Error.Item.Email" = "อีเมล"; "Scene.Register.Error.Item.Locale" = "ตำแหน่งที่ตั้ง"; @@ -258,7 +267,7 @@ "Scene.Register.Error.Item.Reason" = "เหตุผล"; "Scene.Register.Error.Item.Username" = "ชื่อผู้ใช้"; "Scene.Register.Error.Reason.Accepted" = "ต้องยอมรับ %@"; -"Scene.Register.Error.Reason.Blank" = "ต้องมี %@"; +"Scene.Register.Error.Reason.Blank" = "ต้องการ %@"; "Scene.Register.Error.Reason.Blocked" = "%@ มีผู้ให้บริการอีเมลที่ไม่ได้รับอนุญาต"; "Scene.Register.Error.Reason.Inclusion" = "%@ ไม่ใช่ค่าที่รองรับ"; "Scene.Register.Error.Reason.Invalid" = "%@ ไม่ถูกต้อง"; @@ -278,11 +287,12 @@ "Scene.Register.Input.Password.Accessibility.Checked" = "กาเครื่องหมายแล้ว"; "Scene.Register.Input.Password.Accessibility.Unchecked" = "ไม่ได้กาเครื่องหมาย"; "Scene.Register.Input.Password.CharacterLimit" = "8 ตัวอักษร"; -"Scene.Register.Input.Password.Hint" = "รหัสผ่านของคุณต้องมีอย่างน้อยแปดตัวอักษร"; +"Scene.Register.Input.Password.Hint" = "รหัสผ่านของคุณจำเป็นต้องมีอย่างน้อยแปดตัวอักษร"; "Scene.Register.Input.Password.Placeholder" = "รหัสผ่าน"; -"Scene.Register.Input.Password.Require" = "รหัสผ่านของคุณต้องมีอย่างน้อย:"; +"Scene.Register.Input.Password.Require" = "รหัสผ่านของคุณจำเป็นต้องมีอย่างน้อย:"; "Scene.Register.Input.Username.DuplicatePrompt" = "ชื่อผู้ใช้นี้ถูกใช้ไปแล้ว"; "Scene.Register.Input.Username.Placeholder" = "ชื่อผู้ใช้"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "มาตั้งค่าของคุณใน %@ กันเลย"; "Scene.Register.Title" = "มาตั้งค่าของคุณใน %@ กันเลย"; "Scene.Report.Content1" = "มีโพสต์อื่นใดที่คุณต้องการเพิ่มไปยังรายงานหรือไม่?"; "Scene.Report.Content2" = "มีสิ่งใดที่ผู้ควบคุมควรทราบเกี่ยวกับรายงานนี้หรือไม่?"; @@ -292,6 +302,38 @@ "Scene.Report.SkipToSend" = "ส่งโดยไม่มีความคิดเห็น"; "Scene.Report.Step1" = "ขั้นตอนที่ 1 จาก 2"; "Scene.Report.Step2" = "ขั้นตอนที่ 2 จาก 2"; +"Scene.Report.StepFinal.BlockUser" = "ปิดกั้น %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "ไม่ต้องการเห็นสิ่งนี้?"; +"Scene.Report.StepFinal.MuteUser" = "ซ่อน %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "เขาจะไม่สามารถติดตามหรือเห็นโพสต์ของคุณได้อีกต่อไป แต่เขาสามารถเห็นว่ามีการปิดกั้นเขาหรือไม่"; +"Scene.Report.StepFinal.Unfollow" = "เลิกติดตาม"; +"Scene.Report.StepFinal.UnfollowUser" = "เลิกติดตาม %@"; +"Scene.Report.StepFinal.Unfollowed" = "เลิกติดตามแล้ว"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "เมื่อคุณเห็นบางอย่างที่คุณไม่ชอบใน Mastodon คุณสามารถเอาบุคคลออกจากประสบการณ์ของคุณ"; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "ขณะที่เราตรวจทานสิ่งนี้ คุณสามารถดำเนินการกับ %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "คุณจะไม่เห็นโพสต์หรือการดันของเขาในฟีดหน้าแรกของคุณ เขาจะไม่ทราบว่ามีการซ่อนเขา"; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "มีสิ่งอื่นใดที่เราควรทราบหรือไม่?"; +"Scene.Report.StepFour.Step4Of4" = "ขั้นตอนที่ 4 จาก 4"; +"Scene.Report.StepOne.IDontLikeIt" = "ฉันไม่ชอบโพสต์"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "โพสต์ไม่ใช่บางอย่างที่คุณต้องการเห็น"; +"Scene.Report.StepOne.ItViolatesServerRules" = "โพสต์ละเมิดกฎของเซิร์ฟเวอร์"; +"Scene.Report.StepOne.ItsSomethingElse" = "โพสต์เป็นอย่างอื่น"; +"Scene.Report.StepOne.ItsSpam" = "โพสต์เป็นสแปม"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "ลิงก์ที่เป็นอันตราย, การมีส่วนร่วมปลอม หรือการตอบกลับซ้ำ ๆ"; +"Scene.Report.StepOne.SelectTheBestMatch" = "เลือกที่ตรงกันที่สุด"; +"Scene.Report.StepOne.Step1Of4" = "ขั้นตอนที่ 1 จาก 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "ปัญหาไม่เข้าหมวดหมู่อื่น ๆ"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "บัญชีนี้มีอะไรผิดปกติ?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "โพสต์นี้มีอะไรผิดปกติ?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "%@ มีอะไรผิดปกติ?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "คุณทราบว่าโพสต์แหกกฎเฉพาะ"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "มีโพสต์ใด ๆ ที่สนับสนุนรายงานนี้หรือไม่?"; +"Scene.Report.StepThree.SelectAllThatApply" = "เลือกทั้งหมดที่นำไปใช้"; +"Scene.Report.StepThree.Step3Of4" = "ขั้นตอนที่ 3 จาก 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "ฉันแค่ไม่ชอบโพสต์"; +"Scene.Report.StepTwo.SelectAllThatApply" = "เลือกทั้งหมดที่นำไปใช้"; +"Scene.Report.StepTwo.Step2Of4" = "ขั้นตอนที่ 2 จาก 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "กำลังละเมิดกฎใด?"; "Scene.Report.TextPlaceholder" = "พิมพ์หรือวางความคิดเห็นเพิ่มเติม"; "Scene.Report.Title" = "รายงาน %@"; "Scene.Report.TitleReport" = "รายงาน"; @@ -312,16 +354,16 @@ "Scene.Search.Searching.Segment.People" = "ผู้คน"; "Scene.Search.Searching.Segment.Posts" = "โพสต์"; "Scene.Search.Title" = "ค้นหา"; -"Scene.ServerPicker.Button.Category.Academia" = "วิชาการ"; +"Scene.ServerPicker.Button.Category.Academia" = "สถาบันการศึกษา"; "Scene.ServerPicker.Button.Category.Activism" = "กิจกรรมเพื่อการเปลี่ยนแปลง"; "Scene.ServerPicker.Button.Category.All" = "ทั้งหมด"; "Scene.ServerPicker.Button.Category.AllAccessiblityDescription" = "หมวดหมู่: ทั้งหมด"; "Scene.ServerPicker.Button.Category.Art" = "ศิลปะ"; "Scene.ServerPicker.Button.Category.Food" = "อาหาร"; -"Scene.ServerPicker.Button.Category.Furry" = "furry"; +"Scene.ServerPicker.Button.Category.Furry" = "สัตว์ขนยาว"; "Scene.ServerPicker.Button.Category.Games" = "เกม"; "Scene.ServerPicker.Button.Category.General" = "ทั่วไป"; -"Scene.ServerPicker.Button.Category.Journalism" = "การเขียนข่าว"; +"Scene.ServerPicker.Button.Category.Journalism" = "วารสารศาสตร์"; "Scene.ServerPicker.Button.Category.Lgbt" = "lgbt"; "Scene.ServerPicker.Button.Category.Music" = "ดนตรี"; "Scene.ServerPicker.Button.Category.Regional" = "ภูมิภาค"; @@ -331,13 +373,14 @@ "Scene.ServerPicker.EmptyState.BadNetwork" = "มีบางอย่างผิดพลาดขณะโหลดข้อมูล ตรวจสอบการเชื่อมต่ออินเทอร์เน็ตของคุณ"; "Scene.ServerPicker.EmptyState.FindingServers" = "กำลังค้นหาเซิร์ฟเวอร์ที่พร้อมใช้งาน..."; "Scene.ServerPicker.EmptyState.NoResults" = "ไม่มีผลลัพธ์"; -"Scene.ServerPicker.Input.Placeholder" = "ค้นหาชุมชน"; +"Scene.ServerPicker.Input.Placeholder" = "ค้นหาเซิร์ฟเวอร์"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "หมวดหมู่"; "Scene.ServerPicker.Label.Language" = "ภาษา"; "Scene.ServerPicker.Label.Users" = "ผู้ใช้"; -"Scene.ServerPicker.Subtitle" = "เลือกชุมชนตามความสนใจ, ภูมิภาค หรือวัตถุประสงค์ทั่วไปของคุณ"; -"Scene.ServerPicker.SubtitleExtend" = "เลือกชุมชนตามความสนใจ, ภูมิภาค หรือวัตถุประสงค์ทั่วไปของคุณ แต่ละชุมชนดำเนินการโดยองค์กรหรือบุคคลที่เป็นอิสระโดยสิ้นเชิง"; -"Scene.ServerPicker.Title" = "Mastodon ประกอบด้วยผู้ใช้ในชุมชนต่าง ๆ"; +"Scene.ServerPicker.Subtitle" = "เลือกเซิร์ฟเวอร์ตามความสนใจ, ภูมิภาค หรือวัตถุประสงค์ทั่วไปของคุณ"; +"Scene.ServerPicker.SubtitleExtend" = "เลือกเซิร์ฟเวอร์ตามความสนใจ, ภูมิภาค หรือวัตถุประสงค์ทั่วไปของคุณ แต่ละเซิร์ฟเวอร์ดำเนินการโดยองค์กรหรือบุคคลที่เป็นอิสระโดยสิ้นเชิง"; +"Scene.ServerPicker.Title" = "Mastodon ประกอบด้วยผู้ใช้ในเซิร์ฟเวอร์ต่าง ๆ"; "Scene.ServerRules.Button.Confirm" = "ฉันเห็นด้วย"; "Scene.ServerRules.PrivacyPolicy" = "นโยบายความเป็นส่วนตัว"; "Scene.ServerRules.Prompt" = "เมื่อคุณดำเนินการต่อ คุณอยู่ภายใต้เงื่อนไขการให้บริการและนโยบายความเป็นส่วนตัวสำหรับ %@"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.stringsdict index 8ae8feb7b..897d07eca 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/th.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld ตัวอักษร + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + ติดตามโดย %1$@ และ %ld ที่ร่วมกัน + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ โพสต์ + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld สื่อ + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings index 9bee4db1a..a9fb6935e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.strings @@ -199,16 +199,24 @@ yüklenemiyor."; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "E-posta İstemcisini Aç"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Gelen kutunuzu kontrol edin."; "Scene.ConfirmEmail.Subtitle" = "Hesabınızı doğrulamak için size e-postayla gönderdiğimiz bağlantıya dokunun."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Tap the link we emailed to you to verify your account"; "Scene.ConfirmEmail.Title" = "Son bir şey."; "Scene.Discovery.Intro" = "Bunlar, Mastodon'un köşesinde ilgi çeken gönderilerdir."; -"Scene.Discovery.Tabs.Community" = "Community"; +"Scene.Discovery.Tabs.Community" = "Topluluk"; "Scene.Discovery.Tabs.ForYou" = "Senin İçin"; "Scene.Discovery.Tabs.Hashtags" = "Etiketler"; "Scene.Discovery.Tabs.News" = "Haberler"; "Scene.Discovery.Tabs.Posts" = "Gönderiler"; +"Scene.Familiarfollowers.FollowedByNames" = "Followed by %@"; +"Scene.Familiarfollowers.Title" = "Followers you familiar"; "Scene.Favorite.Title" = "Favorilerin"; +"Scene.FavoritedBy.Title" = "Favorited By"; "Scene.Follower.Footer" = "Diğer sunucudaki takipçiler gösterilemiyor."; +"Scene.Follower.Title" = "follower"; "Scene.Following.Footer" = "Diğer sunucudaki takip edilenler gösterilemiyor."; +"Scene.Following.Title" = "following"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo Button"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Yeni gönderiler gör"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Çevrimdışı"; "Scene.HomeTimeline.NavigationBarState.Published" = "Yayınlandı!"; @@ -250,6 +258,7 @@ yüklenemiyor."; "Scene.Profile.SegmentedControl.Posts" = "Gönderiler"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Gönderiler ve Yanıtlar"; "Scene.Profile.SegmentedControl.Replies" = "Yanıtlar"; +"Scene.RebloggedBy.Title" = "Reblogged By"; "Scene.Register.Error.Item.Agreement" = "Anlaşma"; "Scene.Register.Error.Item.Email" = "E-posta"; "Scene.Register.Error.Item.Locale" = "Locale"; @@ -282,6 +291,7 @@ yüklenemiyor."; "Scene.Register.Input.Password.Require" = "Parolanızda en azından şunlar olmalı:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Bu kullanıcı adı alınmış."; "Scene.Register.Input.Username.Placeholder" = "kullanıcı adı"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Let’s get you set up on %@"; "Scene.Register.Title" = "%@ için kurulumunuzu yapalım"; "Scene.Report.Content1" = "Bu rapora eklemek istediğiniz başka gönderiler var mı?"; "Scene.Report.Content2" = "Bu rapor hakkında moderatörlerin bilmesi gerektiği bir şey var mı?"; @@ -291,6 +301,38 @@ yüklenemiyor."; "Scene.Report.SkipToSend" = "Yorum yapmadan gönder"; "Scene.Report.Step1" = "Adım 1/2"; "Scene.Report.Step2" = "Adım 2/2"; +"Scene.Report.StepFinal.BlockUser" = "Block %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Bunu görmek istemiyor musunuz?"; +"Scene.Report.StepFinal.MuteUser" = "Mute %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "They will no longer be able to follow or see your posts, but they can see if they’ve been blocked."; +"Scene.Report.StepFinal.Unfollow" = "Takibi bırak"; +"Scene.Report.StepFinal.UnfollowUser" = "Unfollow %@"; +"Scene.Report.StepFinal.Unfollowed" = "Unfollowed"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "When you see something you don’t like on Mastodon, you can remove the person from your experience."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "While we review this, you can take action against %@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "You won’t see their posts or reblogs in your home feed. They won’t know they’ve been muted."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Bilmemiz gereken başka bir şey var mı?"; +"Scene.Report.StepFour.Step4Of4" = "Adım 4/4"; +"Scene.Report.StepOne.IDontLikeIt" = "Beğenmedim"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "Görmek isteyeceğim bir şey değil"; +"Scene.Report.StepOne.ItViolatesServerRules" = "Sunucu kurallarını ihlal ediyor"; +"Scene.Report.StepOne.ItsSomethingElse" = "Başka bir şey"; +"Scene.Report.StepOne.ItsSpam" = "Spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Malicious links, fake engagement, or repetetive replies"; +"Scene.Report.StepOne.SelectTheBestMatch" = "En iyi seçeneceği seçiniz"; +"Scene.Report.StepOne.Step1Of4" = "Adım 1/4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "Sorun bunlardan biri değil"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Bu hesap ile ilgili sorun nedir?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Bu gönderi ile ilgili sorun nedir?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "%@ kişisinin sorunu nedir?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "You are aware that it breaks specific rules"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Bu bildirimi destekleyecek herhangi bir gönderi var mı?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Geçerli olanların tümünü seçiniz"; +"Scene.Report.StepThree.Step3Of4" = "Adım 3/4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "Beğenmedim"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Geçerli olan tümünü seçiniz"; +"Scene.Report.StepTwo.Step2Of4" = "Adım 2/4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Hangi kurallar ihlal ediliyor?"; "Scene.Report.TextPlaceholder" = "Ek yorum yazın veya yapıştırın"; "Scene.Report.Title" = "%@ kişisini bildir"; "Scene.Report.TitleReport" = "Raporla"; @@ -331,6 +373,7 @@ yüklenemiyor."; "Scene.ServerPicker.EmptyState.FindingServers" = "Mevcut sunucular aranıyor..."; "Scene.ServerPicker.EmptyState.NoResults" = "Sonuç yok"; "Scene.ServerPicker.Input.Placeholder" = "Toplulukları ara"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "KATEGORİ"; "Scene.ServerPicker.Label.Language" = "DİL"; "Scene.ServerPicker.Label.Users" = "KULLANICILAR"; @@ -356,7 +399,7 @@ yüklenemiyor."; "Scene.Settings.Section.LookAndFeel.Light" = "Açık"; "Scene.Settings.Section.LookAndFeel.ReallyDark" = "Gerçek Koyu"; "Scene.Settings.Section.LookAndFeel.SortaDark" = "Hafif Koyu"; -"Scene.Settings.Section.LookAndFeel.Title" = "Look and Feel"; +"Scene.Settings.Section.LookAndFeel.Title" = "Görünüm"; "Scene.Settings.Section.LookAndFeel.UseSystem" = "Sistem İle Aynı"; "Scene.Settings.Section.Notifications.Boosts" = "Gönderimi yeniden paylaştığında"; "Scene.Settings.Section.Notifications.Favorites" = "Gönderimi favorilerine eklediğinde"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict index d6817c1f6..3da12ee4e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/tr.lproj/Localizable.stringsdict @@ -50,6 +50,33 @@ %ld karakter + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + one + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + Followed by %1$@, and another mutual + other + Followed by %1$@, and %ld mutuals + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -66,6 +93,22 @@ gönderi + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + one + 1 media + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings index d7853fa79..9978b2ea9 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.strings @@ -200,6 +200,7 @@ tải lên Mastodon."; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "Mở ứng dụng email"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "Kiểm tra hộp thư của bạn."; "Scene.ConfirmEmail.Subtitle" = "Nhấn vào liên kết chúng tôi gửi qua email để xác thực tài khoản."; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "Nhấn vào liên kết chúng tôi gửi qua email để xác thực tài khoản"; "Scene.ConfirmEmail.Title" = "Còn điều này nữa."; "Scene.Discovery.Intro" = "Đây là những tút thu hút được sự chú ý trong góc Mastodon của bạn."; "Scene.Discovery.Tabs.Community" = "Máy chủ"; @@ -207,9 +208,16 @@ tải lên Mastodon."; "Scene.Discovery.Tabs.Hashtags" = "Hashtag"; "Scene.Discovery.Tabs.News" = "Tin tức"; "Scene.Discovery.Tabs.Posts" = "Tút"; +"Scene.Familiarfollowers.FollowedByNames" = "Theo dõi bởi %@"; +"Scene.Familiarfollowers.Title" = "Người theo dõi tương tự"; "Scene.Favorite.Title" = "Lượt thích"; +"Scene.FavoritedBy.Title" = "Thích bởi"; "Scene.Follower.Footer" = "Không hiển thị người theo dõi từ máy chủ khác."; +"Scene.Follower.Title" = "người theo dõi"; "Scene.Following.Footer" = "Không hiển thị người bạn theo dõi từ máy chủ khác."; +"Scene.Following.Title" = "đang theo dõi"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Nhấn để cuộn lên trên và nhấn lại lần nữa để trở về vị trí cũ"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Nút biểu tượng"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "Đọc những tút mới"; "Scene.HomeTimeline.NavigationBarState.Offline" = "Ngoại tuyến"; "Scene.HomeTimeline.NavigationBarState.Published" = "Đã đăng!"; @@ -251,6 +259,7 @@ tải lên Mastodon."; "Scene.Profile.SegmentedControl.Posts" = "Tút"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "Tút và trả lời"; "Scene.Profile.SegmentedControl.Replies" = "Trả lời"; +"Scene.RebloggedBy.Title" = "Đăng lại bởi"; "Scene.Register.Error.Item.Agreement" = "Thoả thuận"; "Scene.Register.Error.Item.Email" = "Email"; "Scene.Register.Error.Item.Locale" = "Cục bộ"; @@ -283,6 +292,7 @@ tải lên Mastodon."; "Scene.Register.Input.Password.Require" = "Mật khẩu phải tối thiểu:"; "Scene.Register.Input.Username.DuplicatePrompt" = "Tên người dùng đã tồn tại."; "Scene.Register.Input.Username.Placeholder" = "tên người dùng"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "Hãy để tôi đăng ký trên %@"; "Scene.Register.Title" = "Hãy để tôi đăng ký trên %@"; "Scene.Report.Content1" = "Bạn muốn thêm tút nào vào báo cáo nữa không?"; "Scene.Report.Content2" = "Kiểm duyệt viên cần biết gì về báo cáo này?"; @@ -292,6 +302,38 @@ tải lên Mastodon."; "Scene.Report.SkipToSend" = "Gửi không ghi chú"; "Scene.Report.Step1" = "Bước 1 trong 2"; "Scene.Report.Step2" = "Bước 2 trong 2"; +"Scene.Report.StepFinal.BlockUser" = "Chặn %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "Không muốn xem thứ này?"; +"Scene.Report.StepFinal.MuteUser" = "Ẩn %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "Họ sẽ không thể theo dõi hoặc đọc tút của bạn, nhưng họ có thể hiểu bạn đã chặn họ."; +"Scene.Report.StepFinal.Unfollow" = "Ngưng theo dõi"; +"Scene.Report.StepFinal.UnfollowUser" = "Ngưng theo dõi %@"; +"Scene.Report.StepFinal.Unfollowed" = "Ngưng theo dõi"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "Khi bạn thấy có gì đó mà bạn không thích trên Mastodon, bạn có thể tự loại bỏ chúng."; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "Trong lúc chờ chúng tôi xem xét, bạn có thể áp dụng hành động với @%@"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "Bạn sẽ không thấy tút hoặc lượt đăng lại của họ trên bảng tin. Họ không biết rằng bạn ẩn họ."; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "Bạn nghĩ chúng tôi nên biết thêm điều gì?"; +"Scene.Report.StepFour.Step4Of4" = "Bước 4 trong 4"; +"Scene.Report.StepOne.IDontLikeIt" = "Tôi không thích nó"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "Đó không phải là thứ gì mà bạn muốn thấy"; +"Scene.Report.StepOne.ItViolatesServerRules" = "Vi phạm quy tắc máy chủ"; +"Scene.Report.StepOne.ItsSomethingElse" = "Một lý do khác"; +"Scene.Report.StepOne.ItsSpam" = "Đây là spam"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "Liên kết độc hại, tạo tương tác giả hoặc trả lời lặp đi lặp lại"; +"Scene.Report.StepOne.SelectTheBestMatch" = "Chọn lý do khớp nhất"; +"Scene.Report.StepOne.Step1Of4" = "Bước 1 trong 4"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "Vấn đề không nằm trong những mục trên"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Có vấn đề gì với người này?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Có vấn đề gì với tút này?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Có vấn đề gì với %@?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Bạn nhận thấy nó vi phạm quy tắc máy chủ"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "Bạn muốn gửi tút nào kèm báo cáo này?"; +"Scene.Report.StepThree.SelectAllThatApply" = "Chọn tất cả những gì phù hợp"; +"Scene.Report.StepThree.Step3Of4" = "Bước 3 trong 4"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "Tôi không thích nó"; +"Scene.Report.StepTwo.SelectAllThatApply" = "Chọn tất cả những gì phù hợp"; +"Scene.Report.StepTwo.Step2Of4" = "Bước 2 trong 4"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "Vi phạm quy tắc nào?"; "Scene.Report.TextPlaceholder" = "Nhập hoặc bổ sung chú thích"; "Scene.Report.Title" = "Báo cáo %@"; "Scene.Report.TitleReport" = "Báo cáo"; @@ -332,6 +374,7 @@ tải lên Mastodon."; "Scene.ServerPicker.EmptyState.FindingServers" = "Đang tìm máy chủ hoạt động..."; "Scene.ServerPicker.EmptyState.NoResults" = "Không có kết quả"; "Scene.ServerPicker.Input.Placeholder" = "Tìm máy chủ"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "Search servers or enter URL"; "Scene.ServerPicker.Label.Category" = "PHÂN LOẠI"; "Scene.ServerPicker.Label.Language" = "NGÔN NGỮ"; "Scene.ServerPicker.Label.Users" = "NGƯỜI DÙNG"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.stringsdict index 71ba1951f..6905b240e 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/vi.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld ký tự + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + Theo dõi bởi %1$@, và %ld người quen + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ tút + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld media + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings index 438747344..bd45a50c8 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.strings @@ -199,8 +199,8 @@ "Scene.ConfirmEmail.OpenEmailApp.Mail" = "邮件"; "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "打开邮件客户端"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "检查你的邮箱"; -"Scene.ConfirmEmail.Subtitle" = "我们刚刚向 %@ 发送了一封电子邮件, -点击链接确认你的帐户。"; +"Scene.ConfirmEmail.Subtitle" = "点击我们发送给您的链接来验证您的账户。"; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "点击我们发送给您的链接来验证您的账户。"; "Scene.ConfirmEmail.Title" = "最后一件事。"; "Scene.Discovery.Intro" = "这些嘟文在你的长毛象小宇宙中备受关注。"; "Scene.Discovery.Tabs.Community" = "社区"; @@ -208,9 +208,16 @@ "Scene.Discovery.Tabs.Hashtags" = "话题标签"; "Scene.Discovery.Tabs.News" = "最新消息"; "Scene.Discovery.Tabs.Posts" = "嘟文"; +"Scene.Familiarfollowers.FollowedByNames" = "%@ 关注了这个账号"; +"Scene.Familiarfollowers.Title" = "你熟悉的关注者"; "Scene.Favorite.Title" = "你的喜欢"; +"Scene.FavoritedBy.Title" = "收藏者"; "Scene.Follower.Footer" = "不会显示来自其它服务器的关注者"; +"Scene.Follower.Title" = "关注者"; "Scene.Following.Footer" = "不会显示来自其它服务器的关注"; +"Scene.Following.Title" = "正在关注"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "轻点滚到顶部,再次轻点回到原处"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Logo 按钮"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "查看新帖子"; "Scene.HomeTimeline.NavigationBarState.Offline" = "离线"; "Scene.HomeTimeline.NavigationBarState.Published" = "已发送"; @@ -252,6 +259,7 @@ "Scene.Profile.SegmentedControl.Posts" = "帖子"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "帖子与回复"; "Scene.Profile.SegmentedControl.Replies" = "回复"; +"Scene.RebloggedBy.Title" = "转发者"; "Scene.Register.Error.Item.Agreement" = "协议"; "Scene.Register.Error.Item.Email" = "电子邮箱"; "Scene.Register.Error.Item.Locale" = "地区"; @@ -284,7 +292,8 @@ "Scene.Register.Input.Password.Require" = "您的密码至少需要:"; "Scene.Register.Input.Username.DuplicatePrompt" = "此用户名已被使用"; "Scene.Register.Input.Username.Placeholder" = "用户名"; -"Scene.Register.Title" = "介绍一下你自己吧"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "让我们在 %@ 上开始"; +"Scene.Register.Title" = "让我们在 %@ 上开始"; "Scene.Report.Content1" = "是否有帖子需要举报?"; "Scene.Report.Content2" = "是否有关于此举报的详细描述信息?"; "Scene.Report.ReportSentTitle" = "感谢提交举报,我们将会进行处理。"; @@ -293,6 +302,38 @@ "Scene.Report.SkipToSend" = "直接发送"; "Scene.Report.Step1" = "步骤 1 / 2"; "Scene.Report.Step2" = "步骤 2 / 2"; +"Scene.Report.StepFinal.BlockUser" = "屏蔽 %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "不想看到这个内容?"; +"Scene.Report.StepFinal.MuteUser" = "静音 %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "他们将不再能够关注或看到你的帖子,但他们可以知道他们是否被屏蔽。"; +"Scene.Report.StepFinal.Unfollow" = "取消关注"; +"Scene.Report.StepFinal.UnfollowUser" = "取消关注 %@"; +"Scene.Report.StepFinal.Unfollowed" = "已取消关注"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "当你在 Mastodon 看到不喜欢的东西时,可以尝试移除它。"; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "当我们审核这个报告时,你可以对 %@ 采取行动。"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "你不会在主页里看到他们的帖子和转发。他们不会知道被静音了。"; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "还有什么你认为我们应该知道的吗?"; +"Scene.Report.StepFour.Step4Of4" = "第 4 步(共 4 步)"; +"Scene.Report.StepOne.IDontLikeIt" = "我不喜欢它"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "这不是你想看到的东西"; +"Scene.Report.StepOne.ItViolatesServerRules" = "它违反了服务器规则"; +"Scene.Report.StepOne.ItsSomethingElse" = "其他原因"; +"Scene.Report.StepOne.ItsSpam" = "它是垃圾信息"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "恶意链接、虚假参与或重复性回复"; +"Scene.Report.StepOne.SelectTheBestMatch" = "选择最佳匹配"; +"Scene.Report.StepOne.Step1Of4" = "第 1 步(共 4 步)"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "该问题属于其他类别"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "这个账户有什么问题?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "这个帖子有什么问题?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "%@ 有什么问题?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "你发现它违反了某个服务器规则"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "有任何帖子可以支持此报告吗?"; +"Scene.Report.StepThree.SelectAllThatApply" = "选择适用选项"; +"Scene.Report.StepThree.Step3Of4" = "第 3 步(共 4 步)"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "我不喜欢它"; +"Scene.Report.StepTwo.SelectAllThatApply" = "选择适用选项"; +"Scene.Report.StepTwo.Step2Of4" = "第 2 步(共 4 步)"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "哪些规则被违反了?"; "Scene.Report.TextPlaceholder" = "输入或粘贴额外的注释"; "Scene.Report.Title" = "举报 %@"; "Scene.Report.TitleReport" = "举报"; @@ -333,6 +374,7 @@ "Scene.ServerPicker.EmptyState.FindingServers" = "正在查找可用的服务器..."; "Scene.ServerPicker.EmptyState.NoResults" = "无结果"; "Scene.ServerPicker.Input.Placeholder" = "查找或加入你自己的服务器..."; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "搜索服务器或输入 URL"; "Scene.ServerPicker.Label.Category" = "类别"; "Scene.ServerPicker.Label.Language" = "语言"; "Scene.ServerPicker.Label.Users" = "用户"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.stringsdict index 6c2661ee5..5a7af3752 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hans.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld 个字符 + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %1$@ 和你关注的另外 %ld 人也关注了这个账号 + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ 个帖子 + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld 个媒体 + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings index e76396f15..479dded34 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.strings @@ -195,6 +195,7 @@ "Scene.ConfirmEmail.OpenEmailApp.OpenEmailClient" = "請開啟電子郵件程式"; "Scene.ConfirmEmail.OpenEmailApp.Title" = "請檢查您的收件夾。"; "Scene.ConfirmEmail.Subtitle" = "點擊我們寄送給您的帳號驗證連結。"; +"Scene.ConfirmEmail.TapTheLinkWeEmailedToYouToVerifyYourAccount" = "點擊我們寄送給您的帳號驗證連結"; "Scene.ConfirmEmail.Title" = "最後一步。"; "Scene.Discovery.Intro" = "這些嘟文正在您 Mastodon 的角落受到注目。"; "Scene.Discovery.Tabs.Community" = "社群"; @@ -202,9 +203,16 @@ "Scene.Discovery.Tabs.Hashtags" = "主題標籤"; "Scene.Discovery.Tabs.News" = "最新消息"; "Scene.Discovery.Tabs.Posts" = "嘟文"; +"Scene.Familiarfollowers.FollowedByNames" = "被 %@ 跟隨"; +"Scene.Familiarfollowers.Title" = "您熟悉的跟隨者"; "Scene.Favorite.Title" = "您的最愛"; +"Scene.FavoritedBy.Title" = "已加入最愛"; "Scene.Follower.Footer" = "來自其他伺服器的跟隨者不會被顯示。"; +"Scene.Follower.Title" = "跟隨者"; "Scene.Following.Footer" = "來自其他伺服器的跟隨中不會被顯示。"; +"Scene.Following.Title" = "跟隨中"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "輕點一下捲至頂端並且再點ㄧ下回到原先位置"; +"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "標誌按鈕"; "Scene.HomeTimeline.NavigationBarState.NewPosts" = "檢視最新嘟文"; "Scene.HomeTimeline.NavigationBarState.Offline" = "離線"; "Scene.HomeTimeline.NavigationBarState.Published" = "嘟出去!"; @@ -246,6 +254,7 @@ "Scene.Profile.SegmentedControl.Posts" = "嘟文"; "Scene.Profile.SegmentedControl.PostsAndReplies" = "嘟文及回覆"; "Scene.Profile.SegmentedControl.Replies" = "回覆"; +"Scene.RebloggedBy.Title" = "已轉嘟"; "Scene.Register.Error.Item.Agreement" = "條款"; "Scene.Register.Error.Item.Email" = "電子郵件"; "Scene.Register.Error.Item.Locale" = "地區"; @@ -278,6 +287,7 @@ "Scene.Register.Input.Password.Require" = "您的密碼必須是至少:"; "Scene.Register.Input.Username.DuplicatePrompt" = "此使用者名稱已被佔用。"; "Scene.Register.Input.Username.Placeholder" = "使用者名稱"; +"Scene.Register.LetsGetYouSetUpOnDomain" = "讓我們一起設定 %@ 吧!"; "Scene.Register.Title" = "讓我們一起設定 %@ 吧!"; "Scene.Report.Content1" = "還有其他您想加入這份檢舉報告的嘟文嗎?"; "Scene.Report.Content2" = "有其他管管們需要知道關於這份檢舉報告的嗎?"; @@ -287,6 +297,38 @@ "Scene.Report.SkipToSend" = "不加入備註並傳送"; "Scene.Report.Step1" = "兩個步驟中的第一步"; "Scene.Report.Step2" = "兩個步驟中的第二步"; +"Scene.Report.StepFinal.BlockUser" = "封鎖 %@"; +"Scene.Report.StepFinal.DontWantToSeeThis" = "不想再看到這個?"; +"Scene.Report.StepFinal.MuteUser" = "靜音 %@"; +"Scene.Report.StepFinal.TheyWillNoLongerBeAbleToFollowOrSeeYourPostsButTheyCanSeeIfTheyveBeenBlocked" = "他們將無法跟隨您或是看到您的嘟文。他們能看到他們是否已被封鎖。"; +"Scene.Report.StepFinal.Unfollow" = "取消跟隨"; +"Scene.Report.StepFinal.UnfollowUser" = "取消跟隨 %@"; +"Scene.Report.StepFinal.Unfollowed" = "已取消跟隨"; +"Scene.Report.StepFinal.WhenYouSeeSomethingYouDontLikeOnMastodonYouCanRemoveThePersonFromYourExperience." = "當您看到某些不喜歡的內容時,您可以將該帳號從您的體驗中移除。"; +"Scene.Report.StepFinal.WhileWeReviewThisYouCanTakeActionAgainstUser" = "當我們正在審核時,您可以對 %@ 採取以下措施"; +"Scene.Report.StepFinal.YouWontSeeTheirPostsOrReblogsInYourHomeFeedTheyWontKnowTheyVeBeenMuted" = "您不會在您的首頁時間軸中再見到他們的嘟文或轉嘟。他們不會知道他們已被靜音。"; +"Scene.Report.StepFour.IsThereAnythingElseWeShouldKnow" = "有什麼其他您想讓我們知道的嗎?"; +"Scene.Report.StepFour.Step4Of4" = "四個步驟中的第四步"; +"Scene.Report.StepOne.IDontLikeIt" = "我不喜歡"; +"Scene.Report.StepOne.ItIsNotSomethingYouWantToSee" = "這是您不想看到的"; +"Scene.Report.StepOne.ItViolatesServerRules" = "違反伺服器規則"; +"Scene.Report.StepOne.ItsSomethingElse" = "其他原因"; +"Scene.Report.StepOne.ItsSpam" = "垃圾訊息"; +"Scene.Report.StepOne.MaliciousLinksFakeEngagementOrRepetetiveReplies" = "有害連結、假造的互動,或是重複性回覆"; +"Scene.Report.StepOne.SelectTheBestMatch" = "選擇最佳條件符合"; +"Scene.Report.StepOne.Step1Of4" = "四個步驟中的第一步"; +"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "這個問題不屬於其他分類"; +"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "這個帳號有什麼問題嗎?"; +"Scene.Report.StepOne.WhatsWrongWithThisPost" = "這則嘟文有什麼問題嗎?"; +"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "%@ 有什麼問題嗎?"; +"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "您知道它違反特定規則"; +"Scene.Report.StepThree.AreThereAnyPostsThatBackUpThisReport" = "是否有能佐證這份檢舉之嘟文?"; +"Scene.Report.StepThree.SelectAllThatApply" = "請選擇所有適用的選項"; +"Scene.Report.StepThree.Step3Of4" = "四個步驟中的第三步"; +"Scene.Report.StepTwo.IJustDon’tLikeIt" = "就是不順眼"; +"Scene.Report.StepTwo.SelectAllThatApply" = "請選擇所有適用的選項"; +"Scene.Report.StepTwo.Step2Of4" = "四個步驟中的第二步"; +"Scene.Report.StepTwo.WhichRulesAreBeingViolated" = "違反了哪些規則?"; "Scene.Report.TextPlaceholder" = "請輸入或貼上額外的備註"; "Scene.Report.Title" = "檢舉 %@"; "Scene.Report.TitleReport" = "檢舉"; @@ -327,6 +369,7 @@ "Scene.ServerPicker.EmptyState.FindingServers" = "尋找可用的伺服器..."; "Scene.ServerPicker.EmptyState.NoResults" = "沒有結果"; "Scene.ServerPicker.Input.Placeholder" = "搜尋伺服器"; +"Scene.ServerPicker.Input.SearchServersOrEnterUrl" = "搜尋伺服器或輸入網址"; "Scene.ServerPicker.Label.Category" = "分類"; "Scene.ServerPicker.Label.Language" = "語言"; "Scene.ServerPicker.Label.Users" = "使用者"; diff --git a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.stringsdict b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.stringsdict index 0f28a8f6e..c0ce0f9a2 100644 --- a/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.stringsdict +++ b/MastodonSDK/Sources/MastodonLocalization/Resources/zh-Hant.lproj/Localizable.stringsdict @@ -44,6 +44,29 @@ %ld 個字 + plural.count.followed_by_and_mutual + + NSStringLocalizedFormatKey + %#@names@%#@count_mutual@ + names + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + + + count_mutual + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + 被 %1$@ 跟隨,%ld 個共同跟隨者 + + plural.count.metric_formatted.post NSStringLocalizedFormatKey @@ -58,6 +81,20 @@ 嘟文 + plural.count.media + + NSStringLocalizedFormatKey + %#@media_count@ + media_count + + NSStringFormatSpecTypeKey + NSStringPluralRuleType + NSStringFormatValueTypeKey + ld + other + %ld 個媒體 + + plural.count.post NSStringLocalizedFormatKey diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+FamiliarFollowers.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+FamiliarFollowers.swift new file mode 100644 index 000000000..97d7b4618 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Account+FamiliarFollowers.swift @@ -0,0 +1,70 @@ +// +// Mastodon+API+Account+FamiliarFollowers.swift +// +// +// Created by MainasuK on 2022-5-13. +// + +import Foundation +import Combine + +// https://github.com/mastodon/mastodon/pull/17700 +extension Mastodon.API.Account { + + private static func familiarFollowersEndpointURL(domain: String) -> URL { + return Mastodon.API.endpointURL(domain: domain) + .appendingPathComponent("accounts") + .appendingPathComponent("familiar_followers") + } + + /// Fetch familiar followers + /// + /// - Since: 3.5.? + /// - Version: 3.5.2 + /// # Last Update + /// 2022/5/13 + /// # Reference + /// [Document](none) + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - query: `FamiliarFollowersQuery` + /// - authorization: User token + /// - Returns: `AnyPublisher` contains `[Mastodon.Entity.Account]` nested in the response + public static func familiarFollowers( + session: URLSession, + domain: String, + query: FamiliarFollowersQuery, + authorization: Mastodon.API.OAuth.Authorization + ) -> AnyPublisher, Error> { + let request = Mastodon.API.get( + url: familiarFollowersEndpointURL(domain: domain), + query: query, + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: [Mastodon.Entity.FamiliarFollowers].self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } + + public struct FamiliarFollowersQuery: GetQuery { + public let ids: [Mastodon.Entity.Account.ID] + + public init(ids: [Mastodon.Entity.Account.ID]) { + self.ids = ids + } + + var queryItems: [URLQueryItem]? { + var items: [URLQueryItem] = [] + for id in ids { + items.append(URLQueryItem(name: "id[]", value: id)) + } + guard !items.isEmpty else { return nil } + return items + } + } + +} diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Report.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Report.swift index 6ba8c3cf5..08ca3e922 100644 --- a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Report.swift +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Report.swift @@ -69,23 +69,40 @@ public extension Mastodon.API.Reports { public var statusIDs: [Mastodon.Entity.Status.ID]? public var comment: String? public let forward: Bool? + + public let category: Category? + public let ruleIDs: [Mastodon.Entity.Instance.Rule.ID]? enum CodingKeys: String, CodingKey { case accountID = "account_id" case statusIDs = "status_ids" case comment case forward + case category + case ruleIDs = "rule_ids" + + } + + public enum Category: String, Codable { + case spam + case violation + case other } public init( accountID: Mastodon.Entity.Account.ID, statusIDs: [Mastodon.Entity.Status.ID]?, comment: String?, - forward: Bool?) { + forward: Bool?, + category: Category?, + ruleIDs: [Mastodon.Entity.Instance.Rule.ID]? + ) { self.accountID = accountID self.statusIDs = statusIDs self.comment = comment self.forward = forward + self.category = category + self.ruleIDs = ruleIDs } } } diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+FavoriteBy.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+FavoriteBy.swift new file mode 100644 index 000000000..5d5747d13 --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+FavoriteBy.swift @@ -0,0 +1,84 @@ +// +// Mastodon+API+Statuses+FavoriteBy.swift +// +// +// Created by MainasuK on 2022-5-17. +// + +import Foundation +import Combine + +extension Mastodon.API.Statuses { + + private static func favoriteByEndpointURL(domain: String, statusID: Mastodon.Entity.Status.ID) -> URL { + return Mastodon.API.endpointURL(domain: domain) + .appendingPathComponent("statuses") + .appendingPathComponent(statusID) + .appendingPathComponent("favourited_by") // use same word from api + } + + /// Favourited by + /// + /// View who favourited a given status. + /// + /// - Since: 0.0.0 + /// - Version: 3.5.2 + /// # Last Update + /// 2022/5/17 + /// # Reference + /// [Document](https://docs.joinmastodon.org/methods/statuses/) + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - statusID: id for status + /// - authorization: User token. Could be nil if status is public + /// - Returns: `AnyPublisher` contains `Status` nested in the response + public static func favoriteBy( + session: URLSession, + domain: String, + statusID: Mastodon.Entity.Poll.ID, + query: FavoriteByQuery, + authorization: Mastodon.API.OAuth.Authorization? + ) -> AnyPublisher, Error> { + let request = Mastodon.API.get( + url: favoriteByEndpointURL(domain: domain, statusID: statusID), + query: query, + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: [Mastodon.Entity.Account].self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } + + public struct FavoriteByQuery: Codable, GetQuery { + + public let maxID: String? + public let limit: Int? // default 40 + + enum CodingKeys: String, CodingKey { + case maxID = "max_id" + case limit + } + + public init( + maxID: String?, + limit: Int? + ) { + self.maxID = maxID + self.limit = limit + } + + var queryItems: [URLQueryItem]? { + var items: [URLQueryItem] = [] + maxID.flatMap { items.append(URLQueryItem(name: "max_id", value: $0)) } + limit.flatMap { items.append(URLQueryItem(name: "limit", value: String($0))) } + guard !items.isEmpty else { return nil } + return items + } + + } + +} diff --git a/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+RebloggedBy.swift b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+RebloggedBy.swift new file mode 100644 index 000000000..db917a72b --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/API/Mastodon+API+Statuses+RebloggedBy.swift @@ -0,0 +1,84 @@ +// +// Mastodon+API+Statuses+RebloggedBy.swift +// +// +// Created by MainasuK on 2022-5-17. +// + +import Foundation +import Combine + +extension Mastodon.API.Statuses { + + private static func rebloggedByEndpointURL(domain: String, statusID: Mastodon.Entity.Status.ID) -> URL { + return Mastodon.API.endpointURL(domain: domain) + .appendingPathComponent("statuses") + .appendingPathComponent(statusID) + .appendingPathComponent("reblogged_by") + } + + /// Boosted by + /// + /// View who boosted a given status. + /// + /// - Since: 0.0.0 + /// - Version: 3.5.2 + /// # Last Update + /// 2022/5/17 + /// # Reference + /// [Document](https://docs.joinmastodon.org/methods/statuses/) + /// - Parameters: + /// - session: `URLSession` + /// - domain: Mastodon instance domain. e.g. "example.com" + /// - statusID: id for status + /// - authorization: User token. Could be nil if status is public + /// - Returns: `AnyPublisher` contains `Status` nested in the response + public static func rebloggedBy( + session: URLSession, + domain: String, + statusID: Mastodon.Entity.Poll.ID, + query: RebloggedByQuery, + authorization: Mastodon.API.OAuth.Authorization? + ) -> AnyPublisher, Error> { + let request = Mastodon.API.get( + url: rebloggedByEndpointURL(domain: domain, statusID: statusID), + query: query, + authorization: authorization + ) + return session.dataTaskPublisher(for: request) + .tryMap { data, response in + let value = try Mastodon.API.decode(type: [Mastodon.Entity.Account].self, from: data, response: response) + return Mastodon.Response.Content(value: value, response: response) + } + .eraseToAnyPublisher() + } + + public struct RebloggedByQuery: Codable, GetQuery { + + public let maxID: String? + public let limit: Int? // default 40 + + enum CodingKeys: String, CodingKey { + case maxID = "max_id" + case limit + } + + public init( + maxID: String?, + limit: Int? + ) { + self.maxID = maxID + self.limit = limit + } + + var queryItems: [URLQueryItem]? { + var items: [URLQueryItem] = [] + maxID.flatMap { items.append(URLQueryItem(name: "max_id", value: $0)) } + limit.flatMap { items.append(URLQueryItem(name: "limit", value: String($0))) } + guard !items.isEmpty else { return nil } + return items + } + + } + +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+FamiliarFollowers.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+FamiliarFollowers.swift new file mode 100644 index 000000000..ce411619b --- /dev/null +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+FamiliarFollowers.swift @@ -0,0 +1,24 @@ +// +// Mastodon+Entity+FamiliarFollowers.swift +// +// +// Created by MainasuK on 2022-5-16. +// + +import Foundation + +extension Mastodon.Entity { + + /// FamiliarFollowers + /// + /// - Since: 3.5.2 + /// - Version: 3.5.2 + /// # Last Update + /// 2022/5/16 + /// # Reference + /// [Document](TBD) + public class FamiliarFollowers: Codable { + public let id: Mastodon.Entity.Account.ID + public let accounts: [Mastodon.Entity.Account] + } +} diff --git a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift index 5d649a841..353601cd4 100644 --- a/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift +++ b/MastodonSDK/Sources/MastodonSDK/Entity/Mastodon+Entity+Instance.swift @@ -106,7 +106,9 @@ extension Mastodon.Entity.Instance { extension Mastodon.Entity.Instance { public struct Rule: Codable, Hashable { - public let id: String + public typealias ID = String + + public let id: ID public let text: String } } diff --git a/MastodonSDK/Sources/MastodonUI/Extension/CoreDataStack/MastodonEmoji.swift b/MastodonSDK/Sources/MastodonUI/Extension/CoreDataStack/MastodonEmoji.swift index 4f097759f..8e2558bb7 100644 --- a/MastodonSDK/Sources/MastodonUI/Extension/CoreDataStack/MastodonEmoji.swift +++ b/MastodonSDK/Sources/MastodonUI/Extension/CoreDataStack/MastodonEmoji.swift @@ -8,6 +8,7 @@ import Foundation import CoreDataStack import MastodonMeta +import MastodonSDK extension Collection where Element == MastodonEmoji { public var asDictionary: MastodonContent.Emojis { @@ -18,3 +19,13 @@ extension Collection where Element == MastodonEmoji { return dictionary } } + +extension Collection where Element == Mastodon.Entity.Emoji { + public var asDictionary: MastodonContent.Emojis { + var dictionary: MastodonContent.Emojis = [:] + for emoji in self { + dictionary[emoji.shortcode] = emoji.url + } + return dictionary + } +} diff --git a/MastodonSDK/Sources/MastodonUI/Extension/Date.swift b/MastodonSDK/Sources/MastodonUI/Extension/Date.swift index 89d31dc91..549dd550b 100644 --- a/MastodonSDK/Sources/MastodonUI/Extension/Date.swift +++ b/MastodonSDK/Sources/MastodonUI/Extension/Date.swift @@ -11,6 +11,8 @@ import MastodonLocalization extension Date { + static let calendar = Calendar(identifier: .gregorian) + public static let relativeTimestampFormatter: RelativeDateTimeFormatter = { let formatter = RelativeDateTimeFormatter() formatter.dateTimeStyle = .numeric @@ -18,8 +20,15 @@ extension Date { return formatter }() + public static let abbreviatedDateFormatter: DateFormatter = { + let formatter = DateFormatter() + formatter.dateStyle = .medium // e.g. Nov 23, 1937 + formatter.timeStyle = .none // none + return formatter + }() + public var localizedSlowedTimeAgoSinceNow: String { - return self.localizedTimeAgo(since: Date(), isSlowed: true, isAbbreviated: true) + return self.localizedTimeAgo(since: Date(), isSlowed: true, isAbbreviated: false) } public var localizedTimeAgoSinceNow: String { @@ -36,7 +45,21 @@ extension Date { if isAbbreviated { return latestDate.localizedShortTimeAgo(since: earlierDate) } else { - return Date.relativeTimestampFormatter.localizedString(for: earlierDate, relativeTo: latestDate) + if earlierDate.timeIntervalSince(latestDate) < -(7 * 24 * 60 * 60) { + let currentYear = Date.calendar.dateComponents([.year], from: Date()) + let earlierDateYear = Date.calendar.dateComponents([.year], from: earlierDate) + if #available(iOS 15.0, *) { + if currentYear.year! > earlierDateYear.year! { + return earlierDate.formatted(.dateTime.year().month(.abbreviated).day()) + } else { + return earlierDate.formatted(.dateTime.month(.abbreviated).day()) + } + } else { + return Date.abbreviatedDateFormatter.string(from: earlierDate) + } + } else { + return Date.relativeTimestampFormatter.localizedString(for: earlierDate, relativeTo: latestDate) + } } } } @@ -49,7 +72,7 @@ extension Date { let earlierDate = date < self ? date : self let latestDate = earlierDate == date ? self : date - let components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: earlierDate, to: latestDate) + let components = Date.calendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: earlierDate, to: latestDate) if components.year! > 0 { return L10n.Date.Year.Ago.abbr(components.year!) @@ -73,7 +96,7 @@ extension Date { let earlierDate = date < self ? date : self let latestDate = earlierDate == date ? self : date - let components = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: earlierDate, to: latestDate) + let components = Calendar(identifier: .gregorian).dateComponents([.year, .month, .day, .hour, .minute, .second], from: earlierDate, to: latestDate) if components.year! > 0 { return L10n.Date.Year.left(components.year!) diff --git a/MastodonSDK/Sources/MastodonUI/Extension/MastodonSDK/Mastodon+Entity+Account.swift b/MastodonSDK/Sources/MastodonUI/Extension/MastodonSDK/Mastodon+Entity+Account.swift new file mode 100644 index 000000000..2441ebfd0 --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/Extension/MastodonSDK/Mastodon+Entity+Account.swift @@ -0,0 +1,30 @@ +// +// Mastodon+Entity+Account.swift +// +// +// Created by MainasuK on 2022-5-16. +// + +import Foundation +import MastodonSDK + +extension Mastodon.Entity.Account { + public var displayNameWithFallback: String { + if displayName.isEmpty { + return username + } else { + return displayName + } + } +} + +extension Mastodon.Entity.Account { + public func avatarImageURL() -> URL? { + let string = UserDefaults.shared.preferredStaticAvatar ? avatarStatic ?? avatar : avatar + return URL(string: string) + } + + public func avatarImageURLWithFallback(domain: String) -> URL { + return avatarImageURL() ?? URL(string: "https://\(domain)/avatars/original/missing.png")! + } +} diff --git a/MastodonSDK/Sources/MastodonUI/Extension/MetaLabel.swift b/MastodonSDK/Sources/MastodonUI/Extension/MetaLabel.swift index 24a4027f5..41fbfe40c 100644 --- a/MastodonSDK/Sources/MastodonUI/Extension/MetaLabel.swift +++ b/MastodonSDK/Sources/MastodonUI/Extension/MetaLabel.swift @@ -22,6 +22,7 @@ extension MetaLabel { case profileFieldValue case profileCardName case profileCardUsername + case profileCardFamiliarFollowerFooter case recommendAccountName case titleView case settingTableFooter @@ -90,6 +91,14 @@ extension MetaLabel { font = .systemFont(ofSize: 15, weight: .regular) textColor = Asset.Colors.Label.secondary.color + case .profileCardFamiliarFollowerFooter: + font = UIFontMetrics(forTextStyle: .footnote).scaledFont(for: .systemFont(ofSize: 13, weight: .regular), maximumPointSize: 26) + textColor = Asset.Colors.Label.secondary.color + numberOfLines = 2 + textContainer.maximumNumberOfLines = 2 + paragraphStyle.lineSpacing = 0 + paragraphStyle.paragraphSpacing = 0 + case .titleView: font = .systemFont(ofSize: 17, weight: .semibold) textColor = Asset.Colors.Label.primary.color @@ -106,18 +115,23 @@ extension MetaLabel { numberOfLines = 0 textContainer.maximumNumberOfLines = 0 paragraphStyle.alignment = .center + case .autoCompletion: font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold), maximumPointSize: 22) textColor = Asset.Colors.brandBlue.color + case .accountListName: font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .regular), maximumPointSize: 22) textColor = Asset.Colors.Label.primary.color + case .accountListUsername: font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 15, weight: .regular), maximumPointSize: 20) textColor = Asset.Colors.Label.secondary.color + case .sidebarHeadline(let isSelected): font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 22, weight: .regular), maximumPointSize: 20) textColor = isSelected ? .white : Asset.Colors.Label.primary.color + case .sidebarSubheadline(let isSelected): font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 13, weight: .regular), maximumPointSize: 18) textColor = isSelected ? .white : Asset.Colors.Label.secondary.color diff --git a/Mastodon/Service/BlurhashImageCacheService.swift b/MastodonSDK/Sources/MastodonUI/Service/BlurhashImageCacheService.swift similarity index 96% rename from Mastodon/Service/BlurhashImageCacheService.swift rename to MastodonSDK/Sources/MastodonUI/Service/BlurhashImageCacheService.swift index b15a9750b..cc9459b4e 100644 --- a/Mastodon/Service/BlurhashImageCacheService.swift +++ b/MastodonSDK/Sources/MastodonUI/Service/BlurhashImageCacheService.swift @@ -10,6 +10,9 @@ import Combine public final class BlurhashImageCacheService { + // MARK: - Singleton + public static let shared = BlurhashImageCacheService() + static let edgeMaxLength: CGFloat = 20 let cache = NSCache() diff --git a/Mastodon/Vender/BlurHashDecode.swift b/MastodonSDK/Sources/MastodonUI/Vendor/BlurHashDecode.swift similarity index 100% rename from Mastodon/Vender/BlurHashDecode.swift rename to MastodonSDK/Sources/MastodonUI/Vendor/BlurHashDecode.swift diff --git a/Mastodon/Vender/BlurHashEncode.swift b/MastodonSDK/Sources/MastodonUI/Vendor/BlurHashEncode.swift similarity index 100% rename from Mastodon/Vender/BlurHashEncode.swift rename to MastodonSDK/Sources/MastodonUI/Vendor/BlurHashEncode.swift diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/FamiliarFollowersDashboardView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/FamiliarFollowersDashboardView+Configuration.swift new file mode 100644 index 000000000..0b63f848e --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/View/Content/FamiliarFollowersDashboardView+Configuration.swift @@ -0,0 +1,27 @@ +// +// FamiliarFollowersDashboardView+Configuration.swift +// +// +// Created by MainasuK on 2022-5-16. +// + +import UIKit +import MastodonSDK + +extension FamiliarFollowersDashboardView { + public func configure(familiarFollowers: Mastodon.Entity.FamiliarFollowers?) { + assert(Thread.isMainThread) + + let accounts = familiarFollowers?.accounts ?? [] + + viewModel.avatarURLs = accounts.map { $0.avatarImageURL() } + viewModel.names = accounts.map { $0.displayNameWithFallback } + viewModel.emojis = { + var array: [Mastodon.Entity.Emoji] = [] + for account in accounts { + array.append(contentsOf: account.emojis ?? []) + } + return array.asDictionary + }() + } +} diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/FamiliarFollowersDashboardView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/FamiliarFollowersDashboardView+ViewModel.swift new file mode 100644 index 000000000..a9bb2c5f0 --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/View/Content/FamiliarFollowersDashboardView+ViewModel.swift @@ -0,0 +1,108 @@ +// +// FamiliarFollowersDashboardView+ViewModel.swift +// +// +// Created by MainasuK on 2022-5-16. +// + +import os.log +import UIKit +import Combine +import CoreDataStack +import MastodonMeta +import MastodonLocalization + +extension FamiliarFollowersDashboardView { + public final class ViewModel: ObservableObject { + public var disposeBag = Set() + + let logger = Logger(subsystem: "FamiliarFollowersDashboardView", category: "ViewModel") + + @Published var avatarURLs: [URL?] = [] + @Published var names: [String] = [] + @Published var emojis: MastodonContent.Emojis = [:] + @Published var backgroundColor: UIColor? + } +} + +extension FamiliarFollowersDashboardView.ViewModel { + func bind(view: FamiliarFollowersDashboardView) { + Publishers.CombineLatest3( + $avatarURLs, + $backgroundColor, + UIContentSizeCategory.publisher + ) + .sink { avatarURLs, backgroundColor, contentSizeCategory in + // only using first 4 items + let avatarURLs = avatarURLs.prefix(4) + + view.avatarContainerView.subviews.forEach { $0.removeFromSuperview() } + + let initialOffset = min(12 * 1.5, UIFontMetrics(forTextStyle: .headline).scaledValue(for: 12)) // max 1.5x + let offset = min(20 * 1.5, UIFontMetrics(forTextStyle: .headline).scaledValue(for: 20)) + let dimension = min(32 * 1.5, UIFontMetrics(forTextStyle: .headline).scaledValue(for: 32)) + let borderWidth = min(1.5, UIFontMetrics.default.scaledValue(for: 1)) + + for (i, avatarURL) in avatarURLs.enumerated() { + let avatarButton = AvatarButton() + let origin = CGPoint(x: offset * CGFloat(i), y: 0) + let size = CGSize(width: dimension, height: dimension) + avatarButton.size = size + avatarButton.frame = CGRect(origin: origin, size: size) + view.avatarContainerView.addSubview(avatarButton) + avatarButton.avatarImageView.configure( + configuration: .init( + url: avatarURL, + placeholder: .placeholder(color: .systemGray3) + ) + ) + avatarButton.avatarImageView.configure( + cornerConfiguration: .init( + corner: .fixed(radius: 7), + border: .init( + color: backgroundColor ?? .clear, + width: borderWidth + ) + ) + ) + } + + let avatarContainerViewWidth = initialOffset + offset * CGFloat(avatarURLs.count) + view.avatarContainerViewWidthLayoutConstraint.constant = avatarContainerViewWidth + view.avatarContainerViewHeightLayoutConstraint.constant = dimension + } + .store(in: &disposeBag) + + Publishers.CombineLatest( + $names, + $emojis + ) + .sink { names, emojis in + let content: String = { + guard names.count > 0 else { return " " } + + let count = names.count + let firstTwoNames = names.prefix(2).joined(separator: ", ") + + switch names.count { + case 1..<3: + return L10n.Scene.Familiarfollowers.followedByNames(firstTwoNames) + default: + // Note: SwiftGen generates wrong formate argv for "%1$@" + let remains = count - 2 + let format = MastodonLocalization.bundle.localizedString(forKey: "plural.count.followed_by_and_mutual", value: nil, table: "Localizable") + return String(format: format, locale: .current, arguments: [firstTwoNames, remains]) + } + }() + let document = MastodonContent(content: content, emojis: emojis) + do { + let metaContent = try MastodonMetaContent.convert(document: document) + view.descriptionMetaLabel.configure(content: metaContent) + } catch { + assertionFailure() + view.descriptionMetaLabel.configure(content: PlaintextMetaContent(string: content)) + } + } + .store(in: &disposeBag) + } +} diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/FamiliarFollowersDashboardView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/FamiliarFollowersDashboardView.swift new file mode 100644 index 000000000..c15f8878a --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/View/Content/FamiliarFollowersDashboardView.swift @@ -0,0 +1,82 @@ +// +// FamiliarFollowersDashboardView.swift +// +// +// Created by MainasuK on 2022-5-16. +// + +import UIKit +import MastodonAsset +import MetaTextKit + +public final class FamiliarFollowersDashboardView: UIView { + + let avatarContainerView = UIView() + var avatarContainerViewWidthLayoutConstraint: NSLayoutConstraint! + var avatarContainerViewHeightLayoutConstraint: NSLayoutConstraint! + + let descriptionMetaLabel = MetaLabel(style: .profileCardFamiliarFollowerFooter) + + public private(set) lazy var viewModel: ViewModel = { + let viewModel = ViewModel() + viewModel.bind(view: self) + return viewModel + }() + + override init(frame: CGRect) { + super.init(frame: frame) + _init() + } + + required init?(coder: NSCoder) { + super.init(coder: coder) + _init() + } + +} + +extension FamiliarFollowersDashboardView { + + private func _init() { + let stackView = UIStackView() + stackView.axis = .horizontal + stackView.alignment = .center + stackView.spacing = 8 + + stackView.translatesAutoresizingMaskIntoConstraints = false + addSubview(stackView) + NSLayoutConstraint.activate([ + stackView.topAnchor.constraint(equalTo: topAnchor), + stackView.leadingAnchor.constraint(equalTo: leadingAnchor), + stackView.trailingAnchor.constraint(equalTo: trailingAnchor), + stackView.bottomAnchor.constraint(equalTo: bottomAnchor), + ]) + + avatarContainerView.translatesAutoresizingMaskIntoConstraints = false + stackView.addArrangedSubview(avatarContainerView) + avatarContainerViewWidthLayoutConstraint = avatarContainerView.widthAnchor.constraint(equalToConstant: 32).priority(.required - 1) + avatarContainerViewHeightLayoutConstraint = avatarContainerView.heightAnchor.constraint(equalToConstant: 32).priority(.required - 1) + NSLayoutConstraint.activate([ + avatarContainerViewWidthLayoutConstraint, + avatarContainerViewHeightLayoutConstraint + ]) + stackView.addArrangedSubview(descriptionMetaLabel) + descriptionMetaLabel.setContentHuggingPriority(.required - 1, for: .vertical) + descriptionMetaLabel.setContentCompressionResistancePriority(.required - 1, for: .vertical) + + descriptionMetaLabel.isUserInteractionEnabled = false + } + +} + + +#if DEBUG +import SwiftUI +struct FamiliarFollowersDashboardView_Preview: PreviewProvider { + static var previews: some View { + UIViewPreview { + FamiliarFollowersDashboardView() + } + } +} +#endif diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift index 6026e668f..cfe9e73ce 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/MediaView+Configuration.swift @@ -10,6 +10,7 @@ import UIKit import Combine import CoreData import Photos +import AlamofireImage extension MediaView { public class Configuration: Hashable { @@ -142,3 +143,37 @@ extension MediaView.Configuration { } } + +extension MediaView.Configuration { + + public func load() { + if let previewURL = previewURL, + let url = URL(string: previewURL) + { + let placeholder = UIImage.placeholder(color: .systemGray6) + let request = URLRequest(url: url) + ImageDownloader.default.download(request, completion: { [weak self] response in + guard let self = self else { return } + switch response.result { + case .success(let image): + self.previewImage = image + case .failure: + self.previewImage = placeholder + } + }) + } + + if let assetURL = assetURL, + let blurhash = blurhash + { + BlurhashImageCacheService.shared.image( + blurhash: blurhash, + size: aspectRadio, + url: assetURL + ) + .assign(to: \.blurhashImage, on: self) + .store(in: &blurhashImageDisposeBag) + } + } + +} diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift index 397982aaf..7f44232aa 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NewsView+Configuration.swift @@ -6,6 +6,7 @@ // import UIKit +import Combine import MastodonSDK import MastodonLocalization import AlamofireImage diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NewsView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NewsView.swift index 6d4cf3fd7..0d4298035 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NewsView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NewsView.swift @@ -6,9 +6,14 @@ // import UIKit +import Combine import MastodonAsset public final class NewsView: UIView { + + static let imageViewWidth: CGFloat = 132 + + var disposeBag = Set() let container = UIStackView() @@ -44,10 +49,14 @@ public final class NewsView: UIView { }() let imageView = MediaView() + +// let imageView = UIImageView() +// var imageViewMediaConfiguration: MediaView.Configuration? public func prepareForReuse() { providerFaviconImageView.tag = (0..() - let logger = Logger(subsystem: "StatusView", category: "ViewModel") + let logger = Logger(subsystem: "NotificationView", category: "ViewModel") @Published public var userIdentifier: UserIdentifier? // me diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift index 8827eadae..8714c7cd0 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/NotificationView.swift @@ -434,6 +434,14 @@ extension NotificationView: StatusViewDelegate { assertionFailure() } + public func statusView(_ statusView: StatusView, statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton) { + assertionFailure() + } + + public func statusView(_ statusView: StatusView, statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton) { + assertionFailure() + } + public func statusView(_ statusView: StatusView, accessibilityActivate: Void) { assertionFailure() } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+Configuration.swift index 3964099d8..350c43736 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+Configuration.swift @@ -10,6 +10,7 @@ import Combine import CoreDataStack import Meta import MastodonMeta +import MastodonSDK extension ProfileCardView { diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+ViewModel.swift index 5b6c4c59c..0003e82b6 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView+ViewModel.swift @@ -13,6 +13,7 @@ import AlamofireImage import CoreDataStack import MastodonLocalization import MastodonAsset +import MastodonSDK extension ProfileCardView { public class ViewModel: ObservableObject { @@ -44,6 +45,8 @@ extension ProfileCardView { @Published public var groupedAccessibilityLabel = "" + @Published public var familiarFollowers: Mastodon.Entity.FamiliarFollowers? + init() { backgroundColor = ThemeService.shared.currentTheme.value.systemBackgroundColor Publishers.CombineLatest( @@ -77,6 +80,7 @@ extension ProfileCardView.ViewModel { bindBio(view: view) bindRelationship(view: view) bindDashboard(view: view) + bindFamiliarFollowers(view: view) bindAccessibility(view: view) } @@ -189,6 +193,18 @@ extension ProfileCardView.ViewModel { .store(in: &disposeBag) } + private func bindFamiliarFollowers(view: ProfileCardView) { + $familiarFollowers + .sink { familiarFollowers in + view.familiarFollowersDashboardViewAdaptiveMarginContainerView.isHidden = familiarFollowers.flatMap { $0.accounts.isEmpty } ?? true + view.familiarFollowersDashboardView.configure(familiarFollowers: familiarFollowers) + } + .store(in: &disposeBag) + $backgroundColor + .assign(to: \.backgroundColor, on: view.familiarFollowersDashboardView.viewModel) + .store(in: &disposeBag) + } + private func bindAccessibility(view: ProfileCardView) { let authorAccessibilityLabel = Publishers.CombineLatest( $authorName, diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView.swift index 07f441500..0572cc0f6 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/ProfileCardView.swift @@ -13,10 +13,13 @@ import MastodonAsset public protocol ProfileCardViewDelegate: AnyObject { func profileCardView(_ profileCardView: ProfileCardView, relationshipButtonDidPressed button: ProfileRelationshipActionButton) + func profileCardView(_ profileCardView: ProfileCardView, familiarFollowersDashboardViewDidPressed view: FamiliarFollowersDashboardView) } public final class ProfileCardView: UIView { + let logger = Logger(subsystem: "ProfileCardView", category: "View") + static let avatarSize = CGSize(width: 56, height: 56) static let friendshipActionButtonSize = CGSize(width: 108, height: 34) static let contentMargin: CGFloat = 16 @@ -94,6 +97,9 @@ public final class ProfileCardView: UIView { return button }() + let familiarFollowersDashboardViewAdaptiveMarginContainerView = AdaptiveMarginContainerView() + let familiarFollowersDashboardView = FamiliarFollowersDashboardView() + public private(set) lazy var viewModel: ViewModel = { let viewModel = ViewModel() viewModel.bind(view: self) @@ -126,7 +132,7 @@ extension ProfileCardView { bioMetaText.textView.isUserInteractionEnabled = false statusDashboardView.isUserInteractionEnabled = false - // container: V - [ bannerContainer | authorContainer | bioMetaText | infoContainer ] + // container: V - [ bannerContainer | authorContainer | bioMetaText | infoContainer | familiarFollowersDashboardView ] container.axis = .vertical container.spacing = 8 container.translatesAutoresizingMaskIntoConstraints = false @@ -163,7 +169,8 @@ extension ProfileCardView { authorContainerAdaptiveMarginContainerView.contentView = authorContainer authorContainerAdaptiveMarginContainerView.margin = ProfileCardView.contentMargin container.addArrangedSubview(authorContainerAdaptiveMarginContainerView) - + container.setCustomSpacing(6, after: bannerContainer) + // avatarPlaceholder let avatarPlaceholder = UIView() avatarPlaceholder.translatesAutoresizingMaskIntoConstraints = false @@ -211,12 +218,13 @@ extension ProfileCardView { container.addArrangedSubview(bioMetaTextAdaptiveMarginContainerView) container.setCustomSpacing(16, after: bioMetaTextAdaptiveMarginContainerView) - // infoContainer: H - [ statusDashboardView | (spacer) | relationshipActionButton ] + // infoContainer: H - [ statusDashboardView | (spacer) | relationshipActionButton] infoContainer.axis = .horizontal infoContainer.spacing = 8 infoContainerAdaptiveMarginContainerView.contentView = infoContainer infoContainerAdaptiveMarginContainerView.margin = ProfileCardView.contentMargin container.addArrangedSubview(infoContainerAdaptiveMarginContainerView) + container.setCustomSpacing(16, after: infoContainerAdaptiveMarginContainerView) infoContainer.addArrangedSubview(statusDashboardView) let infoContainerSpacer = UIView() @@ -237,15 +245,23 @@ extension ProfileCardView { relationshipActionButtonShadowContainer.widthAnchor.constraint(greaterThanOrEqualToConstant: ProfileCardView.friendshipActionButtonSize.width).priority(.required - 1), relationshipActionButtonShadowContainer.heightAnchor.constraint(equalToConstant: ProfileCardView.friendshipActionButtonSize.height).priority(.required - 1), ]) + + familiarFollowersDashboardViewAdaptiveMarginContainerView.contentView = familiarFollowersDashboardView + familiarFollowersDashboardViewAdaptiveMarginContainerView.margin = ProfileCardView.contentMargin + container.addArrangedSubview(familiarFollowersDashboardViewAdaptiveMarginContainerView) let bottomPadding = UIView() bottomPadding.translatesAutoresizingMaskIntoConstraints = false container.addArrangedSubview(bottomPadding) NSLayoutConstraint.activate([ - bottomPadding.heightAnchor.constraint(equalToConstant: 16).priority(.required - 10), + bottomPadding.heightAnchor.constraint(equalToConstant: 8).priority(.required - 10), ]) relationshipActionButton.addTarget(self, action: #selector(ProfileCardView.relationshipActionButtonDidPressed(_:)), for: .touchUpInside) + + let familiarFollowersDashboardViewTapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer + familiarFollowersDashboardViewTapGestureRecognizer.addTarget(self, action: #selector(ProfileCardView.familiarFollowersDashboardViewDidPressed(_:))) + familiarFollowersDashboardView.addGestureRecognizer(familiarFollowersDashboardViewTapGestureRecognizer) } public override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { @@ -278,8 +294,14 @@ extension ProfileCardView { extension ProfileCardView { @objc private func relationshipActionButtonDidPressed(_ sender: UIButton) { - os_log(.debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function) + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") assert(sender === relationshipActionButton) delegate?.profileCardView(self, relationshipButtonDidPressed: relationshipActionButton) } + + @objc private func familiarFollowersDashboardViewDidPressed(_ sender: UITapGestureRecognizer) { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") + assert(sender.view === familiarFollowersDashboardView) + delegate?.profileCardView(self, familiarFollowersDashboardViewDidPressed: familiarFollowersDashboardView) + } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusMetricView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusMetricView.swift index 2a770f302..d5f6a0709 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusMetricView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusMetricView.swift @@ -5,10 +5,20 @@ // Created by MainasuK on 2022-1-17. // +import os.log import UIKit +protocol StatusMetricViewDelegate: AnyObject { + func statusMetricView(_ statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton) + func statusMetricView(_ statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton) +} + public final class StatusMetricView: UIView { + let logger = Logger(subsystem: "StatusMetricView", category: "View") + + weak var delegate: StatusMetricViewDelegate? + // container public let containerStackView: UIStackView = { let stackView = UIStackView() @@ -88,9 +98,21 @@ extension StatusMetricView { favoriteButton.setContentHuggingPriority(.required - 1, for: .horizontal) favoriteButton.setContentCompressionResistancePriority(.required - 1, for: .horizontal) - // TODO: - reblogButton.isAccessibilityElement = false - favoriteButton.isAccessibilityElement = false + reblogButton.addTarget(self, action: #selector(StatusMetricView.reblogButtonDidPressed(_:)), for: .touchUpInside) + favoriteButton.addTarget(self, action: #selector(StatusMetricView.favoriteButtonDidPressed(_:)), for: .touchUpInside) + } +} + +extension StatusMetricView { + + @objc private func reblogButtonDidPressed(_ sender: UIButton) { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") + delegate?.statusMetricView(self, reblogButtonDidPressed: sender) + } + + @objc private func favoriteButtonDidPressed(_ sender: UIButton) { + logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)") + delegate?.statusMetricView(self, favoriteButtonDidPressed: sender) } } diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift index 44f7bb9ab..f3d9f6f80 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView+ViewModel.swift @@ -666,12 +666,11 @@ extension StatusView.ViewModel { let meidaAccessibilityLabel = $mediaViewConfigurations .map { configurations -> String? in let count = configurations.count - // TODO: i18n - return count > 0 ? "\(count) media" : nil + return L10n.Plural.Count.media(count) } // TODO: Toolbar - + Publishers.CombineLatest3( authorAccessibilityLabel, contentAccessibilityLabel, diff --git a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift index 7b96fe0b5..bdcbd473e 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Content/StatusView.swift @@ -25,6 +25,8 @@ public protocol StatusViewDelegate: AnyObject { func statusView(_ statusView: StatusView, menuButton button: UIButton, didSelectAction action: MastodonMenu.Action) func statusView(_ statusView: StatusView, spoilerOverlayViewDidPressed overlayView: SpoilerOverlayView) func statusView(_ statusView: StatusView, mediaGridContainerView: MediaGridContainerView, mediaSensitiveButtonDidPressed button: UIButton) + func statusView(_ statusView: StatusView, statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton) + func statusView(_ statusView: StatusView, statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton) // a11y func statusView(_ statusView: StatusView, accessibilityActivate: Void) @@ -318,8 +320,12 @@ extension StatusView { ]) pollTableView.delegate = self pollVoteButton.addTarget(self, action: #selector(StatusView.pollVoteButtonDidPressed(_:)), for: .touchUpInside) + // toolbar actionToolbarContainer.delegate = self + + // statusMetricView + statusMetricView.delegate = self } } @@ -405,18 +411,19 @@ extension StatusView.Style { NSLayoutConstraint.activate([ statusView.headerIconImageView.leadingAnchor.constraint(equalTo: statusView.headerContainerView.leadingAnchor), statusView.headerIconImageView.heightAnchor.constraint(equalTo: statusView.headerInfoLabel.heightAnchor, multiplier: 1.0).priority(.required - 1), - statusView.headerIconImageView.widthAnchor.constraint(equalTo: statusView.headerIconImageView.heightAnchor, multiplier: 1.0).priority(.required - 1), + statusView.headerIconImageView.widthAnchor.constraint(equalTo: statusView.headerInfoLabel.heightAnchor, multiplier: 1.0).priority(.required - 1), statusView.headerInfoLabel.topAnchor.constraint(equalTo: statusView.headerContainerView.topAnchor), statusView.headerInfoLabel.leadingAnchor.constraint(equalTo: statusView.headerIconImageView.trailingAnchor, constant: 6), statusView.headerInfoLabel.trailingAnchor.constraint(equalTo: statusView.headerContainerView.trailingAnchor), statusView.headerInfoLabel.bottomAnchor.constraint(equalTo: statusView.headerContainerView.bottomAnchor), statusView.headerInfoLabel.centerYAnchor.constraint(equalTo: statusView.headerIconImageView.centerYAnchor), ]) - statusView.headerInfoLabel.setContentHuggingPriority(.required, for: .vertical) - statusView.headerIconImageView.setContentHuggingPriority(.defaultLow, for: .vertical) - statusView.headerIconImageView.setContentHuggingPriority(.defaultLow, for: .horizontal) - statusView.headerIconImageView.setContentCompressionResistancePriority(.defaultLow, for: .vertical) - statusView.headerIconImageView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) + statusView.headerInfoLabel.setContentHuggingPriority(.required - 1, for: .vertical) + statusView.headerInfoLabel.setContentCompressionResistancePriority(.required - 1, for: .vertical) + statusView.headerIconImageView.setContentHuggingPriority(.defaultLow - 100, for: .vertical) + statusView.headerIconImageView.setContentHuggingPriority(.defaultLow - 100, for: .horizontal) + statusView.headerIconImageView.setContentCompressionResistancePriority(.defaultLow - 100, for: .vertical) + statusView.headerIconImageView.setContentCompressionResistancePriority(.defaultLow - 100, for: .horizontal) // author container: H - [ avatarButton | author meta container | contentWarningToggleButton ] statusView.authorAdaptiveMarginContainerView.contentView = statusView.authorContainerView @@ -801,6 +808,17 @@ extension StatusView: ActionToolbarContainerDelegate { } } +// MARK: - StatusMetricViewDelegate +extension StatusView: StatusMetricViewDelegate { + func statusMetricView(_ statusMetricView: StatusMetricView, reblogButtonDidPressed button: UIButton) { + delegate?.statusView(self, statusMetricView: statusMetricView, reblogButtonDidPressed: button) + } + + func statusMetricView(_ statusMetricView: StatusMetricView, favoriteButtonDidPressed button: UIButton) { + delegate?.statusView(self, statusMetricView: statusMetricView, favoriteButtonDidPressed: button) + } +} + // MARK: - MastodonMenuDelegate extension StatusView: MastodonMenuDelegate { public func menuAction(_ action: MastodonMenu.Action) { diff --git a/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift b/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift index c3a9b96f3..4a5c44850 100644 --- a/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift +++ b/MastodonSDK/Sources/MastodonUI/View/Control/ActionToolbarContainer.swift @@ -216,7 +216,7 @@ extension ActionToolbarContainer { public func configureReply(count: Int, isEnabled: Bool) { let title = ActionToolbarContainer.title(from: count) replyButton.setTitle(title, for: .normal) - replyButton.accessibilityLabel = "\(count) reply" // TODO: i18n + replyButton.accessibilityLabel = L10n.Plural.Count.reply(count) } public func configureReblog(count: Int, isEnabled: Bool, isHighlighted: Bool) { diff --git a/MastodonSDK/Sources/MastodonUI/View/ImageView/AvatarImageView.swift b/MastodonSDK/Sources/MastodonUI/View/ImageView/AvatarImageView.swift index c0204bc65..0406b17f6 100644 --- a/MastodonSDK/Sources/MastodonUI/View/ImageView/AvatarImageView.swift +++ b/MastodonSDK/Sources/MastodonUI/View/ImageView/AvatarImageView.swift @@ -44,6 +44,11 @@ extension AvatarImageView { } } + private func setup(border: CornerConfiguration.Border?) { + layer.borderColor = border?.color.cgColor + layer.borderWidth = border?.width ?? .zero + } + } extension AvatarImageView { @@ -98,7 +103,11 @@ extension AvatarImageView { return ScaledToSizeFilter(size: self.frame.size) }() - af.setImage(withURL: url, filter: filter) + af.setImage( + withURL: url, + placeholderImage: configuration.placeholder, + filter: filter + ) } } @@ -107,9 +116,14 @@ extension AvatarImageView { extension AvatarImageView { public struct CornerConfiguration { public let corner: Corner + public let border: Border? - public init(corner: Corner = .circle) { + public init( + corner: Corner = .circle, + border: Border? = nil + ) { self.corner = corner + self.border = border } public enum Corner { @@ -117,10 +131,16 @@ extension AvatarImageView { case fixed(radius: CGFloat) case scale(ratio: Int = 4) // width / ratio } + + public struct Border { + public let color: UIColor + public let width: CGFloat + } } public func configure(cornerConfiguration: CornerConfiguration) { self.cornerConfiguration = cornerConfiguration setup(corner: cornerConfiguration.corner) + setup(border: cornerConfiguration.border) } } diff --git a/MastodonSDK/Sources/MastodonUI/View/TableViewCell/ProfileCardTableViewCell+Configuration.swift b/MastodonSDK/Sources/MastodonUI/View/TableViewCell/ProfileCardTableViewCell+Configuration.swift index 061af0f48..1274b7960 100644 --- a/MastodonSDK/Sources/MastodonUI/View/TableViewCell/ProfileCardTableViewCell+Configuration.swift +++ b/MastodonSDK/Sources/MastodonUI/View/TableViewCell/ProfileCardTableViewCell+Configuration.swift @@ -7,6 +7,7 @@ import UIKit import CoreDataStack +import MastodonSDK extension ProfileCardTableViewCell { diff --git a/MastodonSDK/Sources/MastodonUI/View/TableViewCell/ProfileCardTableViewCell.swift b/MastodonSDK/Sources/MastodonUI/View/TableViewCell/ProfileCardTableViewCell.swift index aff7b6feb..2d210f20c 100644 --- a/MastodonSDK/Sources/MastodonUI/View/TableViewCell/ProfileCardTableViewCell.swift +++ b/MastodonSDK/Sources/MastodonUI/View/TableViewCell/ProfileCardTableViewCell.swift @@ -11,6 +11,7 @@ import Combine public protocol ProfileCardTableViewCellDelegate: AnyObject { func profileCardTableViewCell(_ cell: ProfileCardTableViewCell, profileCardView: ProfileCardView, relationshipButtonDidPressed button: ProfileRelationshipActionButton) + func profileCardTableViewCell(_ cell: ProfileCardTableViewCell, profileCardView: ProfileCardView, familiarFollowersDashboardViewDidPressed view: FamiliarFollowersDashboardView) } public final class ProfileCardTableViewCell: UITableViewCell { @@ -86,7 +87,13 @@ extension ProfileCardTableViewCell { // MARK: - ProfileCardViewDelegate extension ProfileCardTableViewCell: ProfileCardViewDelegate { + public func profileCardView(_ profileCardView: ProfileCardView, relationshipButtonDidPressed button: ProfileRelationshipActionButton) { delegate?.profileCardTableViewCell(self, profileCardView: profileCardView, relationshipButtonDidPressed: button) } + + public func profileCardView(_ profileCardView: ProfileCardView, familiarFollowersDashboardViewDidPressed view: FamiliarFollowersDashboardView) { + delegate?.profileCardTableViewCell(self, profileCardView: profileCardView, familiarFollowersDashboardViewDidPressed: view) + } + } diff --git a/MastodonTests/Info.plist b/MastodonTests/Info.plist index 92f442892..bc0be73ac 100644 --- a/MastodonTests/Info.plist +++ b/MastodonTests/Info.plist @@ -15,8 +15,8 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.1 + 1.4.2 CFBundleVersion - 126 + 133 diff --git a/MastodonUITests/Info.plist b/MastodonUITests/Info.plist index 92f442892..bc0be73ac 100644 --- a/MastodonUITests/Info.plist +++ b/MastodonUITests/Info.plist @@ -15,8 +15,8 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.1 + 1.4.2 CFBundleVersion - 126 + 133 diff --git a/NotificationService/Info.plist b/NotificationService/Info.plist index f074db82b..31a95bf2b 100644 --- a/NotificationService/Info.plist +++ b/NotificationService/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.1 + 1.4.2 CFBundleVersion - 126 + 133 NSExtension NSExtensionPointIdentifier diff --git a/ShareActionExtension/Info.plist b/ShareActionExtension/Info.plist index 31c7447fe..7df1564a3 100644 --- a/ShareActionExtension/Info.plist +++ b/ShareActionExtension/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.4.1 + 1.4.2 CFBundleVersion - 126 + 133 NSExtension NSExtensionAttributes diff --git a/crowdin.yml b/crowdin.yml index 38421efa6..9fdca4a22 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -14,37 +14,37 @@ files: [ # Where translations will be placed # e.g. "/resources/%two_letters_code%/%original_file_name%" # - "translation" : "/Localization/StringsConvertor/input/%locale_with_underscore%/%original_file_name%", + "translation" : "/Localization/StringsConvertor/input/%osx_code%/%original_file_name%", # # The parameter "update_option" is optional. If it is not set, after the files update the translations for changed strings will be removed. Use to fix typos and for minor changes in the source strings # e.g. "update_as_unapproved" or "update_without_changes" # - "update_option" : "update_as_unapproved", + # "update_option" : "update_as_unapproved", # }, { # App info plist strings template "source" : "/Localization/ios-infoPlist.json", - "translation" : "/Localization/StringsConvertor/input/%locale_with_underscore%/%original_file_name%", + "translation" : "/Localization/StringsConvertor/input/%osx_code%/%original_file_name%", "update_option" : "update_as_unapproved", }, { # App strings dict "source" : "/Localization/Localizable.stringsdict", - "translation" : "/Localization/StringsConvertor/input/%locale_with_underscore%/%original_file_name%", - "update_option" : "update_as_unapproved", + "translation" : "/Localization/StringsConvertor/input/%osx_code%/%original_file_name%", + # "update_option" : "update_as_unapproved", }, { # intents strings "source" : "/MastodonIntent/en.lproj/Intents.strings", - "translation" : "/Localization/StringsConvertor/Intents/input/%locale_with_underscore%/%original_file_name%", - "update_option" : "update_as_unapproved", + "translation" : "/Localization/StringsConvertor/Intents/input/%osx_code%/%original_file_name%", + # "update_option" : "update_as_unapproved", }, { # intents strings dict "source" : "/MastodonIntent/en.lproj/Intents.stringsdict", - "translation" : "/Localization/StringsConvertor/Intents/input/%locale_with_underscore%/%original_file_name%", - "update_option" : "update_as_unapproved", + "translation" : "/Localization/StringsConvertor/Intents/input/%osx_code%/%original_file_name%", + # "update_option" : "update_as_unapproved", }, ] \ No newline at end of file