Merge branch 'release-1.4.4' into feature-purple-tint

# Conflicts:
#	AppShared/Info.plist
#	Mastodon.xcodeproj/project.pbxproj
#	Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist
#	Mastodon/Info.plist
#	MastodonIntent/Info.plist
#	MastodonTests/Info.plist
#	MastodonUITests/Info.plist
#	NotificationService/Info.plist
#	ShareActionExtension/Info.plist
This commit is contained in:
CMK 2022-06-14 14:28:35 +08:00
commit 34b3cad365
74 changed files with 700 additions and 282 deletions

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "يُتابِعُك"
},
"dashboard": {
"posts": "مَنشورات",
"following": "مُتابَع",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Et segueix"
},
"dashboard": {
"posts": "publicacions",
"following": "seguint",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "پۆستەکان",
"following": "شوێنکەوتن",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "postiadau",
"following": "following",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "posts",
"following": "following",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "Beiträge",
"following": "Gefolgte",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "posts",
"following": "following",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "posts",
"following": "following",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Te sigue"
},
"dashboard": {
"posts": "mensajes",
"following": "siguiendo",
@ -500,7 +503,7 @@
},
"searching": {
"segment": {
"all": "Todas",
"all": "Todo",
"people": "Cuentas",
"hashtags": "Etiquetas",
"posts": "Mensajes"
@ -565,10 +568,10 @@
},
"notifications": {
"title": "Notificaciones",
"favorites": "Marcó como favorito mi mensaje",
"favorites": "Marca mi mensaje como favorito",
"follows": "Me sigue",
"boosts": "Adhirió a mi mensaje",
"mentions": "Me mencionó",
"boosts": "Adhiere a mi mensaje",
"mentions": "Me menciona",
"trigger": {
"anyone": "cualquiera",
"follower": "un seguidor",
@ -582,7 +585,7 @@
"true_black_dark_mode": "Modo negro oscuro real",
"disable_avatar_animation": "Deshabilitar avatares animados",
"disable_emoji_animation": "Deshabilitar emojis animados",
"using_default_browser": "Usar navegador web predeterminado para abrir enlaces",
"using_default_browser": "Usar navegador web predet. para abrir enlaces",
"open_links_in_mastodon": "Abrir enlaces en Mastodon"
},
"boring_zone": {

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "publicaciones",
"following": "siguiendo",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "bidalketa",
"following": "jarraitzen",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "julkaisut",
"following": "seurataan",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "publications",
"following": "abonnements",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "postaichean",
"following": "a leantainn",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Séguete"
},
"dashboard": {
"posts": "publicacións",
"following": "seguindo",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "posts",
"following": "following",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "postingan",
"following": "mengikuti",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Ti segue"
},
"dashboard": {
"posts": "post",
"following": "seguendo",
@ -531,7 +534,7 @@
"Mentions": "Menzioni"
},
"notification_description": {
"followed_you": "ti ha seguito",
"followed_you": "ha iniziato a seguirti",
"favorited_your_post": "ha apprezzato il tuo post",
"reblogged_your_post": "ha condiviso il tuo post",
"mentioned_you": "ti ha menzionato",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "投稿",
"following": "フォロー",

View File

@ -72,9 +72,9 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<string>Yeṭṭafar-it %1$@, akked wayeḍ d ucrik</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
<string>Yeṭṭafar-it %1$@, akked %ld d ucriken</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
@ -104,9 +104,9 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 media</string>
<string>1 umidyat</string>
<key>other</key>
<string>%ld media</string>
<string>%ld yimidyaten</string>
</dict>
</dict>
<key>plural.count.post</key>

View File

@ -348,7 +348,7 @@
"Publishing": "Asuffeɣ tasuffeɣt...",
"accessibility": {
"logo_label": "Taqeffalt n ulugu",
"logo_hint": "Tap to scroll to top and tap again to previous location"
"logo_hint": "Sit i wakken ad tɛeddiḍ i usawen, sit tikkelt-nniḍen i wakken ad tɛeddiḍ ɣer wadig yezrin"
}
}
},
@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Yeṭṭafaṛ-ik•im"
},
"dashboard": {
"posts": "tisuffaɣ",
"following": "iṭafaṛ",
@ -470,14 +473,14 @@
"footer": "Ineḍfaren seg yiqeddacen-nniḍen ur d-ttwaskanen ara."
},
"familiarFollowers": {
"title": "Followers you familiar",
"followed_by_names": "Followed by %s"
"title": "Ineḍfaren i tessneḍ",
"followed_by_names": "Yeṭṭafar-it %s"
},
"favorited_by": {
"title": "Favorited By"
"title": "Ismenyaf-it"
},
"reblogged_by": {
"title": "Reblogged By"
"title": "Tettwasuffeɣ-d sɣur"
},
"search": {
"title": "Nadi",
@ -619,7 +622,7 @@
"step_one": {
"step_1_of_4": "Aḥric 1 seg 4",
"whats_wrong_with_this_post": "Acu n wugur yellan d tsuffeɣt-a?",
"whats_wrong_with_this_account": "What's wrong with this account?",
"whats_wrong_with_this_account": "Acu n wugur yellan deg umiḍan-a?",
"whats_wrong_with_this_username": "Acu n wugur yellan d %s?",
"select_the_best_match": "Fren amṣada akk igerrzen",
"i_dont_like_it": "Ur ḥemmleɣ ara aya",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Te dişopîne"
},
"dashboard": {
"posts": "şandî",
"following": "dişopîne",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "게시물",
"following": "팔로잉",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "berichten",
"following": "volgend",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "posts",
"following": "following",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "posts",
"following": "following",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "posts",
"following": "following",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Подписан(а) на вас"
},
"dashboard": {
"posts": "посты",
"following": "подписки",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "inlägg",
"following": "följer",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "โพสต์",
"following": "กำลังติดตาม",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "gönderiler",
"following": "takip ediliyor",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Đang theo dõi bạn"
},
"dashboard": {
"posts": "tút",
"following": "theo dõi",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "关注了你"
},
"dashboard": {
"posts": "帖子",
"following": "正在关注",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "跟隨了您"
},
"dashboard": {
"posts": "嘟文",
"following": "跟隨中",

View File

@ -417,6 +417,9 @@
}
},
"profile": {
"header": {
"follows_you": "Follows You"
},
"dashboard": {
"posts": "posts",
"following": "following",

View File

@ -108,7 +108,7 @@
5E0DEC05797A7E6933788DDB /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */; };
5E44BF88AD33646E64727BCF /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */; };
87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; };
DB0009A626AEE5DC009B9D2D /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = DB0009A926AEE5DC009B9D2D /* Intents.intentdefinition */; settings = {ATTRIBUTES = (no_codegen, ); }; };
DB0009A626AEE5DC009B9D2D /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = DB0009A926AEE5DC009B9D2D /* Intents.intentdefinition */; settings = {ATTRIBUTES = (codegen, ); }; };
DB0009A726AEE5DC009B9D2D /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = DB0009A926AEE5DC009B9D2D /* Intents.intentdefinition */; };
DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140CE25C42AEE00F9F3CF /* OSLog.swift */; };
DB023D26279FFB0A005AC798 /* ShareActivityProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB023D25279FFB0A005AC798 /* ShareActivityProvider.swift */; };
@ -346,6 +346,8 @@
DB63F779279ABF9C00455B82 /* DataSourceFacade+Reblog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F778279ABF9C00455B82 /* DataSourceFacade+Reblog.swift */; };
DB63F77B279ACAE500455B82 /* DataSourceFacade+Favorite.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB63F77A279ACAE500455B82 /* DataSourceFacade+Favorite.swift */; };
DB647C5926F1EA2700F7F82C /* WizardPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB647C5826F1EA2700F7F82C /* WizardPreference.swift */; };
DB64BA452851F23000ADF1B7 /* MastodonAuthentication+Fetch.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB64BA442851F23000ADF1B7 /* MastodonAuthentication+Fetch.swift */; };
DB64BA482851F29300ADF1B7 /* Account+Fetch.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB64BA472851F29300ADF1B7 /* Account+Fetch.swift */; };
DB65C63727A2AF6C008BAC2E /* ReportItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB65C63627A2AF6C008BAC2E /* ReportItem.swift */; };
DB66728C25F9F8DC00D60309 /* ComposeViewModel+DataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB66728B25F9F8DC00D60309 /* ComposeViewModel+DataSource.swift */; };
DB66729625F9F91600D60309 /* ComposeStatusSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB66729525F9F91600D60309 /* ComposeStatusSection.swift */; };
@ -649,13 +651,6 @@
remoteGlobalIDString = DB68047E2637CD4C00430867;
remoteInfo = AppShared;
};
DB6804C92637CE3000430867 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DB427DCA25BAA00100D1B89D /* Project object */;
proxyType = 1;
remoteGlobalIDString = DB68047E2637CD4C00430867;
remoteInfo = AppShared;
};
DB8FABCC26AEC7B2008E5AF4 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DB427DCA25BAA00100D1B89D /* Project object */;
@ -1112,6 +1107,8 @@
DB63F778279ABF9C00455B82 /* DataSourceFacade+Reblog.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Reblog.swift"; sourceTree = "<group>"; };
DB63F77A279ACAE500455B82 /* DataSourceFacade+Favorite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Favorite.swift"; sourceTree = "<group>"; };
DB647C5826F1EA2700F7F82C /* WizardPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardPreference.swift; sourceTree = "<group>"; };
DB64BA442851F23000ADF1B7 /* MastodonAuthentication+Fetch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonAuthentication+Fetch.swift"; sourceTree = "<group>"; };
DB64BA472851F29300ADF1B7 /* Account+Fetch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Fetch.swift"; sourceTree = "<group>"; };
DB65C63627A2AF6C008BAC2E /* ReportItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportItem.swift; sourceTree = "<group>"; };
DB66728B25F9F8DC00D60309 /* ComposeViewModel+DataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ComposeViewModel+DataSource.swift"; sourceTree = "<group>"; };
DB66729525F9F91600D60309 /* ComposeStatusSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeStatusSection.swift; sourceTree = "<group>"; };
@ -2601,6 +2598,23 @@
path = NotificationTimeline;
sourceTree = "<group>";
};
DB64BA462851F23300ADF1B7 /* Model */ = {
isa = PBXGroup;
children = (
DB64BA442851F23000ADF1B7 /* MastodonAuthentication+Fetch.swift */,
DB64BA472851F29300ADF1B7 /* Account+Fetch.swift */,
);
path = Model;
sourceTree = "<group>";
};
DB64BA492851F65F00ADF1B7 /* Handler */ = {
isa = PBXGroup;
children = (
DBB8AB4526AECDE200F6D281 /* SendPostIntentHandler.swift */,
);
path = Handler;
sourceTree = "<group>";
};
DB65C63527A2AF52008BAC2E /* Report */ = {
isa = PBXGroup;
children = (
@ -2892,7 +2906,8 @@
DBA4B0F926C269880077136E /* Intents.stringsdict */,
DB8FABD626AEC864008E5AF4 /* MastodonIntent.entitlements */,
DB8FABC926AEC7B2008E5AF4 /* IntentHandler.swift */,
DBB8AB4526AECDE200F6D281 /* SendPostIntentHandler.swift */,
DB64BA462851F23300ADF1B7 /* Model */,
DB64BA492851F65F00ADF1B7 /* Handler */,
DBB8AB4B26AED0B800F6D281 /* Service */,
DB8FABCB26AEC7B2008E5AF4 /* Info.plist */,
);
@ -3413,13 +3428,13 @@
buildConfigurationList = DB427DFC25BAA00100D1B89D /* Build configuration list for PBXNativeTarget "Mastodon" */;
buildPhases = (
7A04933A2AB1D5B758D4F908 /* [CP] Check Pods Manifest.lock */,
DB3D100425BAA71500EAA174 /* ShellScript */,
5532CB85BBE168B25B20720B /* [CP] Embed Pods Frameworks */,
DB427DD025BAA00100D1B89D /* Resources */,
DB427DCE25BAA00100D1B89D /* Sources */,
DB427DCF25BAA00100D1B89D /* Frameworks */,
DB427DD025BAA00100D1B89D /* Resources */,
5532CB85BBE168B25B20720B /* [CP] Embed Pods Frameworks */,
DB89BA0825C10FD0008580ED /* Embed Frameworks */,
DBF8AE1B263293E400C9C23C /* Embed App Extensions */,
DB3D100425BAA71500EAA174 /* ShellScript */,
DB025B8E278D6448002F581E /* ShellScript */,
DB697DD2278F48D5004EF2F7 /* ShellScript */,
);
@ -3428,7 +3443,6 @@
dependencies = (
DBF8AE19263293E400C9C23C /* PBXTargetDependency */,
DB6804852637CD4C00430867 /* PBXTargetDependency */,
DB6804CA2637CE3000430867 /* PBXTargetDependency */,
DBC6461B26A170AB00B0E31B /* PBXTargetDependency */,
DB8FABCD26AEC7B2008E5AF4 /* PBXTargetDependency */,
);
@ -4487,6 +4501,8 @@
DBB8AB4626AECDE200F6D281 /* SendPostIntentHandler.swift in Sources */,
DBB8AB4A26AED0B500F6D281 /* APIService.swift in Sources */,
DBB8AB4C26AED11300F6D281 /* APIService+APIError.swift in Sources */,
DB64BA452851F23000ADF1B7 /* MastodonAuthentication+Fetch.swift in Sources */,
DB64BA482851F29300ADF1B7 /* Account+Fetch.swift in Sources */,
DB6746E9278ED63F008A6B94 /* MastodonAuthenticationBox.swift in Sources */,
DBB8AB5226AED1B300F6D281 /* APIService+Status+Publish.swift in Sources */,
DB8FABCA26AEC7B2008E5AF4 /* IntentHandler.swift in Sources */,
@ -4555,11 +4571,6 @@
target = DB68047E2637CD4C00430867 /* AppShared */;
targetProxy = DB6804A72637CDCC00430867 /* PBXContainerItemProxy */;
};
DB6804CA2637CE3000430867 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DB68047E2637CD4C00430867 /* AppShared */;
targetProxy = DB6804C92637CE3000430867 /* PBXContainerItemProxy */;
};
DB8FABCD26AEC7B2008E5AF4 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DB8FABC526AEC7B2008E5AF4 /* MastodonIntent */;
@ -4839,7 +4850,7 @@
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@ -4869,7 +4880,7 @@
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@ -4977,11 +4988,11 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 139;
DYLIB_CURRENT_VERSION = 140;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = AppShared/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@ -5008,11 +5019,11 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 139;
DYLIB_CURRENT_VERSION = 140;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = AppShared/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@ -5103,7 +5114,7 @@
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@ -5171,11 +5182,11 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 139;
DYLIB_CURRENT_VERSION = 140;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = AppShared/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@ -5200,7 +5211,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5223,7 +5234,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5247,7 +5258,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = MastodonIntent/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5271,7 +5282,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = MastodonIntent/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5295,7 +5306,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = MastodonIntent/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5319,7 +5330,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5343,7 +5354,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5430,7 +5441,7 @@
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@ -5497,11 +5508,11 @@
APPLICATION_EXTENSION_API_ONLY = YES;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEFINES_MODULE = YES;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 139;
DYLIB_CURRENT_VERSION = 140;
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = AppShared/Info.plist;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
@ -5525,7 +5536,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5548,7 +5559,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5572,7 +5583,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = MastodonIntent/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5596,7 +5607,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@ -5619,7 +5630,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 139;
CURRENT_PROJECT_VERSION = 140;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (

View File

@ -64,13 +64,8 @@ final class ProfileAboutViewModel {
guard let self = self else { return }
guard let account = account else { return }
self.profileInfo.fields = account.source?.fields?.compactMap { field in
ProfileFieldItem.FieldValue(
name: field.name,
value: field.value,
emojiMeta: emojiMeta
)
} ?? []
// update profileInfo will occurs race condition issue
// bind user.fields to profileInfo to avoid it
self.profileInfoEditing.fields = account.source?.fields?.compactMap { field in
ProfileFieldItem.FieldValue(

View File

@ -88,6 +88,13 @@ extension ProfileHeaderView.ViewModel {
)
}
.store(in: &disposeBag)
// follows you
$relationshipActionOptionSet
.map { $0.contains(.followingBy) && !$0.contains(.isMyself) }
.sink { isFollowingBy in
view.followsYouBlurEffectView.isHidden = !isFollowingBy
}
.store(in: &disposeBag)
// avatar
Publishers.CombineLatest4(
$avatarImageURL,
@ -102,7 +109,7 @@ extension ProfileHeaderView.ViewModel {
))
}
.store(in: &disposeBag)
// blur
// blur for blocking & blockingBy
$relationshipActionOptionSet
.map { $0.contains(.blocking) || $0.contains(.blockingBy) }
.sink { needsImageOverlayBlurred in

View File

@ -72,6 +72,16 @@ final class ProfileHeaderView: UIView {
var bannerImageViewTopLayoutConstraint: NSLayoutConstraint!
var bannerImageViewBottomLayoutConstraint: NSLayoutConstraint!
let followsYouBlurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
let followsYouVibrantEffectView = UIVisualEffectView(effect: UIVibrancyEffect(blurEffect: UIBlurEffect(style: .regular), style: .label))
let followsYouLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 15, weight: .regular)
label.text = "Follows You" // TODO: i18n
return label
}()
let followsYouMaskView = UIView()
let avatarImageViewBackgroundView: UIView = {
let view = UIView()
view.layer.masksToBounds = true
@ -174,9 +184,6 @@ final class ProfileHeaderView: UIView {
return button
}()
// let bioContainerView = UIView()
// let fieldContainerStackView = UIStackView()
let bioMetaText: MetaText = {
let metaText = MetaText()
metaText.textView.backgroundColor = .clear
@ -263,6 +270,40 @@ extension ProfileHeaderView {
bannerImageViewOverlayVisualEffectView.bottomAnchor.constraint(equalTo: bannerImageView.bottomAnchor),
])
// follows you
followsYouBlurEffectView.translatesAutoresizingMaskIntoConstraints = false
addSubview(followsYouBlurEffectView)
NSLayoutConstraint.activate([
layoutMarginsGuide.trailingAnchor.constraint(equalTo: followsYouBlurEffectView.trailingAnchor),
bannerContainerView.bottomAnchor.constraint(equalTo: followsYouBlurEffectView.bottomAnchor, constant: 16),
])
followsYouBlurEffectView.layer.masksToBounds = true
followsYouBlurEffectView.layer.cornerRadius = 8
followsYouBlurEffectView.layer.cornerCurve = .continuous
followsYouBlurEffectView.isHidden = true
followsYouVibrantEffectView.translatesAutoresizingMaskIntoConstraints = false
followsYouBlurEffectView.contentView.addSubview(followsYouVibrantEffectView)
NSLayoutConstraint.activate([
followsYouVibrantEffectView.topAnchor.constraint(equalTo: followsYouBlurEffectView.topAnchor),
followsYouVibrantEffectView.leadingAnchor.constraint(equalTo: followsYouBlurEffectView.leadingAnchor),
followsYouVibrantEffectView.trailingAnchor.constraint(equalTo: followsYouBlurEffectView.trailingAnchor),
followsYouVibrantEffectView.bottomAnchor.constraint(equalTo: followsYouBlurEffectView.bottomAnchor),
])
followsYouLabel.translatesAutoresizingMaskIntoConstraints = false
followsYouVibrantEffectView.contentView.addSubview(followsYouLabel)
NSLayoutConstraint.activate([
followsYouLabel.topAnchor.constraint(equalTo: followsYouVibrantEffectView.topAnchor, constant: 4),
followsYouLabel.leadingAnchor.constraint(equalTo: followsYouVibrantEffectView.leadingAnchor, constant: 6),
followsYouVibrantEffectView.trailingAnchor.constraint(equalTo: followsYouLabel.trailingAnchor, constant: 6),
followsYouVibrantEffectView.bottomAnchor.constraint(equalTo: followsYouLabel.bottomAnchor, constant: 4),
])
followsYouMaskView.frame = CGRect(x: 0, y: 0, width: 1000, height: 1000)
followsYouMaskView.backgroundColor = .red
followsYouBlurEffectView.mask = followsYouMaskView
// avatar
avatarImageViewBackgroundView.translatesAutoresizingMaskIntoConstraints = false
addSubview(avatarImageViewBackgroundView)
@ -406,6 +447,7 @@ extension ProfileHeaderView {
container.addArrangedSubview(bioMetaText.textView)
bringSubviewToFront(bannerContainerView)
bringSubviewToFront(followsYouBlurEffectView)
bringSubviewToFront(avatarImageViewBackgroundView)
statusDashboardView.delegate = self

View File

@ -305,7 +305,10 @@ extension ProfileViewController {
}
// about
let aboutViewModel = profilePagingViewController.viewModel.profileAboutViewController.viewModel!
let aboutViewModel = viewModel.profileAboutViewModel
viewModel.$user
.assign(to: \.user, on: aboutViewModel)
.store(in: &disposeBag)
viewModel.$isEditing
.assign(to: \.isEditing, on: aboutViewModel)
.store(in: &disposeBag)
@ -584,6 +587,22 @@ extension ProfileViewController: TabBarPagerDelegate {
progress = 0
}
// setup follows you mask
// 1. set mask size
profileHeaderViewController.profileHeaderView.followsYouMaskView.frame = profileHeaderViewController.profileHeaderView.followsYouBlurEffectView.bounds
// 2. check follows you view overflow navigation bar or not
let followsYouBlurEffectViewInWindow = profileHeaderViewController.profileHeaderView.convert(
profileHeaderViewController.profileHeaderView.followsYouBlurEffectView.frame,
to: nil
)
if followsYouBlurEffectViewInWindow.minY < tabBarPagerController.containerScrollView.safeAreaInsets.top {
let offestY = tabBarPagerController.containerScrollView.safeAreaInsets.top - followsYouBlurEffectViewInWindow.minY
let height = profileHeaderViewController.profileHeaderView.followsYouMaskView.frame.height
profileHeaderViewController.profileHeaderView.followsYouMaskView.frame.origin.y = min(offestY, height)
} else {
profileHeaderViewController.profileHeaderView.followsYouMaskView.frame.origin.y = .zero
}
// setup titleView offset and fade avatar
profileHeaderViewController.updateHeaderScrollProgress(progress, throttle: throttle)

View File

@ -163,7 +163,7 @@ class ProfileViewModel: NSObject {
} // end Task
}
.store(in: &disposeBag)
//
let isBlockingOrBlocked = Publishers.CombineLatest(
relationshipViewModel.$isBlocking,
relationshipViewModel.$isBlockingBy

View File

@ -37,11 +37,8 @@ extension APIService {
]
case .mentions:
return [
.follow,
.followRequest,
.reblog,
.favourite,
.poll
.mention,
.status,
]
}
}(),

View File

@ -53,11 +53,11 @@
<key>INIntentDefinitionNamespace</key>
<string>BvMBE4</string>
<key>INIntentDefinitionSystemVersion</key>
<string>20G80</string>
<string>21F79</string>
<key>INIntentDefinitionToolsBuildVersion</key>
<string>12E507</string>
<string>13F100</string>
<key>INIntentDefinitionToolsVersion</key>
<string>12.5.1</string>
<string>13.4.1</string>
<key>INIntents</key>
<array>
<dict>
@ -74,10 +74,10 @@
<key>INIntentKeyParameter</key>
<string>content</string>
<key>INIntentLastParameterTag</key>
<integer>3</integer>
<integer>6</integer>
<key>INIntentManagedParameterCombinations</key>
<dict>
<key>content,visibility</key>
<key>content,visibility,accounts</key>
<dict>
<key>INIntentParameterCombinationSupportsBackgroundExecution</key>
<true/>
@ -91,6 +91,19 @@
<string>SendPost</string>
<key>INIntentParameterCombinations</key>
<dict>
<key>accounts,visibility,content</key>
<dict>
<key>INIntentParameterCombinationSubtitle</key>
<string>${content}. Post via ${accounts}. (${visibility})</string>
<key>INIntentParameterCombinationSubtitleID</key>
<string>YMuITB</string>
<key>INIntentParameterCombinationSupportsBackgroundExecution</key>
<true/>
<key>INIntentParameterCombinationTitle</key>
<string>Post on Mastodon</string>
<key>INIntentParameterCombinationTitleID</key>
<string>D2h76g</string>
</dict>
<key>content</key>
<dict>
<key>INIntentParameterCombinationSubtitle</key>
@ -109,7 +122,7 @@
<key>INIntentParameterCombinationIsPrimary</key>
<true/>
<key>INIntentParameterCombinationSubtitle</key>
<string>${content}, ${visibility}</string>
<string>${content}. (${visibility})</string>
<key>INIntentParameterCombinationSubtitleID</key>
<string>ayoYEb</string>
<key>INIntentParameterCombinationSupportsBackgroundExecution</key>
@ -170,6 +183,69 @@
<key>INIntentParameterType</key>
<string>String</string>
</dict>
<dict>
<key>INIntentParameterConfigurable</key>
<true/>
<key>INIntentParameterCustomDisambiguation</key>
<true/>
<key>INIntentParameterDisplayName</key>
<string>Accounts</string>
<key>INIntentParameterDisplayNameID</key>
<string>nQtHsT</string>
<key>INIntentParameterDisplayPriority</key>
<integer>2</integer>
<key>INIntentParameterName</key>
<string>accounts</string>
<key>INIntentParameterObjectType</key>
<string>Account</string>
<key>INIntentParameterObjectTypeNamespace</key>
<string>BvMBE4</string>
<key>INIntentParameterPromptDialogs</key>
<array>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogType</key>
<string>Configuration</string>
</dict>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogType</key>
<string>Primary</string>
</dict>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogFormatString</key>
<string>There are ${count} options matching ${accounts}.</string>
<key>INIntentParameterPromptDialogFormatStringID</key>
<string>ciITyC</string>
<key>INIntentParameterPromptDialogType</key>
<string>DisambiguationIntroduction</string>
</dict>
<dict>
<key>INIntentParameterPromptDialogCustom</key>
<true/>
<key>INIntentParameterPromptDialogFormatString</key>
<string>Just to confirm, you wanted ${accounts}?</string>
<key>INIntentParameterPromptDialogFormatStringID</key>
<string>4kVQfr</string>
<key>INIntentParameterPromptDialogType</key>
<string>Confirmation</string>
</dict>
</array>
<key>INIntentParameterSupportsDynamicEnumeration</key>
<true/>
<key>INIntentParameterSupportsMultipleValues</key>
<true/>
<key>INIntentParameterSupportsResolution</key>
<true/>
<key>INIntentParameterTag</key>
<integer>6</integer>
<key>INIntentParameterType</key>
<string>Object</string>
</dict>
<dict>
<key>INIntentParameterConfigurable</key>
<true/>
@ -180,7 +256,7 @@
<key>INIntentParameterDisplayNameID</key>
<string>ZbSjzC</string>
<key>INIntentParameterDisplayPriority</key>
<integer>2</integer>
<integer>3</integer>
<key>INIntentParameterEnumType</key>
<string>PostVisibility</string>
<key>INIntentParameterEnumTypeNamespace</key>
@ -267,26 +343,28 @@
</dict>
</array>
<key>INIntentResponseLastParameterTag</key>
<integer>7</integer>
<integer>8</integer>
<key>INIntentResponseOutput</key>
<string>post</string>
<string>posts</string>
<key>INIntentResponseParameters</key>
<array>
<dict>
<key>INIntentResponseParameterDisplayName</key>
<string>Post</string>
<string>Posts</string>
<key>INIntentResponseParameterDisplayNameID</key>
<string>ZKJSNu</string>
<key>INIntentResponseParameterDisplayPriority</key>
<integer>1</integer>
<key>INIntentResponseParameterName</key>
<string>post</string>
<string>posts</string>
<key>INIntentResponseParameterObjectType</key>
<string>Post</string>
<key>INIntentResponseParameterObjectTypeNamespace</key>
<string>BvMBE4</string>
<key>INIntentResponseParameterSupportsMultipleValues</key>
<true/>
<key>INIntentResponseParameterTag</key>
<integer>6</integer>
<integer>8</integer>
<key>INIntentResponseParameterType</key>
<string>Object</string>
</dict>
@ -395,6 +473,97 @@
</dict>
</array>
</dict>
<dict>
<key>INTypeDisplayName</key>
<string>Account</string>
<key>INTypeDisplayNameID</key>
<string>Gcmnot</string>
<key>INTypeLastPropertyTag</key>
<integer>101</integer>
<key>INTypeName</key>
<string>Account</string>
<key>INTypeProperties</key>
<array>
<dict>
<key>INTypePropertyDefault</key>
<true/>
<key>INTypePropertyDisplayPriority</key>
<integer>1</integer>
<key>INTypePropertyName</key>
<string>identifier</string>
<key>INTypePropertyTag</key>
<integer>1</integer>
<key>INTypePropertyType</key>
<string>String</string>
</dict>
<dict>
<key>INTypePropertyDefault</key>
<true/>
<key>INTypePropertyDisplayPriority</key>
<integer>2</integer>
<key>INTypePropertyName</key>
<string>displayString</string>
<key>INTypePropertyTag</key>
<integer>2</integer>
<key>INTypePropertyType</key>
<string>String</string>
</dict>
<dict>
<key>INTypePropertyDefault</key>
<true/>
<key>INTypePropertyDisplayPriority</key>
<integer>3</integer>
<key>INTypePropertyName</key>
<string>pronunciationHint</string>
<key>INTypePropertyTag</key>
<integer>3</integer>
<key>INTypePropertyType</key>
<string>String</string>
</dict>
<dict>
<key>INTypePropertyDefault</key>
<true/>
<key>INTypePropertyDisplayPriority</key>
<integer>4</integer>
<key>INTypePropertyName</key>
<string>alternativeSpeakableMatches</string>
<key>INTypePropertySupportsMultipleValues</key>
<true/>
<key>INTypePropertyTag</key>
<integer>4</integer>
<key>INTypePropertyType</key>
<string>SpeakableString</string>
</dict>
<dict>
<key>INTypePropertyDisplayName</key>
<string>Name</string>
<key>INTypePropertyDisplayNameID</key>
<string>Zim0Js</string>
<key>INTypePropertyDisplayPriority</key>
<integer>5</integer>
<key>INTypePropertyName</key>
<string>name</string>
<key>INTypePropertyTag</key>
<integer>100</integer>
<key>INTypePropertyType</key>
<string>String</string>
</dict>
<dict>
<key>INTypePropertyDisplayName</key>
<string>Username</string>
<key>INTypePropertyDisplayNameID</key>
<string>3sNRTG</string>
<key>INTypePropertyDisplayPriority</key>
<integer>6</integer>
<key>INTypePropertyName</key>
<string>username</string>
<key>INTypePropertyTag</key>
<integer>101</integer>
<key>INTypePropertyType</key>
<string>String</string>
</dict>
</array>
</dict>
</array>
</dict>
</plist>

View File

@ -0,0 +1,152 @@
//
// SendPostIntentHandler.swift
// MastodonIntent
//
// Created by Cirno MainasuK on 2021-7-26.
//
import Foundation
import Intents
import Combine
import CoreData
import CoreDataStack
import MastodonSDK
final class SendPostIntentHandler: NSObject {
var disposeBag = Set<AnyCancellable>()
let coreDataStack = CoreDataStack()
lazy var managedObjectContext = coreDataStack.persistentContainer.viewContext
lazy var api = APIService.shared
}
// MARK: - SendPostIntentHandling
extension SendPostIntentHandler: SendPostIntentHandling {
func handle(intent: SendPostIntent) async -> SendPostIntentResponse {
guard let content = intent.content else {
return SendPostIntentResponse(code: .failure, userActivity: nil)
}
let visibility: Mastodon.Entity.Status.Visibility = {
switch intent.visibility {
case .unknown: return .public
case .public: return .public
case .followersOnly: return .private
}
}()
do {
// fetch authentications from
// user pick accounts
// or fallback to active account
let mastodonAuthentications: [MastodonAuthentication]
let accounts = intent.accounts ?? []
if accounts.isEmpty {
let request = MastodonAuthentication.sortedFetchRequest
let authentications = try managedObjectContext.fetch(request)
let _authentication = authentications.sorted(by: { $0.activedAt > $1.activedAt }).first
guard let authentication = _authentication else {
let failureReason = APIService.APIError.implicit(.authenticationMissing).errorDescription ?? "Fail to Send Post"
return SendPostIntentResponse.failure(failureReason: failureReason)
}
mastodonAuthentications = [authentication]
} else {
mastodonAuthentications = try accounts.mastodonAuthentication(in: managedObjectContext)
}
let authenticationBoxes = mastodonAuthentications.map { authentication in
MastodonAuthenticationBox(
authenticationRecord: .init(objectID: authentication.objectID),
domain: authentication.domain,
userID: authentication.userID,
appAuthorization: .init(accessToken: authentication.appAccessToken),
userAuthorization: .init(accessToken: authentication.userAccessToken)
)
}
var posts: [Post] = []
for authenticationBox in authenticationBoxes {
let idempotencyKey = UUID().uuidString
let response = try await api.publishStatus(
domain: authenticationBox.domain,
idempotencyKey: idempotencyKey,
query: .init(
status: content,
mediaIDs: nil,
pollOptions: nil,
pollExpiresIn: nil,
inReplyToID: nil,
sensitive: nil,
spoilerText: nil,
visibility: visibility
),
authenticationBox: authenticationBox
)
let post = Post(
identifier: response.value.id,
display: response.value.account.acct,
subtitle: content,
image: response.value.account.avatarImageURL().flatMap { INImage(url: $0) }
)
posts.append(post)
} // end for in
let intentResponse = SendPostIntentResponse(code: .success, userActivity: nil)
intentResponse.posts = posts
return intentResponse
} catch {
let intentResponse = SendPostIntentResponse(code: .failure, userActivity: nil)
if let error = error as? LocalizedError {
intentResponse.failureReason = [
error.errorDescription,
error.failureReason,
error.recoverySuggestion
]
.compactMap { $0 }
.joined(separator: ", ")
} else {
intentResponse.failureReason = error.localizedDescription
}
return intentResponse
}
} // end func
// content
func resolveContent(for intent: SendPostIntent, with completion: @escaping (INStringResolutionResult) -> Void) {
guard let content = intent.content, !content.isEmpty else {
completion(.needsValue())
return
}
completion(.success(with: content))
}
// accounts
func resolveAccounts(for intent: SendPostIntent) async -> [AccountResolutionResult] {
guard let accounts = intent.accounts, !accounts.isEmpty else {
return [AccountResolutionResult.needsValue()]
}
let results = accounts.map { account in
AccountResolutionResult.success(with: account)
}
return results
}
func provideAccountsOptionsCollection(for intent: SendPostIntent) async throws -> INObjectCollection<Account> {
let accounts = try await Account.fetch(in: managedObjectContext)
return .init(items: accounts)
}
// visibility
func resolveVisibility(for intent: SendPostIntent, with completion: @escaping (PostVisibilityResolutionResult) -> Void) {
completion(.success(with: intent.visibility))
}
}

View File

@ -0,0 +1,51 @@
//
// Account.swift
// MastodonIntent
//
// Created by MainasuK on 2022-6-9.
//
import Foundation
import CoreData
import CoreDataStack
import Intents
extension Account {
@MainActor
static func fetch(in managedObjectContext: NSManagedObjectContext) async throws -> [Account] {
// get accounts
let accounts: [Account] = try await managedObjectContext.perform {
let results = try MastodonAuthentication.fetch(in: managedObjectContext)
let accounts = results.compactMap { mastodonAuthentication -> Account? in
let user = mastodonAuthentication.user
let account = Account(
identifier: mastodonAuthentication.identifier.uuidString,
display: user.displayNameWithFallback,
subtitle: user.acctWithDomain,
image: user.avatarImageURL().flatMap { INImage(url: $0) }
)
account.name = user.displayNameWithFallback
account.username = user.acctWithDomain
return account
}
return accounts
} // end managedObjectContext.perform
return accounts
}
}
extension Array where Element == Account {
func mastodonAuthentication(in managedObjectContext: NSManagedObjectContext) throws -> [MastodonAuthentication] {
let identifiers = self
.compactMap { $0.identifier }
.compactMap { UUID(uuidString: $0) }
let request = MastodonAuthentication.sortedFetchRequest
request.predicate = MastodonAuthentication.predicate(identifiers: identifiers)
let results = try managedObjectContext.fetch(request)
return results
}
}

View File

@ -0,0 +1,20 @@
//
// MastodonAuthentication.swift
// MastodonIntent
//
// Created by MainasuK on 2022-6-9.
//
import Foundation
import CoreData
import CoreDataStack
extension MastodonAuthentication {
static func fetch(in managedObjectContext: NSManagedObjectContext) throws -> [MastodonAuthentication] {
let request = MastodonAuthentication.sortedFetchRequest
let results = try managedObjectContext.fetch(request)
return results
}
}

View File

@ -1,106 +0,0 @@
//
// SendPostIntentHandler.swift
// MastodonIntent
//
// Created by Cirno MainasuK on 2021-7-26.
//
import Foundation
import Intents
import Combine
import CoreData
import CoreDataStack
import MastodonSDK
final class SendPostIntentHandler: NSObject, SendPostIntentHandling {
var disposeBag = Set<AnyCancellable>()
lazy var coreDataStack = CoreDataStack()
lazy var managedObjectContext = coreDataStack.persistentContainer.viewContext
func handle(intent: SendPostIntent, completion: @escaping (SendPostIntentResponse) -> Void) {
managedObjectContext.performAndWait {
let request = MastodonAuthentication.sortedFetchRequest
let authentications = (try? self.managedObjectContext.fetch(request)) ?? []
let _authentication = authentications.sorted(by: { $0.activedAt > $1.activedAt }).first
guard let authentication = _authentication else {
let failureReason = APIService.APIError.implicit(.authenticationMissing).errorDescription ?? "Fail to Send Post"
completion(SendPostIntentResponse.failure(failureReason: failureReason))
return
}
let box = MastodonAuthenticationBox(
authenticationRecord: .init(objectID: authentication.objectID),
domain: authentication.domain,
userID: authentication.userID,
appAuthorization: .init(accessToken: authentication.appAccessToken),
userAuthorization: .init(accessToken: authentication.userAccessToken)
)
let visibility: Mastodon.Entity.Status.Visibility = {
switch intent.visibility {
case .unknown: return .public
case .public: return .public
case .followersOnly: return .private
}
}()
let query = Mastodon.API.Statuses.PublishStatusQuery(
status: intent.content,
mediaIDs: nil,
pollOptions: nil,
pollExpiresIn: nil,
inReplyToID: nil,
sensitive: nil,
spoilerText: nil,
visibility: visibility
)
let idempotencyKey = UUID().uuidString
Just(Void())
.asyncMap {
try await APIService.shared.publishStatus(
domain: box.domain,
idempotencyKey: idempotencyKey,
query: query,
authenticationBox: box
)
}
.sink { _completion in
switch _completion {
case .failure(let error):
let failureReason = error.localizedDescription
completion(SendPostIntentResponse.failure(failureReason: failureReason))
case .finished:
break
}
} receiveValue: { response in
let post = Post(identifier: response.value.id, display: intent.content ?? "")
post.url = URL(string: response.value.url ?? response.value.uri)
let result = SendPostIntentResponse(code: .success, userActivity: nil)
result.post = post
completion(result)
}
.store(in: &disposeBag)
}
}
func resolveContent(for intent: SendPostIntent, with completion: @escaping (INStringResolutionResult) -> Void) {
guard let content = intent.content, !content.isEmpty else {
completion(.needsValue())
return
}
completion(.success(with: content))
}
func resolveVisibility(for intent: SendPostIntent, with completion: @escaping (PostVisibilityResolutionResult) -> Void) {
completion(.success(with: intent.visibility))
}
}

View File

@ -171,4 +171,12 @@ extension MastodonAuthentication {
return NSPredicate(format: "%K == %@", #keyPath(MastodonAuthentication.userAccessToken), userAccessToken)
}
public static func predicate(identifier: UUID) -> NSPredicate {
return NSPredicate(format: "%K == %@", #keyPath(MastodonAuthentication.identifier), identifier as NSUUID)
}
public static func predicate(identifiers: [UUID]) -> NSPredicate {
return NSPredicate(format: "%K IN %@", #keyPath(MastodonAuthentication.identifier), identifiers as [NSUUID])
}
}

View File

@ -363,82 +363,6 @@ extension MastodonUser: AutoGenerateProperty {
// sourcery:end
}
//extension MastodonUser {
// public struct Property {
// public let identifier: String
// public let domain: String
//
// public let id: String
// public let acct: String
// public let username: String
// public let displayName: String
// public let avatar: String
// public let avatarStatic: String?
// public let header: String
// public let headerStatic: String?
// public let note: String?
// public let url: String?
// public let emojisData: Data?
// public let fieldsData: Data?
// public let statusesCount: Int
// public let followingCount: Int
// public let followersCount: Int
// public let locked: Bool
// public let bot: Bool?
// public let suspended: Bool?
//
// public let createdAt: Date
// public let networkDate: Date
//
// public init(
// id: String,
// domain: String,
// acct: String,
// username: String,
// displayName: String,
// avatar: String,
// avatarStatic: String?,
// header: String,
// headerStatic: String?,
// note: String?,
// url: String?,
// emojisData: Data?,
// fieldsData: Data?,
// statusesCount: Int,
// followingCount: Int,
// followersCount: Int,
// locked: Bool,
// bot: Bool?,
// suspended: Bool?,
// createdAt: Date,
// networkDate: Date
// ) {
// self.identifier = id + "@" + domain
// self.domain = domain
// self.id = id
// self.acct = acct
// self.username = username
// self.displayName = displayName
// self.avatar = avatar
// self.avatarStatic = avatarStatic
// self.header = header
// self.headerStatic = headerStatic
// self.note = note
// self.url = url
// self.emojisData = emojisData
// self.fieldsData = fieldsData
// self.statusesCount = statusesCount
// self.followingCount = followingCount
// self.followersCount = followersCount
// self.locked = locked
// self.bot = bot
// self.suspended = suspended
// self.createdAt = createdAt
// self.networkDate = networkDate
// }
// }
//}
// MARK: - AutoUpdatableObject
extension MastodonUser: AutoUpdatableObject {
// sourcery:inline:MastodonUser.AutoUpdatableObject

View File

@ -678,6 +678,10 @@ public enum L10n {
public static let label = L10n.tr("Localizable", "Scene.Profile.Fields.Placeholder.Label")
}
}
public enum Header {
/// Follows You
public static let followsYou = L10n.tr("Localizable", "Scene.Profile.Header.FollowsYou")
}
public enum RelationshipActionAlert {
public enum ConfirmBlockUser {
/// Confirm to block %@

View File

@ -246,6 +246,7 @@
"Scene.Profile.Fields.AddRow" = "إضافة صف";
"Scene.Profile.Fields.Placeholder.Content" = "المُحتَوى";
"Scene.Profile.Fields.Placeholder.Label" = "التسمية";
"Scene.Profile.Header.FollowsYou" = "يُتابِعُك";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "تأكيدُ حَظر %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "حَظرُ الحِساب";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "تأكيدُ كَتم %@";

View File

@ -246,6 +246,7 @@ carregat a Mastodon.";
"Scene.Profile.Fields.AddRow" = "Afegeix fila";
"Scene.Profile.Fields.Placeholder.Content" = "Contingut";
"Scene.Profile.Fields.Placeholder.Label" = "Etiqueta";
"Scene.Profile.Header.FollowsYou" = "Et segueix";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirma per a bloquejar %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Bloqueja el Compte";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirma per a silenciar %@";

View File

@ -245,6 +245,7 @@
"Scene.Profile.Fields.AddRow" = "ڕیز زیاد بکە";
"Scene.Profile.Fields.Placeholder.Content" = "ناوەڕۆک";
"Scene.Profile.Fields.Placeholder.Label" = "ناونیشان";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "دڵنیا ببەوە بۆ ئاستەنگکردنی %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "ئاستەنگی بکە";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "دڵیا ببەوە بۆ بێدەنگکردنی %@";

View File

@ -246,6 +246,7 @@ kann nicht auf Mastodon hochgeladen werden.";
"Scene.Profile.Fields.AddRow" = "Zeile hinzufügen";
"Scene.Profile.Fields.Placeholder.Content" = "Inhalt";
"Scene.Profile.Fields.Placeholder.Label" = "Bezeichnung";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Bestätige %@ zu blockieren";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Konto blockieren";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Bestätige %@ stumm zu schalten";

View File

@ -246,6 +246,7 @@ uploaded to Mastodon.";
"Scene.Profile.Fields.AddRow" = "Add Row";
"Scene.Profile.Fields.Placeholder.Content" = "Content";
"Scene.Profile.Fields.Placeholder.Label" = "Label";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirm to block %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Block Account";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirm to mute %@";

View File

@ -247,6 +247,7 @@ pulsa en el enlace para confirmar tu cuenta.";
"Scene.Profile.Fields.AddRow" = "Añadir Fila";
"Scene.Profile.Fields.Placeholder.Content" = "Contenido";
"Scene.Profile.Fields.Placeholder.Label" = "Nombre para el campo";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirmar para bloquear a %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Bloquear cuenta";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirmar para silenciar %@";

View File

@ -246,6 +246,7 @@ Mastodonera igo.";
"Scene.Profile.Fields.AddRow" = "Gehitu errenkada";
"Scene.Profile.Fields.Placeholder.Content" = "Edukia";
"Scene.Profile.Fields.Placeholder.Label" = "Etiketa";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Berretsi %@ blokeatzea";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Blokeatu kontua";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Berretsi %@ mututzea";

View File

@ -246,6 +246,7 @@ uploaded to Mastodon.";
"Scene.Profile.Fields.AddRow" = "Lisää rivi";
"Scene.Profile.Fields.Placeholder.Content" = "Sisältö";
"Scene.Profile.Fields.Placeholder.Label" = "Nimi";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirm to block %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Block Account";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirm to mute %@";

View File

@ -246,6 +246,7 @@ téléversé sur Mastodon.";
"Scene.Profile.Fields.AddRow" = "Ajouter une rangée";
"Scene.Profile.Fields.Placeholder.Content" = "Contenu";
"Scene.Profile.Fields.Placeholder.Label" = "Étiquette";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirmer le blocage de %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Bloquer le compte";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Êtes-vous sûr de vouloir mettre en sourdine %@";

View File

@ -247,6 +247,7 @@ thoir gnogag air a chunntas a dhearbhadh a chunntais agad.";
"Scene.Profile.Fields.AddRow" = "Cuir ràgh ris";
"Scene.Profile.Fields.Placeholder.Content" = "Susbaint";
"Scene.Profile.Fields.Placeholder.Label" = "Leubail";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Dearbh bacadh %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Bac an cunntas";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Dearbh mùchadh %@";

View File

@ -246,6 +246,7 @@ ser subido a Mastodon.";
"Scene.Profile.Fields.AddRow" = "Engadir fila";
"Scene.Profile.Fields.Placeholder.Content" = "Contido";
"Scene.Profile.Fields.Placeholder.Label" = "Etiqueta";
"Scene.Profile.Header.FollowsYou" = "Séguete";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirma o bloqueo de %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Bloquear Conta";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirma Acalar a %@";

View File

@ -226,7 +226,7 @@ caricato su Mastodon.";
"Scene.Notification.Keyobard.ShowEverything" = "Mostra Tutto";
"Scene.Notification.Keyobard.ShowMentions" = "Mostra Menzioni";
"Scene.Notification.NotificationDescription.FavoritedYourPost" = "ha apprezzato il tuo post";
"Scene.Notification.NotificationDescription.FollowedYou" = "ti ha seguito";
"Scene.Notification.NotificationDescription.FollowedYou" = "ha iniziato a seguirti";
"Scene.Notification.NotificationDescription.MentionedYou" = "ti ha menzionato";
"Scene.Notification.NotificationDescription.PollHasEnded" = "sondaggio terminato";
"Scene.Notification.NotificationDescription.RebloggedYourPost" = "ha condiviso il tuo post";
@ -246,6 +246,7 @@ caricato su Mastodon.";
"Scene.Profile.Fields.AddRow" = "Aggiungi riga";
"Scene.Profile.Fields.Placeholder.Content" = "Contenuto";
"Scene.Profile.Fields.Placeholder.Label" = "Etichetta";
"Scene.Profile.Header.FollowsYou" = "Ti segue";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confermi di bloccare %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Blocca account";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confermi di silenziare %@";

View File

@ -241,6 +241,7 @@
"Scene.Profile.Fields.AddRow" = "行追加";
"Scene.Profile.Fields.Placeholder.Content" = "コンテンツ";
"Scene.Profile.Fields.Placeholder.Label" = "ラベル";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirm to block %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Block Account";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirm to mute %@";

View File

@ -208,15 +208,15 @@ 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.Familiarfollowers.FollowedByNames" = "Yeṭṭafar-it %@";
"Scene.Familiarfollowers.Title" = "Ineḍfaren i tessneḍ";
"Scene.Favorite.Title" = "Ismenyifen-ik·im";
"Scene.FavoritedBy.Title" = "Favorited By";
"Scene.FavoritedBy.Title" = "Ismenyaf-it";
"Scene.Follower.Footer" = "Ineḍfaren seg yiqeddacen-nniḍen ur d-ttwaskanen ara.";
"Scene.Follower.Title" = "aneḍfar";
"Scene.Following.Footer" = "Ineḍfaren seg yiqeddacen-nniḍen ur d-ttwaskanen ara.";
"Scene.Following.Title" = "yeṭṭafar";
"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Tap to scroll to top and tap again to previous location";
"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoHint" = "Sit i wakken ad tɛeddiḍ i usawen, sit tikkelt-nniḍen i wakken ad tɛeddiḍ ɣer wadig yezrin";
"Scene.HomeTimeline.NavigationBarState.Accessibility.LogoLabel" = "Taqeffalt n ulugu";
"Scene.HomeTimeline.NavigationBarState.NewPosts" = "Tissufaɣ timaynutin";
"Scene.HomeTimeline.NavigationBarState.Offline" = "Beṛṛa n tuqqna";
@ -246,6 +246,7 @@ Ad d-yettwasali ɣef Mastodon.";
"Scene.Profile.Fields.AddRow" = "Rnu izirig";
"Scene.Profile.Fields.Placeholder.Content" = "Agbur";
"Scene.Profile.Fields.Placeholder.Label" = "Tabzimt";
"Scene.Profile.Header.FollowsYou" = "Yeṭṭafaṛ-ik•im";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Sentem asewḥel n %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Sewḥel amiḍan";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Sentem asgugem i %@";
@ -259,7 +260,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.RebloggedBy.Title" = "Tettwasuffeɣ-d sɣur";
"Scene.Register.Error.Item.Agreement" = "Amtawa";
"Scene.Register.Error.Item.Email" = "Imayl";
"Scene.Register.Error.Item.Locale" = "Tadigant";
@ -323,7 +324,7 @@ Ad d-yettwasali ɣef Mastodon.";
"Scene.Report.StepOne.SelectTheBestMatch" = "Fren amṣada akk igerrzen";
"Scene.Report.StepOne.Step1Of4" = "Aḥric 1 seg 4";
"Scene.Report.StepOne.TheIssueDoesNotFitIntoOtherCategories" = "Ugur ur yemṣada ara akk d taggayin-nniḍen";
"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "What's wrong with this account?";
"Scene.Report.StepOne.WhatsWrongWithThisAccount" = "Acu n wugur yellan deg umiḍan-a?";
"Scene.Report.StepOne.WhatsWrongWithThisPost" = "Acu n wugur yellan d tsuffeɣt-a?";
"Scene.Report.StepOne.WhatsWrongWithThisUsername" = "Acu n wugur yellan d %@?";
"Scene.Report.StepOne.YouAreAwareThatItBreaksSpecificRules" = "Teẓriḍ y•tettruẓu kra n yilugan";

View File

@ -72,9 +72,9 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>Followed by %1$@, and another mutual</string>
<string>Yeṭṭafar-it %1$@, akked wayeḍ d ucrik</string>
<key>other</key>
<string>Followed by %1$@, and %ld mutuals</string>
<string>Yeṭṭafar-it %1$@, akked %ld d ucriken</string>
</dict>
</dict>
<key>plural.count.metric_formatted.post</key>
@ -104,9 +104,9 @@
<key>NSStringFormatValueTypeKey</key>
<string>ld</string>
<key>one</key>
<string>1 media</string>
<string>1 umidyat</string>
<key>other</key>
<string>%ld media</string>
<string>%ld yimidyaten</string>
</dict>
</dict>
<key>plural.count.post</key>

View File

@ -247,6 +247,7 @@ girêdanê bitikne da ku ajimêra xwe bidî piştrastkirin.";
"Scene.Profile.Fields.AddRow" = "Rêzê tevlî bike";
"Scene.Profile.Fields.Placeholder.Content" = "Naverok";
"Scene.Profile.Fields.Placeholder.Label" = "Nîşan";
"Scene.Profile.Header.FollowsYou" = "Te dişopîne";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Ji bo rakirina astengkirinê %@ bipejirîne";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Ajimêr asteng bike";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Ji bo bêdengkirina %@ bipejirîne";

View File

@ -241,6 +241,7 @@ klik op de link om uw account te bevestigen.";
"Scene.Profile.Fields.AddRow" = "Rij Toevoegen";
"Scene.Profile.Fields.Placeholder.Content" = "Inhoud";
"Scene.Profile.Fields.Placeholder.Label" = "Etiket";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Bevestig om %@ te blokkeren";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Blokkeer account";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Bevestig om %@ te negeren";

View File

@ -257,6 +257,7 @@
"Scene.Profile.Fields.AddRow" = "Добавить строку";
"Scene.Profile.Fields.Placeholder.Content" = "Содержимое";
"Scene.Profile.Fields.Placeholder.Label" = "Ярлык";
"Scene.Profile.Header.FollowsYou" = "Подписан(а) на вас";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Confirm to block %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Block Account";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Confirm to mute %@";

View File

@ -246,6 +246,7 @@ laddas upp till Mastodon.";
"Scene.Profile.Fields.AddRow" = "Lägg till rad";
"Scene.Profile.Fields.Placeholder.Content" = "Innehåll";
"Scene.Profile.Fields.Placeholder.Label" = "Etikett";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"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 %@";

View File

@ -246,6 +246,7 @@
"Scene.Profile.Fields.AddRow" = "เพิ่มแถว";
"Scene.Profile.Fields.Placeholder.Content" = "เนื้อหา";
"Scene.Profile.Fields.Placeholder.Label" = "ป้ายชื่อ";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "ยืนยันเพื่อปิดกั้น %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "ปิดกั้นบัญชี";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "ยืนยันเพื่อซ่อน %@";

View File

@ -245,6 +245,7 @@ yüklenemiyor.";
"Scene.Profile.Fields.AddRow" = "Satır Ekle";
"Scene.Profile.Fields.Placeholder.Content" = "İçerik";
"Scene.Profile.Fields.Placeholder.Label" = "Etiket";
"Scene.Profile.Header.FollowsYou" = "Follows You";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "%@ engellemeyi onayla";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Hesabı Engelle";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "%@ susturmak için onaylayın";

View File

@ -246,6 +246,7 @@ tải lên Mastodon.";
"Scene.Profile.Fields.AddRow" = "Thêm hàng";
"Scene.Profile.Fields.Placeholder.Content" = "Nội dung";
"Scene.Profile.Fields.Placeholder.Label" = "Nhãn";
"Scene.Profile.Header.FollowsYou" = "Đang theo dõi bạn";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "Xác nhận chặn %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "Chặn người dùng";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "Xác nhận ẩn %@";

View File

@ -246,6 +246,7 @@
"Scene.Profile.Fields.AddRow" = "添加";
"Scene.Profile.Fields.Placeholder.Content" = "内容";
"Scene.Profile.Fields.Placeholder.Label" = "标签";
"Scene.Profile.Header.FollowsYou" = "关注了你";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "确认屏蔽 %@";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "屏蔽帐户";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "确认静音 %@";

View File

@ -241,6 +241,7 @@
"Scene.Profile.Fields.AddRow" = "新增列";
"Scene.Profile.Fields.Placeholder.Content" = "內容";
"Scene.Profile.Fields.Placeholder.Label" = "標籤";
"Scene.Profile.Header.FollowsYou" = "跟隨了您";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Message" = "確認將 %@ 封鎖";
"Scene.Profile.RelationshipActionAlert.ConfirmBlockUser.Title" = "封鎖";
"Scene.Profile.RelationshipActionAlert.ConfirmMuteUser.Message" = "確認將 %@ 靜音";