forked from zelo72/mastodon-ios
feat: update server rule scene UI
This commit is contained in:
parent
d08cb9ece9
commit
a7a36d503a
|
@ -22,7 +22,7 @@
|
||||||
0FAA101C25E10E760017CCDE /* UIFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA101B25E10E760017CCDE /* UIFont.swift */; };
|
0FAA101C25E10E760017CCDE /* UIFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA101B25E10E760017CCDE /* UIFont.swift */; };
|
||||||
0FAA102725E1126A0017CCDE /* MastodonPickServerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA102625E1126A0017CCDE /* MastodonPickServerViewController.swift */; };
|
0FAA102725E1126A0017CCDE /* MastodonPickServerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA102625E1126A0017CCDE /* MastodonPickServerViewController.swift */; };
|
||||||
0FB3D2F725E4C24D00AAD544 /* MastodonPickServerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D2F625E4C24D00AAD544 /* MastodonPickServerViewModel.swift */; };
|
0FB3D2F725E4C24D00AAD544 /* MastodonPickServerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D2F625E4C24D00AAD544 /* MastodonPickServerViewModel.swift */; };
|
||||||
0FB3D2FE25E4CB6400AAD544 /* PickServerTitleCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D2FD25E4CB6400AAD544 /* PickServerTitleCell.swift */; };
|
0FB3D2FE25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D2FD25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift */; };
|
||||||
0FB3D30825E524C600AAD544 /* PickServerCategoriesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D30725E524C600AAD544 /* PickServerCategoriesCell.swift */; };
|
0FB3D30825E524C600AAD544 /* PickServerCategoriesCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D30725E524C600AAD544 /* PickServerCategoriesCell.swift */; };
|
||||||
0FB3D30F25E525CD00AAD544 /* PickServerCategoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.swift */; };
|
0FB3D30F25E525CD00AAD544 /* PickServerCategoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.swift */; };
|
||||||
0FB3D31E25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D31D25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift */; };
|
0FB3D31E25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D31D25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift */; };
|
||||||
|
@ -195,6 +195,10 @@
|
||||||
DB0617ED277F02C50030EE79 /* OnboardingNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */; };
|
DB0617ED277F02C50030EE79 /* OnboardingNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */; };
|
||||||
DB0617EF277F12720030EE79 /* NavigationActionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617EE277F12720030EE79 /* NavigationActionView.swift */; };
|
DB0617EF277F12720030EE79 /* NavigationActionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617EE277F12720030EE79 /* NavigationActionView.swift */; };
|
||||||
DB0617F1278413D00030EE79 /* PickServerServerSectionTableHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617F0278413D00030EE79 /* PickServerServerSectionTableHeaderView.swift */; };
|
DB0617F1278413D00030EE79 /* PickServerServerSectionTableHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617F0278413D00030EE79 /* PickServerServerSectionTableHeaderView.swift */; };
|
||||||
|
DB0617F527855AB90030EE79 /* ServerRuleSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617F427855AB90030EE79 /* ServerRuleSection.swift */; };
|
||||||
|
DB0617FD27855BFE0030EE79 /* ServerRuleItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617FC27855BFE0030EE79 /* ServerRuleItem.swift */; };
|
||||||
|
DB0617FF27855D6C0030EE79 /* MastodonServerRulesViewModel+Diffable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617FE27855D6C0030EE79 /* MastodonServerRulesViewModel+Diffable.swift */; };
|
||||||
|
DB0618012785732C0030EE79 /* ServerRulesTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0618002785732C0030EE79 /* ServerRulesTableViewCell.swift */; };
|
||||||
DB084B5725CBC56C00F898ED /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB084B5625CBC56C00F898ED /* Status.swift */; };
|
DB084B5725CBC56C00F898ED /* Status.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB084B5625CBC56C00F898ED /* Status.swift */; };
|
||||||
DB0AC6FC25CD02E600D75117 /* APIService+Instance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */; };
|
DB0AC6FC25CD02E600D75117 /* APIService+Instance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */; };
|
||||||
DB0C946526A6FD4D0088FB11 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = DB0C946426A6FD4D0088FB11 /* AlamofireImage */; };
|
DB0C946526A6FD4D0088FB11 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = DB0C946426A6FD4D0088FB11 /* AlamofireImage */; };
|
||||||
|
@ -244,7 +248,6 @@
|
||||||
DB427DE225BAA00100D1B89D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DB427DE025BAA00100D1B89D /* LaunchScreen.storyboard */; };
|
DB427DE225BAA00100D1B89D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DB427DE025BAA00100D1B89D /* LaunchScreen.storyboard */; };
|
||||||
DB427DED25BAA00100D1B89D /* MastodonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DEC25BAA00100D1B89D /* MastodonTests.swift */; };
|
DB427DED25BAA00100D1B89D /* MastodonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DEC25BAA00100D1B89D /* MastodonTests.swift */; };
|
||||||
DB427DF825BAA00100D1B89D /* MastodonUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DF725BAA00100D1B89D /* MastodonUITests.swift */; };
|
DB427DF825BAA00100D1B89D /* MastodonUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DF725BAA00100D1B89D /* MastodonUITests.swift */; };
|
||||||
DB44384F25E8C1FA008912A2 /* CALayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB44384E25E8C1FA008912A2 /* CALayer.swift */; };
|
|
||||||
DB443CD42694627B00159B29 /* AppearanceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB443CD32694627B00159B29 /* AppearanceView.swift */; };
|
DB443CD42694627B00159B29 /* AppearanceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB443CD32694627B00159B29 /* AppearanceView.swift */; };
|
||||||
DB44767B260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB44767A260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift */; };
|
DB44767B260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB44767A260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift */; };
|
||||||
DB447681260B3ED600B66B82 /* CustomEmojiPickerSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB447680260B3ED600B66B82 /* CustomEmojiPickerSection.swift */; };
|
DB447681260B3ED600B66B82 /* CustomEmojiPickerSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB447680260B3ED600B66B82 /* CustomEmojiPickerSection.swift */; };
|
||||||
|
@ -782,7 +785,7 @@
|
||||||
0FAA101B25E10E760017CCDE /* UIFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFont.swift; sourceTree = "<group>"; };
|
0FAA101B25E10E760017CCDE /* UIFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIFont.swift; sourceTree = "<group>"; };
|
||||||
0FAA102625E1126A0017CCDE /* MastodonPickServerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonPickServerViewController.swift; sourceTree = "<group>"; };
|
0FAA102625E1126A0017CCDE /* MastodonPickServerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonPickServerViewController.swift; sourceTree = "<group>"; };
|
||||||
0FB3D2F625E4C24D00AAD544 /* MastodonPickServerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonPickServerViewModel.swift; sourceTree = "<group>"; };
|
0FB3D2F625E4C24D00AAD544 /* MastodonPickServerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonPickServerViewModel.swift; sourceTree = "<group>"; };
|
||||||
0FB3D2FD25E4CB6400AAD544 /* PickServerTitleCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerTitleCell.swift; sourceTree = "<group>"; };
|
0FB3D2FD25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingHeadlineTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
0FB3D30725E524C600AAD544 /* PickServerCategoriesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoriesCell.swift; sourceTree = "<group>"; };
|
0FB3D30725E524C600AAD544 /* PickServerCategoriesCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoriesCell.swift; sourceTree = "<group>"; };
|
||||||
0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoryView.swift; sourceTree = "<group>"; };
|
0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoryView.swift; sourceTree = "<group>"; };
|
||||||
0FB3D31D25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoryCollectionViewCell.swift; sourceTree = "<group>"; };
|
0FB3D31D25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoryCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
|
@ -977,6 +980,10 @@
|
||||||
DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingNavigationController.swift; sourceTree = "<group>"; };
|
DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingNavigationController.swift; sourceTree = "<group>"; };
|
||||||
DB0617EE277F12720030EE79 /* NavigationActionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationActionView.swift; sourceTree = "<group>"; };
|
DB0617EE277F12720030EE79 /* NavigationActionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationActionView.swift; sourceTree = "<group>"; };
|
||||||
DB0617F0278413D00030EE79 /* PickServerServerSectionTableHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerServerSectionTableHeaderView.swift; sourceTree = "<group>"; };
|
DB0617F0278413D00030EE79 /* PickServerServerSectionTableHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerServerSectionTableHeaderView.swift; sourceTree = "<group>"; };
|
||||||
|
DB0617F427855AB90030EE79 /* ServerRuleSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerRuleSection.swift; sourceTree = "<group>"; };
|
||||||
|
DB0617FC27855BFE0030EE79 /* ServerRuleItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerRuleItem.swift; sourceTree = "<group>"; };
|
||||||
|
DB0617FE27855D6C0030EE79 /* MastodonServerRulesViewModel+Diffable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonServerRulesViewModel+Diffable.swift"; sourceTree = "<group>"; };
|
||||||
|
DB0618002785732C0030EE79 /* ServerRulesTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerRulesTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
DB084B5625CBC56C00F898ED /* Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Status.swift; sourceTree = "<group>"; };
|
DB084B5625CBC56C00F898ED /* Status.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Status.swift; sourceTree = "<group>"; };
|
||||||
DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Instance.swift"; sourceTree = "<group>"; };
|
DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Instance.swift"; sourceTree = "<group>"; };
|
||||||
DB0C946A26A700AB0088FB11 /* MastodonUser+Property.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonUser+Property.swift"; sourceTree = "<group>"; };
|
DB0C946A26A700AB0088FB11 /* MastodonUser+Property.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MastodonUser+Property.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -1033,7 +1040,6 @@
|
||||||
DB427DF325BAA00100D1B89D /* MastodonUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MastodonUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
DB427DF325BAA00100D1B89D /* MastodonUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MastodonUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
DB427DF725BAA00100D1B89D /* MastodonUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonUITests.swift; sourceTree = "<group>"; };
|
DB427DF725BAA00100D1B89D /* MastodonUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonUITests.swift; sourceTree = "<group>"; };
|
||||||
DB427DF925BAA00100D1B89D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
DB427DF925BAA00100D1B89D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
DB44384E25E8C1FA008912A2 /* CALayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CALayer.swift; sourceTree = "<group>"; };
|
|
||||||
DB443CD32694627B00159B29 /* AppearanceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceView.swift; sourceTree = "<group>"; };
|
DB443CD32694627B00159B29 /* AppearanceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppearanceView.swift; sourceTree = "<group>"; };
|
||||||
DB44767A260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiPickerInputView.swift; sourceTree = "<group>"; };
|
DB44767A260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiPickerInputView.swift; sourceTree = "<group>"; };
|
||||||
DB447680260B3ED600B66B82 /* CustomEmojiPickerSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiPickerSection.swift; sourceTree = "<group>"; };
|
DB447680260B3ED600B66B82 /* CustomEmojiPickerSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiPickerSection.swift; sourceTree = "<group>"; };
|
||||||
|
@ -1598,7 +1604,6 @@
|
||||||
0FB3D2FC25E4CB4B00AAD544 /* TableViewCell */ = {
|
0FB3D2FC25E4CB4B00AAD544 /* TableViewCell */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
0FB3D2FD25E4CB6400AAD544 /* PickServerTitleCell.swift */,
|
|
||||||
0FB3D33725E6401400AAD544 /* PickServerCell.swift */,
|
0FB3D33725E6401400AAD544 /* PickServerCell.swift */,
|
||||||
DB0F814F264D1E2500F2A12B /* PickServerLoaderTableViewCell.swift */,
|
DB0F814F264D1E2500F2A12B /* PickServerLoaderTableViewCell.swift */,
|
||||||
);
|
);
|
||||||
|
@ -1862,28 +1867,21 @@
|
||||||
2D76319C25C151DE00929FB9 /* Diffiable */ = {
|
2D76319C25C151DE00929FB9 /* Diffiable */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
2D76319D25C151F600929FB9 /* Section */,
|
DB4F097826A039B400D62E92 /* Onboarding */,
|
||||||
2D7631B125C159E700929FB9 /* Item */,
|
DB0617FB27855B740030EE79 /* Account */,
|
||||||
|
DB0617F827855B170030EE79 /* User */,
|
||||||
|
DB0617F927855B460030EE79 /* Profile */,
|
||||||
|
DB4F097926A039C400D62E92 /* Status */,
|
||||||
|
DB0617F627855AF30030EE79 /* Poll */,
|
||||||
|
DB4F097626A0398000D62E92 /* Compose */,
|
||||||
|
DB0617F727855B010030EE79 /* Notification */,
|
||||||
|
DB4F097726A039A200D62E92 /* Search */,
|
||||||
|
DB0617FA27855B660030EE79 /* Settings */,
|
||||||
DBCBED2226132E1D00B49291 /* FetchedResultsController */,
|
DBCBED2226132E1D00B49291 /* FetchedResultsController */,
|
||||||
);
|
);
|
||||||
path = Diffiable;
|
path = Diffiable;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
2D76319D25C151F600929FB9 /* Section */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
DB4F097926A039C400D62E92 /* Status */,
|
|
||||||
DB4F097826A039B400D62E92 /* Onboarding */,
|
|
||||||
DB4F097726A039A200D62E92 /* Search */,
|
|
||||||
DB4F097626A0398000D62E92 /* Compose */,
|
|
||||||
2D4AD8A126316CD200613EFC /* SelectedAccountSection.swift */,
|
|
||||||
DB6D9F7C26358ED4008423CD /* SettingsSection.swift */,
|
|
||||||
DBA94433265CBB5300C537E1 /* ProfileFieldSection.swift */,
|
|
||||||
DB6B74FB272FF55800C70B6E /* UserSection.swift */,
|
|
||||||
);
|
|
||||||
path = Section;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
2D7631A425C1532200929FB9 /* Share */ = {
|
2D7631A425C1532200929FB9 /* Share */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1930,29 +1928,6 @@
|
||||||
path = TableviewCell;
|
path = TableviewCell;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
2D7631B125C159E700929FB9 /* Item */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
2D7631B225C159F700929FB9 /* Item.swift */,
|
|
||||||
DB6B74FD272FF59000C70B6E /* UserItem.swift */,
|
|
||||||
2D198642261BF09500F0B013 /* SearchResultItem.swift */,
|
|
||||||
DB4F097C26A03A5B00D62E92 /* SearchHistoryItem.swift */,
|
|
||||||
2D4AD8A726316D3500613EFC /* SelectedAccountItem.swift */,
|
|
||||||
2D7867182625B77500211898 /* NotificationItem.swift */,
|
|
||||||
DB4481CB25EE2AFE00BEFB67 /* PollItem.swift */,
|
|
||||||
DB1E347725F519300079D7DF /* PickServerItem.swift */,
|
|
||||||
DB1FD45925F27898004CFCFC /* CategoryPickerItem.swift */,
|
|
||||||
DB66729B25F9F91F00D60309 /* ComposeStatusItem.swift */,
|
|
||||||
DB3667A0268ABB2E0027D07F /* ComposeStatusAttachmentItem.swift */,
|
|
||||||
DB3667A7268AE2900027D07F /* ComposeStatusPollItem.swift */,
|
|
||||||
DB44768A260B3F2100B66B82 /* CustomEmojiPickerItem.swift */,
|
|
||||||
DB6D9F8326358EEC008423CD /* SettingsItem.swift */,
|
|
||||||
DBBF1DCA2652539E00E5B703 /* AutoCompleteItem.swift */,
|
|
||||||
DBA94435265CBB7400C537E1 /* ProfileFieldItem.swift */,
|
|
||||||
);
|
|
||||||
path = Item;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
2DA504672601ADBA008F4E6C /* Decoration */ = {
|
2DA504672601ADBA008F4E6C /* Decoration */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -2109,6 +2084,60 @@
|
||||||
path = Deprecated;
|
path = Deprecated;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
DB0617F627855AF30030EE79 /* Poll */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DB4481C525EE2ADA00BEFB67 /* PollSection.swift */,
|
||||||
|
DB4481CB25EE2AFE00BEFB67 /* PollItem.swift */,
|
||||||
|
);
|
||||||
|
path = Poll;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
DB0617F727855B010030EE79 /* Notification */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
2D35237926256D920031AF25 /* NotificationSection.swift */,
|
||||||
|
2D7867182625B77500211898 /* NotificationItem.swift */,
|
||||||
|
);
|
||||||
|
path = Notification;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
DB0617F827855B170030EE79 /* User */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DB6B74FB272FF55800C70B6E /* UserSection.swift */,
|
||||||
|
DB6B74FD272FF59000C70B6E /* UserItem.swift */,
|
||||||
|
);
|
||||||
|
path = User;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
DB0617F927855B460030EE79 /* Profile */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DBA94433265CBB5300C537E1 /* ProfileFieldSection.swift */,
|
||||||
|
DBA94435265CBB7400C537E1 /* ProfileFieldItem.swift */,
|
||||||
|
);
|
||||||
|
path = Profile;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
DB0617FA27855B660030EE79 /* Settings */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DB6D9F7C26358ED4008423CD /* SettingsSection.swift */,
|
||||||
|
DB6D9F8326358EEC008423CD /* SettingsItem.swift */,
|
||||||
|
);
|
||||||
|
path = Settings;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
DB0617FB27855B740030EE79 /* Account */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
2D4AD8A126316CD200613EFC /* SelectedAccountSection.swift */,
|
||||||
|
2D4AD8A726316D3500613EFC /* SelectedAccountItem.swift */,
|
||||||
|
);
|
||||||
|
path = Account;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
DB084B5125CBC56300F898ED /* CoreDataStack */ = {
|
DB084B5125CBC56300F898ED /* CoreDataStack */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -2360,10 +2389,15 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
DB66729525F9F91600D60309 /* ComposeStatusSection.swift */,
|
DB66729525F9F91600D60309 /* ComposeStatusSection.swift */,
|
||||||
|
DB66729B25F9F91F00D60309 /* ComposeStatusItem.swift */,
|
||||||
DB36679E268ABAF20027D07F /* ComposeStatusAttachmentSection.swift */,
|
DB36679E268ABAF20027D07F /* ComposeStatusAttachmentSection.swift */,
|
||||||
|
DB3667A0268ABB2E0027D07F /* ComposeStatusAttachmentItem.swift */,
|
||||||
DB3667A5268AE2620027D07F /* ComposeStatusPollSection.swift */,
|
DB3667A5268AE2620027D07F /* ComposeStatusPollSection.swift */,
|
||||||
|
DB3667A7268AE2900027D07F /* ComposeStatusPollItem.swift */,
|
||||||
DB447680260B3ED600B66B82 /* CustomEmojiPickerSection.swift */,
|
DB447680260B3ED600B66B82 /* CustomEmojiPickerSection.swift */,
|
||||||
|
DB44768A260B3F2100B66B82 /* CustomEmojiPickerItem.swift */,
|
||||||
DBBF1DC82652538500E5B703 /* AutoCompleteSection.swift */,
|
DBBF1DC82652538500E5B703 /* AutoCompleteSection.swift */,
|
||||||
|
DBBF1DCA2652539E00E5B703 /* AutoCompleteItem.swift */,
|
||||||
);
|
);
|
||||||
path = Compose;
|
path = Compose;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2374,7 +2408,9 @@
|
||||||
2DE0FAC02615F04D00CDF649 /* RecommendHashTagSection.swift */,
|
2DE0FAC02615F04D00CDF649 /* RecommendHashTagSection.swift */,
|
||||||
2DE0FACD2615F7AD00CDF649 /* RecommendAccountSection.swift */,
|
2DE0FACD2615F7AD00CDF649 /* RecommendAccountSection.swift */,
|
||||||
2D198648261C0B8500F0B013 /* SearchResultSection.swift */,
|
2D198648261C0B8500F0B013 /* SearchResultSection.swift */,
|
||||||
|
2D198642261BF09500F0B013 /* SearchResultItem.swift */,
|
||||||
DB4F097A26A039FF00D62E92 /* SearchHistorySection.swift */,
|
DB4F097A26A039FF00D62E92 /* SearchHistorySection.swift */,
|
||||||
|
DB4F097C26A03A5B00D62E92 /* SearchHistoryItem.swift */,
|
||||||
);
|
);
|
||||||
path = Search;
|
path = Search;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2383,7 +2419,11 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
DB1FD44325F26CCC004CFCFC /* PickServerSection.swift */,
|
DB1FD44325F26CCC004CFCFC /* PickServerSection.swift */,
|
||||||
|
DB1E347725F519300079D7DF /* PickServerItem.swift */,
|
||||||
DB1E346725F518E20079D7DF /* CategoryPickerSection.swift */,
|
DB1E346725F518E20079D7DF /* CategoryPickerSection.swift */,
|
||||||
|
DB1FD45925F27898004CFCFC /* CategoryPickerItem.swift */,
|
||||||
|
DB0617F427855AB90030EE79 /* ServerRuleSection.swift */,
|
||||||
|
DB0617FC27855BFE0030EE79 /* ServerRuleItem.swift */,
|
||||||
);
|
);
|
||||||
path = Onboarding;
|
path = Onboarding;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2392,8 +2432,7 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
2D76319E25C1521200929FB9 /* StatusSection.swift */,
|
2D76319E25C1521200929FB9 /* StatusSection.swift */,
|
||||||
DB4481C525EE2ADA00BEFB67 /* PollSection.swift */,
|
2D7631B225C159F700929FB9 /* Item.swift */,
|
||||||
2D35237926256D920031AF25 /* NotificationSection.swift */,
|
|
||||||
5BB04FF4262F0E6D0043BFF6 /* ReportSection.swift */,
|
5BB04FF4262F0E6D0043BFF6 /* ReportSection.swift */,
|
||||||
);
|
);
|
||||||
path = Status;
|
path = Status;
|
||||||
|
@ -2533,10 +2572,11 @@
|
||||||
DB68A03825E900CC00CFDF14 /* Share */ = {
|
DB68A03825E900CC00CFDF14 /* Share */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
2D82B9FE25E7863200E36F0F /* OnboardingViewControllerAppearance.swift */,
|
|
||||||
DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */,
|
DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */,
|
||||||
DB029E94266A20430062874E /* MastodonAuthenticationController.swift */,
|
DB029E94266A20430062874E /* MastodonAuthenticationController.swift */,
|
||||||
|
2D82B9FE25E7863200E36F0F /* OnboardingViewControllerAppearance.swift */,
|
||||||
DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */,
|
DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */,
|
||||||
|
0FB3D2FD25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift */,
|
||||||
DB0617EE277F12720030EE79 /* NavigationActionView.swift */,
|
DB0617EE277F12720030EE79 /* NavigationActionView.swift */,
|
||||||
);
|
);
|
||||||
path = Share;
|
path = Share;
|
||||||
|
@ -2595,6 +2635,8 @@
|
||||||
children = (
|
children = (
|
||||||
DB72601B25E36A2100235243 /* MastodonServerRulesViewController.swift */,
|
DB72601B25E36A2100235243 /* MastodonServerRulesViewController.swift */,
|
||||||
DB72602625E36A6F00235243 /* MastodonServerRulesViewModel.swift */,
|
DB72602625E36A6F00235243 /* MastodonServerRulesViewModel.swift */,
|
||||||
|
DB0617FE27855D6C0030EE79 /* MastodonServerRulesViewModel+Diffable.swift */,
|
||||||
|
DB0618002785732C0030EE79 /* ServerRulesTableViewCell.swift */,
|
||||||
);
|
);
|
||||||
path = ServerRules;
|
path = ServerRules;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2797,7 +2839,6 @@
|
||||||
2DF123A625C3B0210020F248 /* ActiveLabel.swift */,
|
2DF123A625C3B0210020F248 /* ActiveLabel.swift */,
|
||||||
5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */,
|
5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */,
|
||||||
0F20223826146553000C64BF /* Array.swift */,
|
0F20223826146553000C64BF /* Array.swift */,
|
||||||
DB44384E25E8C1FA008912A2 /* CALayer.swift */,
|
|
||||||
2D206B8525F5FB0900143C56 /* Double.swift */,
|
2D206B8525F5FB0900143C56 /* Double.swift */,
|
||||||
DB97131E2666078B00BD1E90 /* Date.swift */,
|
DB97131E2666078B00BD1E90 /* Date.swift */,
|
||||||
DBB3BA2926A81C020004F2D4 /* FLAnimatedImageView.swift */,
|
DBB3BA2926A81C020004F2D4 /* FLAnimatedImageView.swift */,
|
||||||
|
@ -3954,6 +3995,7 @@
|
||||||
DB68A06325E905E000CFDF14 /* UIApplication.swift in Sources */,
|
DB68A06325E905E000CFDF14 /* UIApplication.swift in Sources */,
|
||||||
DB02CDAB26256A9500D0A2AF /* ThreadReplyLoaderTableViewCell.swift in Sources */,
|
DB02CDAB26256A9500D0A2AF /* ThreadReplyLoaderTableViewCell.swift in Sources */,
|
||||||
DB63BE7F268DD1070011D3F9 /* NotificationViewController+StatusProvider.swift in Sources */,
|
DB63BE7F268DD1070011D3F9 /* NotificationViewController+StatusProvider.swift in Sources */,
|
||||||
|
DB0617FF27855D6C0030EE79 /* MastodonServerRulesViewModel+Diffable.swift in Sources */,
|
||||||
DBB5255E2611F07A002F1F29 /* ProfileViewModel.swift in Sources */,
|
DBB5255E2611F07A002F1F29 /* ProfileViewModel.swift in Sources */,
|
||||||
2D8434FB25FF46B300EECE90 /* HomeTimelineNavigationBarTitleView.swift in Sources */,
|
2D8434FB25FF46B300EECE90 /* HomeTimelineNavigationBarTitleView.swift in Sources */,
|
||||||
0F1E2D0B2615C39400C38565 /* DoubleTitleLabelNavigationBarTitleView.swift in Sources */,
|
0F1E2D0B2615C39400C38565 /* DoubleTitleLabelNavigationBarTitleView.swift in Sources */,
|
||||||
|
@ -3990,6 +4032,7 @@
|
||||||
DB789A0B25F9F2950071ACA0 /* ComposeViewController.swift in Sources */,
|
DB789A0B25F9F2950071ACA0 /* ComposeViewController.swift in Sources */,
|
||||||
DB938F0926240F3C00E5B6C1 /* RemoteThreadViewModel.swift in Sources */,
|
DB938F0926240F3C00E5B6C1 /* RemoteThreadViewModel.swift in Sources */,
|
||||||
DB0617ED277F02C50030EE79 /* OnboardingNavigationController.swift in Sources */,
|
DB0617ED277F02C50030EE79 /* OnboardingNavigationController.swift in Sources */,
|
||||||
|
DB0617F527855AB90030EE79 /* ServerRuleSection.swift in Sources */,
|
||||||
DBBC24AE26A53DC100398BB9 /* ReplicaStatusView.swift in Sources */,
|
DBBC24AE26A53DC100398BB9 /* ReplicaStatusView.swift in Sources */,
|
||||||
DB75BF1E263C1C1B00EDBF1F /* CustomScheduler.swift in Sources */,
|
DB75BF1E263C1C1B00EDBF1F /* CustomScheduler.swift in Sources */,
|
||||||
0FAA102725E1126A0017CCDE /* MastodonPickServerViewController.swift in Sources */,
|
0FAA102725E1126A0017CCDE /* MastodonPickServerViewController.swift in Sources */,
|
||||||
|
@ -4101,7 +4144,7 @@
|
||||||
DB71FD3C25F8A1C500512AE1 /* APIService+Persist+PersistCache.swift in Sources */,
|
DB71FD3C25F8A1C500512AE1 /* APIService+Persist+PersistCache.swift in Sources */,
|
||||||
2DA6055125F74407006356F9 /* AudioContainerViewModel.swift in Sources */,
|
2DA6055125F74407006356F9 /* AudioContainerViewModel.swift in Sources */,
|
||||||
DB4F0968269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift in Sources */,
|
DB4F0968269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift in Sources */,
|
||||||
0FB3D2FE25E4CB6400AAD544 /* PickServerTitleCell.swift in Sources */,
|
0FB3D2FE25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift in Sources */,
|
||||||
5DA732CC2629CEF500A92342 /* UIView+Remove.swift in Sources */,
|
5DA732CC2629CEF500A92342 /* UIView+Remove.swift in Sources */,
|
||||||
DBAEDE5C267A058D00D25FF5 /* BlurhashImageCacheService.swift in Sources */,
|
DBAEDE5C267A058D00D25FF5 /* BlurhashImageCacheService.swift in Sources */,
|
||||||
2D38F1DF25CD46A400561493 /* HomeTimelineViewController+Provider.swift in Sources */,
|
2D38F1DF25CD46A400561493 /* HomeTimelineViewController+Provider.swift in Sources */,
|
||||||
|
@ -4146,6 +4189,7 @@
|
||||||
2D34D9D126148D9E0081BFC0 /* APIService+Recommend.swift in Sources */,
|
2D34D9D126148D9E0081BFC0 /* APIService+Recommend.swift in Sources */,
|
||||||
DBB525562611EDCA002F1F29 /* UserTimelineViewModel.swift in Sources */,
|
DBB525562611EDCA002F1F29 /* UserTimelineViewModel.swift in Sources */,
|
||||||
2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */,
|
2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */,
|
||||||
|
DB0618012785732C0030EE79 /* ServerRulesTableViewCell.swift in Sources */,
|
||||||
DB221B16260C395900AEFE46 /* CustomEmojiPickerInputViewModel.swift in Sources */,
|
DB221B16260C395900AEFE46 /* CustomEmojiPickerInputViewModel.swift in Sources */,
|
||||||
DB0617EF277F12720030EE79 /* NavigationActionView.swift in Sources */,
|
DB0617EF277F12720030EE79 /* NavigationActionView.swift in Sources */,
|
||||||
DB1FD43625F26899004CFCFC /* MastodonPickServerViewModel+LoadIndexedServerState.swift in Sources */,
|
DB1FD43625F26899004CFCFC /* MastodonPickServerViewModel+LoadIndexedServerState.swift in Sources */,
|
||||||
|
@ -4216,7 +4260,6 @@
|
||||||
DB6180F826391D660018D199 /* MediaPreviewingViewController.swift in Sources */,
|
DB6180F826391D660018D199 /* MediaPreviewingViewController.swift in Sources */,
|
||||||
DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */,
|
DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */,
|
||||||
DB6B75022730060700C70B6E /* UserProviderFacade+UITableViewDelegate.swift in Sources */,
|
DB6B75022730060700C70B6E /* UserProviderFacade+UITableViewDelegate.swift in Sources */,
|
||||||
DB44384F25E8C1FA008912A2 /* CALayer.swift in Sources */,
|
|
||||||
2D34D9CB261489930081BFC0 /* SearchViewController+Recommend.swift in Sources */,
|
2D34D9CB261489930081BFC0 /* SearchViewController+Recommend.swift in Sources */,
|
||||||
DB71C7CB271D5A0300BE3819 /* LineChartView.swift in Sources */,
|
DB71C7CB271D5A0300BE3819 /* LineChartView.swift in Sources */,
|
||||||
DB938F1526241FDF00E5B6C1 /* APIService+Thread.swift in Sources */,
|
DB938F1526241FDF00E5B6C1 /* APIService+Thread.swift in Sources */,
|
||||||
|
@ -4358,6 +4401,7 @@
|
||||||
DBAFB7352645463500371D5F /* Emojis.swift in Sources */,
|
DBAFB7352645463500371D5F /* Emojis.swift in Sources */,
|
||||||
DBCCC71E25F73297007E1AB6 /* APIService+Reblog.swift in Sources */,
|
DBCCC71E25F73297007E1AB6 /* APIService+Reblog.swift in Sources */,
|
||||||
DBE3CE13261D7D4200430CC6 /* StatusTableViewControllerAspect.swift in Sources */,
|
DBE3CE13261D7D4200430CC6 /* StatusTableViewControllerAspect.swift in Sources */,
|
||||||
|
DB0617FD27855BFE0030EE79 /* ServerRuleItem.swift in Sources */,
|
||||||
5BB04FD5262E7AFF0043BFF6 /* ReportViewController.swift in Sources */,
|
5BB04FD5262E7AFF0043BFF6 /* ReportViewController.swift in Sources */,
|
||||||
DBAE3F942616E28B004B8251 /* APIService+Follow.swift in Sources */,
|
DBAE3F942616E28B004B8251 /* APIService+Follow.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,60 @@
|
||||||
{
|
{
|
||||||
"object": {
|
"object": {
|
||||||
"pins": [
|
"pins": [
|
||||||
|
{
|
||||||
|
"package": "Alamofire",
|
||||||
|
"repositoryURL": "https://github.com/Alamofire/Alamofire.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "f82c23a8a7ef8dc1a49a8bfc6a96883e79121864",
|
||||||
|
"version": "5.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "AlamofireImage",
|
||||||
|
"repositoryURL": "https://github.com/Alamofire/AlamofireImage.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "98cbb00ce0ec5fc8e52a5b50a6bfc08d3e5aee10",
|
||||||
|
"version": "4.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "AlamofireNetworkActivityIndicator",
|
||||||
|
"repositoryURL": "https://github.com/Alamofire/AlamofireNetworkActivityIndicator",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "392bed083e8d193aca16bfa684ee24e4bcff0510",
|
||||||
|
"version": "3.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "CommonOSLog",
|
||||||
|
"repositoryURL": "https://github.com/MainasuK/CommonOSLog",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "c121624a30698e9886efe38aebb36ff51c01b6c2",
|
||||||
|
"version": "0.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "DiffableDataSources",
|
||||||
|
"repositoryURL": "https://github.com/MainasuK/DiffableDataSources.git",
|
||||||
|
"state": {
|
||||||
|
"branch": "feature/async-display-table",
|
||||||
|
"revision": "73393a97690959d24387c95594c045c62d9c47cf",
|
||||||
|
"version": null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "DifferenceKit",
|
||||||
|
"repositoryURL": "https://github.com/ra1028/DifferenceKit.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "62745d7780deef4a023a792a1f8f763ec7bf9705",
|
||||||
|
"version": "1.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"package": "FLAnimatedImage",
|
"package": "FLAnimatedImage",
|
||||||
"repositoryURL": "https://github.com/Flipboard/FLAnimatedImage",
|
"repositoryURL": "https://github.com/Flipboard/FLAnimatedImage",
|
||||||
|
@ -10,6 +64,42 @@
|
||||||
"version": "1.0.16"
|
"version": "1.0.16"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"package": "FPSIndicator",
|
||||||
|
"repositoryURL": "https://github.com/MainasuK/FPSIndicator.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "e4a5067ccd5293b024c767f09e51056afd4a4796",
|
||||||
|
"version": "1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "Fuzi",
|
||||||
|
"repositoryURL": "https://github.com/cezheng/Fuzi.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "f08c8323da21e985f3772610753bcfc652c2103f",
|
||||||
|
"version": "3.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "KeychainAccess",
|
||||||
|
"repositoryURL": "https://github.com/kishikawakatsumi/KeychainAccess.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "84e546727d66f1adc5439debad16270d0fdd04e7",
|
||||||
|
"version": "4.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "MetaTextKit",
|
||||||
|
"repositoryURL": "https://github.com/TwidereProject/MetaTextKit.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "7af4182f64329440a4656f2cba307cb5848e496a",
|
||||||
|
"version": "2.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"package": "Nuke",
|
"package": "Nuke",
|
||||||
"repositoryURL": "https://github.com/kean/Nuke.git",
|
"repositoryURL": "https://github.com/kean/Nuke.git",
|
||||||
|
@ -28,6 +118,42 @@
|
||||||
"version": "8.0.0"
|
"version": "8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"package": "Pageboy",
|
||||||
|
"repositoryURL": "https://github.com/uias/Pageboy",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "34ecb6e7c4e0e07494960ab2f7cc9a02293915a6",
|
||||||
|
"version": "3.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "PanModal",
|
||||||
|
"repositoryURL": "https://github.com/slackhq/PanModal.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "b012aecb6b67a8e46369227f893c12544846613f",
|
||||||
|
"version": "1.2.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "SDWebImage",
|
||||||
|
"repositoryURL": "https://github.com/SDWebImage/SDWebImage.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "0fff0d7505b5306348263ea64fcc561253bbeb21",
|
||||||
|
"version": "5.12.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "swift-collections",
|
||||||
|
"repositoryURL": "https://github.com/apple/swift-collections.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "9d8719c8bebdc79740b6969c912ac706eb721d7a",
|
||||||
|
"version": "0.0.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"package": "swift-nio",
|
"package": "swift-nio",
|
||||||
"repositoryURL": "https://github.com/apple/swift-nio.git",
|
"repositoryURL": "https://github.com/apple/swift-nio.git",
|
||||||
|
@ -63,6 +189,33 @@
|
||||||
"revision": "b3dcd7dbd0d488e1a7077cb33b00f2083e382f07",
|
"revision": "b3dcd7dbd0d488e1a7077cb33b00f2083e382f07",
|
||||||
"version": "5.0.1"
|
"version": "5.0.1"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "Tabman",
|
||||||
|
"repositoryURL": "https://github.com/uias/Tabman",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "f43489cdd743ba7ad86a422ebb5fcbf34e333df4",
|
||||||
|
"version": "2.11.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "ThirdPartyMailer",
|
||||||
|
"repositoryURL": "https://github.com/vtourraine/ThirdPartyMailer.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "779da6ce0793b461ccbbac2804755c1e29b6fa63",
|
||||||
|
"version": "1.8.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"package": "TOCropViewController",
|
||||||
|
"repositoryURL": "https://github.com/TimOliver/TOCropViewController.git",
|
||||||
|
"state": {
|
||||||
|
"branch": null,
|
||||||
|
"revision": "dad97167bf1be16aeecd109130900995dd01c515",
|
||||||
|
"version": "2.6.0"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
|
@ -28,7 +28,7 @@ extension PickServerSection {
|
||||||
guard let dependency = dependency else { return nil }
|
guard let dependency = dependency else { return nil }
|
||||||
switch item {
|
switch item {
|
||||||
case .header:
|
case .header:
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PickServerTitleCell.self), for: indexPath) as! PickServerTitleCell
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: OnboardingHeadlineTableViewCell.self), for: indexPath) as! OnboardingHeadlineTableViewCell
|
||||||
return cell
|
return cell
|
||||||
case .server(let server, let attribute):
|
case .server(let server, let attribute):
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PickServerCell.self), for: indexPath) as! PickServerCell
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: PickServerCell.self), for: indexPath) as! PickServerCell
|
|
@ -0,0 +1,21 @@
|
||||||
|
//
|
||||||
|
// ServerRuleItem.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by MainasuK on 2022-1-5.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import MastodonSDK
|
||||||
|
|
||||||
|
enum ServerRuleItem: Hashable {
|
||||||
|
case header(domain: String)
|
||||||
|
case rule(RuleContext)
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ServerRuleItem {
|
||||||
|
struct RuleContext: Hashable {
|
||||||
|
let index: Int
|
||||||
|
let rule: Mastodon.Entity.Instance.Rule
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
//
|
||||||
|
// ServerRuleSection.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by MainasuK on 2022-1-5.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
enum ServerRuleSection: Hashable {
|
||||||
|
case header
|
||||||
|
case rules
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ServerRuleSection {
|
||||||
|
static func tableViewDiffableDataSource(
|
||||||
|
tableView: UITableView
|
||||||
|
) -> UITableViewDiffableDataSource<ServerRuleSection, ServerRuleItem> {
|
||||||
|
return UITableViewDiffableDataSource(tableView: tableView) { tableView, indexPath, item in
|
||||||
|
switch item {
|
||||||
|
case .header(let domain):
|
||||||
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: OnboardingHeadlineTableViewCell.self), for: indexPath) as! OnboardingHeadlineTableViewCell
|
||||||
|
cell.titleLabel.text = L10n.Scene.ServerRules.title
|
||||||
|
cell.subTitleLabel.text = L10n.Scene.ServerRules.subtitle(domain)
|
||||||
|
return cell
|
||||||
|
case .rule(let ruleContext):
|
||||||
|
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: ServerRulesTableViewCell.self), for: indexPath) as! ServerRulesTableViewCell
|
||||||
|
cell.indexImageView.image = UIImage(systemName: "\(ruleContext.index).circle.fill") ?? UIImage(systemName: "questionmark.circle.fill")
|
||||||
|
cell.ruleLabel.text = ruleContext.rule.text
|
||||||
|
return cell
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,7 +35,7 @@ final class MastodonPickServerViewController: UIViewController, NeedsDependency
|
||||||
|
|
||||||
let tableView: UITableView = {
|
let tableView: UITableView = {
|
||||||
let tableView = ControlContainableTableView()
|
let tableView = ControlContainableTableView()
|
||||||
tableView.register(PickServerTitleCell.self, forCellReuseIdentifier: String(describing: PickServerTitleCell.self))
|
tableView.register(OnboardingHeadlineTableViewCell.self, forCellReuseIdentifier: String(describing: OnboardingHeadlineTableViewCell.self))
|
||||||
tableView.register(PickServerCell.self, forCellReuseIdentifier: String(describing: PickServerCell.self))
|
tableView.register(PickServerCell.self, forCellReuseIdentifier: String(describing: PickServerCell.self))
|
||||||
tableView.register(PickServerLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: PickServerLoaderTableViewCell.self))
|
tableView.register(PickServerLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: PickServerLoaderTableViewCell.self))
|
||||||
tableView.rowHeight = UITableView.automaticDimension
|
tableView.rowHeight = UITableView.automaticDimension
|
||||||
|
@ -236,6 +236,12 @@ extension MastodonPickServerViewController {
|
||||||
viewModel.viewWillAppear.send()
|
viewModel.viewWillAppear.send()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
|
super.viewDidAppear(animated)
|
||||||
|
|
||||||
|
tableView.flashScrollIndicators()
|
||||||
|
}
|
||||||
|
|
||||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||||
super.traitCollectionDidChange(previousTraitCollection)
|
super.traitCollectionDidChange(previousTraitCollection)
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,11 @@ import MetaTextKit
|
||||||
|
|
||||||
final class MastodonServerRulesViewController: UIViewController, NeedsDependency {
|
final class MastodonServerRulesViewController: UIViewController, NeedsDependency {
|
||||||
|
|
||||||
var disposeBag = Set<AnyCancellable>()
|
let logger = Logger(subsystem: "MastodonServerRulesViewController", category: "ViewController")
|
||||||
|
|
||||||
|
var disposeBag = Set<AnyCancellable>()
|
||||||
|
private var observations = Set<NSKeyValueObservation>()
|
||||||
|
|
||||||
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
weak var context: AppContext! { willSet { precondition(!isViewLoaded) } }
|
||||||
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
weak var coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
||||||
|
|
||||||
|
@ -25,8 +28,8 @@ final class MastodonServerRulesViewController: UIViewController, NeedsDependency
|
||||||
|
|
||||||
let largeTitleLabel: UILabel = {
|
let largeTitleLabel: UILabel = {
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 34, weight: .bold))
|
label.font = MastodonServerRulesViewController.largeTitleFont
|
||||||
label.textColor = .label
|
label.textColor = MastodonServerRulesViewController.largeTitleTextColor
|
||||||
label.text = L10n.Scene.ServerRules.title
|
label.text = L10n.Scene.ServerRules.title
|
||||||
label.numberOfLines = 0
|
label.numberOfLines = 0
|
||||||
return label
|
return label
|
||||||
|
@ -34,56 +37,33 @@ final class MastodonServerRulesViewController: UIViewController, NeedsDependency
|
||||||
|
|
||||||
private(set) lazy var subtitleLabel: UILabel = {
|
private(set) lazy var subtitleLabel: UILabel = {
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = UIFontMetrics(forTextStyle: .title1).scaledFont(for: UIFont.systemFont(ofSize: 20))
|
label.font = MastodonServerRulesViewController.subTitleFont
|
||||||
label.textColor = .secondaryLabel
|
label.textColor = MastodonServerRulesViewController.subTitleTextColor
|
||||||
label.text = L10n.Scene.ServerRules.subtitle(viewModel.domain)
|
label.text = L10n.Scene.ServerRules.subtitle(viewModel.domain)
|
||||||
label.numberOfLines = 0
|
label.numberOfLines = 0
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
|
|
||||||
let rulesLabel: UILabel = {
|
let tableView: UITableView = {
|
||||||
let label = UILabel()
|
let tableView = UITableView()
|
||||||
label.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold))
|
tableView.register(OnboardingHeadlineTableViewCell.self, forCellReuseIdentifier: String(describing: OnboardingHeadlineTableViewCell.self))
|
||||||
label.textColor = Asset.Colors.Label.primary.color
|
tableView.register(ServerRulesTableViewCell.self, forCellReuseIdentifier: String(describing: ServerRulesTableViewCell.self))
|
||||||
label.text = "Rules"
|
tableView.rowHeight = UITableView.automaticDimension
|
||||||
label.numberOfLines = 0
|
tableView.separatorStyle = .none
|
||||||
return label
|
tableView.backgroundColor = .clear
|
||||||
|
tableView.keyboardDismissMode = .onDrag
|
||||||
|
if #available(iOS 15.0, *) {
|
||||||
|
tableView.sectionHeaderTopPadding = 0
|
||||||
|
} else {
|
||||||
|
// Fallback on earlier versions
|
||||||
|
}
|
||||||
|
return tableView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
let bottomContainerView: UIView = {
|
let navigationActionView: NavigationActionView = {
|
||||||
let view = UIView()
|
let navigationActionView = NavigationActionView()
|
||||||
view.backgroundColor = Asset.Theme.Mastodon.systemGroupedBackground.color
|
navigationActionView.backgroundColor = Asset.Scene.Onboarding.onboardingBackground.color
|
||||||
return view
|
return navigationActionView
|
||||||
}()
|
|
||||||
|
|
||||||
private(set) lazy var bottomPromptMetaText: MetaText = {
|
|
||||||
let metaText = MetaText()
|
|
||||||
metaText.textAttributes = [
|
|
||||||
.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 17, weight: .regular), maximumPointSize: 22),
|
|
||||||
.foregroundColor: UIColor.label,
|
|
||||||
]
|
|
||||||
metaText.linkAttributes = [
|
|
||||||
.font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 17, weight: .regular), maximumPointSize: 22),
|
|
||||||
.foregroundColor: Asset.Colors.brandBlue.color,
|
|
||||||
]
|
|
||||||
metaText.textView.isEditable = false
|
|
||||||
metaText.textView.isSelectable = false
|
|
||||||
metaText.textView.isScrollEnabled = false
|
|
||||||
metaText.textView.backgroundColor = Asset.Theme.Mastodon.systemGroupedBackground.color // needs background color to prevent server rules text overlap
|
|
||||||
return metaText
|
|
||||||
}()
|
|
||||||
|
|
||||||
let confirmButton: PrimaryActionButton = {
|
|
||||||
let button = PrimaryActionButton()
|
|
||||||
button.setTitle(L10n.Scene.ServerRules.Button.confirm, for: .normal)
|
|
||||||
return button
|
|
||||||
}()
|
|
||||||
|
|
||||||
let scrollView: UIScrollView = {
|
|
||||||
let scrollView = UIScrollView()
|
|
||||||
scrollView.alwaysBounceVertical = true
|
|
||||||
scrollView.showsVerticalScrollIndicator = false
|
|
||||||
return scrollView
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
@ -97,224 +77,90 @@ extension MastodonServerRulesViewController {
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
navigationItem.leftBarButtonItem = UIBarButtonItem()
|
||||||
|
|
||||||
setupOnboardingAppearance()
|
setupOnboardingAppearance()
|
||||||
configureTitleLabel()
|
|
||||||
configureMargin()
|
|
||||||
configTextView()
|
|
||||||
|
|
||||||
defer { setupNavigationBarBackgroundView() }
|
defer { setupNavigationBarBackgroundView() }
|
||||||
|
|
||||||
bottomContainerView.translatesAutoresizingMaskIntoConstraints = false
|
tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
view.addSubview(bottomContainerView)
|
view.addSubview(tableView)
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
view.bottomAnchor.constraint(equalTo: bottomContainerView.bottomAnchor),
|
tableView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||||
bottomContainerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||||
bottomContainerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||||
|
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||||
])
|
])
|
||||||
bottomContainerView.preservesSuperviewLayoutMargins = true
|
|
||||||
|
navigationActionView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
view.addSubview(navigationActionView)
|
||||||
defer {
|
defer {
|
||||||
view.bringSubviewToFront(bottomContainerView)
|
view.bringSubviewToFront(navigationActionView)
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmButton.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
bottomContainerView.addSubview(confirmButton)
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
bottomContainerView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: confirmButton.bottomAnchor, constant: MastodonServerRulesViewController.viewBottomPaddingHeight),
|
navigationActionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||||
confirmButton.leadingAnchor.constraint(equalTo: bottomContainerView.layoutMarginsGuide.leadingAnchor),
|
navigationActionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||||
bottomContainerView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: confirmButton.trailingAnchor),
|
view.bottomAnchor.constraint(equalTo: navigationActionView.bottomAnchor),
|
||||||
confirmButton.heightAnchor.constraint(equalToConstant: MastodonServerRulesViewController.actionButtonHeight).priority(.defaultHigh),
|
|
||||||
])
|
])
|
||||||
|
|
||||||
bottomPromptMetaText.textView.translatesAutoresizingMaskIntoConstraints = false
|
navigationActionView
|
||||||
bottomContainerView.addSubview(bottomPromptMetaText.textView)
|
.observe(\.bounds, options: [.initial, .new]) { [weak self] navigationActionView, _ in
|
||||||
NSLayoutConstraint.activate([
|
guard let self = self else { return }
|
||||||
bottomPromptMetaText.textView.frameLayoutGuide.topAnchor.constraint(equalTo: bottomContainerView.topAnchor, constant: 20),
|
let inset = navigationActionView.frame.height
|
||||||
bottomPromptMetaText.textView.frameLayoutGuide.leadingAnchor.constraint(equalTo: bottomContainerView.layoutMarginsGuide.leadingAnchor),
|
self.tableView.contentInset.bottom = inset
|
||||||
bottomPromptMetaText.textView.frameLayoutGuide.trailingAnchor.constraint(equalTo: bottomContainerView.layoutMarginsGuide.trailingAnchor),
|
}
|
||||||
confirmButton.topAnchor.constraint(equalTo: bottomPromptMetaText.textView.frameLayoutGuide.bottomAnchor, constant: 20),
|
.store(in: &observations)
|
||||||
])
|
|
||||||
|
|
||||||
scrollView.translatesAutoresizingMaskIntoConstraints = false
|
tableView.delegate = self
|
||||||
view.addSubview(scrollView)
|
viewModel.setupDiffableDataSource(tableView: tableView)
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
scrollView.frameLayoutGuide.topAnchor.constraint(equalTo: view.topAnchor),
|
|
||||||
scrollView.frameLayoutGuide.leadingAnchor.constraint(equalTo: view.readableContentGuide.leadingAnchor),
|
|
||||||
scrollView.frameLayoutGuide.trailingAnchor.constraint(equalTo: view.readableContentGuide.trailingAnchor),
|
|
||||||
scrollView.frameLayoutGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
|
||||||
scrollView.frameLayoutGuide.widthAnchor.constraint(equalTo: scrollView.contentLayoutGuide.widthAnchor),
|
|
||||||
])
|
|
||||||
|
|
||||||
stackView.axis = .vertical
|
|
||||||
stackView.distribution = .fill
|
|
||||||
stackView.spacing = 10
|
|
||||||
stackView.isLayoutMarginsRelativeArrangement = true
|
|
||||||
stackView.layoutMargins = UIEdgeInsets(top: 20, left: 0, bottom: 20, right: 0)
|
|
||||||
stackView.addArrangedSubview(largeTitleLabel)
|
|
||||||
stackView.addArrangedSubview(subtitleLabel)
|
|
||||||
stackView.addArrangedSubview(rulesLabel)
|
|
||||||
|
|
||||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
navigationActionView.backButton.addTarget(self, action: #selector(MastodonServerRulesViewController.backButtonPressed(_:)), for: .touchUpInside)
|
||||||
scrollView.addSubview(stackView)
|
navigationActionView.nextButton.addTarget(self, action: #selector(MastodonServerRulesViewController.nextButtonPressed(_:)), for: .touchUpInside)
|
||||||
NSLayoutConstraint.activate([
|
|
||||||
stackView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor),
|
|
||||||
stackView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor),
|
|
||||||
stackView.trailingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.trailingAnchor),
|
|
||||||
scrollView.contentLayoutGuide.bottomAnchor.constraint(equalTo: stackView.bottomAnchor),
|
|
||||||
])
|
|
||||||
|
|
||||||
rulesLabel.attributedText = viewModel.rulesAttributedString
|
|
||||||
confirmButton.addTarget(self, action: #selector(MastodonServerRulesViewController.confirmButtonPressed(_:)), for: .touchUpInside)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override func viewDidAppear(_ animated: Bool) {
|
override func viewDidAppear(_ animated: Bool) {
|
||||||
super.viewDidAppear(animated)
|
super.viewDidAppear(animated)
|
||||||
|
|
||||||
scrollView.flashScrollIndicators()
|
tableView.flashScrollIndicators()
|
||||||
}
|
|
||||||
|
|
||||||
override func viewDidLayoutSubviews() {
|
|
||||||
super.viewDidLayoutSubviews()
|
|
||||||
updateScrollViewContentInset()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func viewSafeAreaInsetsDidChange() {
|
|
||||||
super.viewSafeAreaInsetsDidChange()
|
|
||||||
updateScrollViewContentInset()
|
|
||||||
}
|
|
||||||
|
|
||||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
|
||||||
super.traitCollectionDidChange(previousTraitCollection)
|
|
||||||
|
|
||||||
setupNavigationBarAppearance()
|
|
||||||
configureTitleLabel()
|
|
||||||
configureMargin()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension MastodonServerRulesViewController {
|
extension MastodonServerRulesViewController {
|
||||||
private func configureTitleLabel() {
|
|
||||||
guard UIDevice.current.userInterfaceIdiom == .pad else {
|
@objc private func backButtonPressed(_ sender: UIButton) {
|
||||||
return
|
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)")
|
||||||
}
|
navigationController?.popViewController(animated: true)
|
||||||
|
|
||||||
switch traitCollection.horizontalSizeClass {
|
|
||||||
case .regular:
|
|
||||||
navigationItem.largeTitleDisplayMode = .always
|
|
||||||
navigationItem.title = L10n.Scene.ServerRules.title.replacingOccurrences(of: "\n", with: " ")
|
|
||||||
largeTitleLabel.isHidden = true
|
|
||||||
default:
|
|
||||||
navigationItem.leftBarButtonItem = nil
|
|
||||||
navigationItem.largeTitleDisplayMode = .never
|
|
||||||
navigationItem.title = nil
|
|
||||||
largeTitleLabel.isHidden = false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func configureMargin() {
|
@objc private func nextButtonPressed(_ sender: UIButton) {
|
||||||
switch traitCollection.horizontalSizeClass {
|
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)")
|
||||||
case .regular:
|
|
||||||
let margin = MastodonPickServerViewController.viewEdgeMargin
|
|
||||||
stackView.layoutMargins = UIEdgeInsets(top: 32, left: margin, bottom: 20, right: margin)
|
|
||||||
bottomContainerView.layoutMargins = UIEdgeInsets(top: 0, left: margin, bottom: 0, right: margin)
|
|
||||||
default:
|
|
||||||
stackView.layoutMargins = UIEdgeInsets(top: 20, left: 0, bottom: 20, right: 0)
|
|
||||||
bottomContainerView.layoutMargins = .zero
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension MastodonServerRulesViewController {
|
let viewModel = MastodonRegisterViewModel(domain: viewModel.domain, context: context, authenticateInfo: viewModel.authenticateInfo, instance: viewModel.instance, applicationToken: viewModel.applicationToken)
|
||||||
func updateScrollViewContentInset() {
|
coordinator.present(scene: .mastodonRegister(viewModel: viewModel), from: self, transition: .show)
|
||||||
view.layoutIfNeeded()
|
|
||||||
scrollView.contentInset.bottom = bottomContainerView.frame.height
|
|
||||||
scrollView.verticalScrollIndicatorInsets.bottom = bottomContainerView.frame.height
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func configTextView() {
|
|
||||||
let metaContent = ServerRulesPromptMetaContent(domain: viewModel.domain)
|
|
||||||
bottomPromptMetaText.configure(content: metaContent)
|
|
||||||
bottomPromptMetaText.textView.linkDelegate = self
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ServerRulesPromptMetaContent: MetaContent {
|
|
||||||
let string: String
|
|
||||||
let entities: [Meta.Entity]
|
|
||||||
|
|
||||||
init(domain: String) {
|
|
||||||
let _string = L10n.Scene.ServerRules.prompt(domain)
|
|
||||||
self.string = _string
|
|
||||||
|
|
||||||
var _entities: [Meta.Entity] = []
|
|
||||||
|
|
||||||
let termsOfServiceText = L10n.Scene.ServerRules.termsOfService
|
|
||||||
if let termsOfServiceRange = _string.range(of: termsOfServiceText) {
|
|
||||||
let url = Mastodon.API.serverRulesURL(domain: domain)
|
|
||||||
let entity = Meta.Entity(range: NSRange(termsOfServiceRange, in: _string), meta: .url(termsOfServiceText, trimmed: termsOfServiceText, url: url.absoluteString, userInfo: nil))
|
|
||||||
_entities.append(entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
let privacyPolicyText = L10n.Scene.ServerRules.privacyPolicy
|
|
||||||
if let privacyPolicyRange = _string.range(of: privacyPolicyText) {
|
|
||||||
let url = Mastodon.API.privacyURL(domain: domain)
|
|
||||||
let entity = Meta.Entity(range: NSRange(privacyPolicyRange, in: _string), meta: .url(privacyPolicyText, trimmed: privacyPolicyText, url: url.absoluteString, userInfo: nil))
|
|
||||||
_entities.append(entity)
|
|
||||||
}
|
|
||||||
|
|
||||||
self.entities = _entities
|
|
||||||
}
|
|
||||||
|
|
||||||
func metaAttachment(for entity: Meta.Entity) -> MetaAttachment? {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
extension MastodonServerRulesViewController: UITextViewDelegate {
|
|
||||||
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - MetaTextViewDelegate
|
|
||||||
extension MastodonServerRulesViewController: MetaTextViewDelegate {
|
|
||||||
func metaTextView(_ metaTextView: MetaTextView, didSelectMeta meta: Meta) {
|
|
||||||
switch meta {
|
|
||||||
case .url(_, _, let url, _):
|
|
||||||
guard let url = URL(string: url) else { return }
|
|
||||||
coordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil))
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension MastodonServerRulesViewController {
|
|
||||||
@objc private func confirmButtonPressed(_ sender: UIButton) {
|
|
||||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
|
|
||||||
|
|
||||||
let viewModel = MastodonRegisterViewModel(domain: self.viewModel.domain, context: self.context, authenticateInfo: self.viewModel.authenticateInfo, instance: self.viewModel.instance, applicationToken: self.viewModel.applicationToken)
|
|
||||||
self.coordinator.present(scene: .mastodonRegister(viewModel: viewModel), from: self, transition: .show)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - OnboardingViewControllerAppearance
|
// MARK: - OnboardingViewControllerAppearance
|
||||||
extension MastodonServerRulesViewController: OnboardingViewControllerAppearance { }
|
extension MastodonServerRulesViewController: OnboardingViewControllerAppearance { }
|
||||||
|
|
||||||
#if canImport(SwiftUI) && DEBUG
|
// MARK: - UITableViewDelegate
|
||||||
import SwiftUI
|
extension MastodonServerRulesViewController: UITableViewDelegate {
|
||||||
|
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||||
struct ServerRulesViewController_Previews: PreviewProvider {
|
return UIView()
|
||||||
|
|
||||||
static var previews: some View {
|
|
||||||
UIViewControllerPreview {
|
|
||||||
let viewController = MastodonServerRulesViewController()
|
|
||||||
return viewController
|
|
||||||
}
|
|
||||||
.previewLayout(.fixed(width: 375, height: 800))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
||||||
|
guard let diffableDataSource = viewModel.diffableDataSource,
|
||||||
|
section < diffableDataSource.snapshot().numberOfSections
|
||||||
|
else { return .leastNonzeroMagnitude }
|
||||||
|
|
||||||
|
let sectionItem = diffableDataSource.snapshot().sectionIdentifiers[section]
|
||||||
|
switch sectionItem {
|
||||||
|
case .header:
|
||||||
|
return .leastNonzeroMagnitude
|
||||||
|
case .rules:
|
||||||
|
return 16
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
//
|
||||||
|
// MastodonServerRulesViewModel+Diffable.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by MainasuK on 2022-1-5.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension MastodonServerRulesViewModel {
|
||||||
|
func setupDiffableDataSource(
|
||||||
|
tableView: UITableView
|
||||||
|
) {
|
||||||
|
diffableDataSource = ServerRuleSection.tableViewDiffableDataSource(tableView: tableView)
|
||||||
|
|
||||||
|
var snapshot = NSDiffableDataSourceSnapshot<ServerRuleSection, ServerRuleItem>()
|
||||||
|
snapshot.appendSections([.header, .rules])
|
||||||
|
snapshot.appendItems([.header(domain: domain)], toSection: .header)
|
||||||
|
let ruleItems: [ServerRuleItem] = rules.enumerated().map { i, rule in
|
||||||
|
let ruleContext = ServerRuleItem.RuleContext(index: i, rule: rule)
|
||||||
|
return ServerRuleItem.rule(ruleContext)
|
||||||
|
}
|
||||||
|
snapshot.appendItems(ruleItems, toSection: .rules)
|
||||||
|
diffableDataSource?.applySnapshot(snapshot, animated: false, completion: nil)
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,9 @@ final class MastodonServerRulesViewModel {
|
||||||
let instance: Mastodon.Entity.Instance
|
let instance: Mastodon.Entity.Instance
|
||||||
let applicationToken: Mastodon.Entity.Token
|
let applicationToken: Mastodon.Entity.Token
|
||||||
|
|
||||||
|
// output
|
||||||
|
var diffableDataSource: UITableViewDiffableDataSource<ServerRuleSection, ServerRuleItem>?
|
||||||
|
|
||||||
init(
|
init(
|
||||||
domain: String,
|
domain: String,
|
||||||
authenticateInfo: AuthenticationViewModel.AuthenticateInfo,
|
authenticateInfo: AuthenticationViewModel.AuthenticateInfo,
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
//
|
||||||
|
// ServerRulesTableViewCell.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by MainasuK on 2022-1-5.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
final class ServerRulesTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
|
static let margin: CGFloat = 23
|
||||||
|
|
||||||
|
let indexImageView: UIImageView = {
|
||||||
|
let imageView = UIImageView()
|
||||||
|
imageView.tintColor = Asset.Colors.Label.primary.color
|
||||||
|
return imageView
|
||||||
|
}()
|
||||||
|
|
||||||
|
let ruleLabel: UILabel = {
|
||||||
|
let label = UILabel()
|
||||||
|
label.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold))
|
||||||
|
label.textColor = Asset.Colors.Label.primary.color
|
||||||
|
label.numberOfLines = 0
|
||||||
|
return label
|
||||||
|
}()
|
||||||
|
|
||||||
|
let separalerLine: UIView = {
|
||||||
|
let view = UIView()
|
||||||
|
view.backgroundColor = Asset.Theme.System.separator.color
|
||||||
|
return view
|
||||||
|
}()
|
||||||
|
|
||||||
|
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||||
|
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ServerRulesTableViewCell {
|
||||||
|
|
||||||
|
private func _init() {
|
||||||
|
selectionStyle = .none
|
||||||
|
backgroundColor = .clear
|
||||||
|
|
||||||
|
indexImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
contentView.addSubview(indexImageView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
indexImageView.topAnchor.constraint(greaterThanOrEqualTo: contentView.topAnchor, constant: ServerRulesTableViewCell.margin),
|
||||||
|
indexImageView.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||||
|
contentView.bottomAnchor.constraint(greaterThanOrEqualTo: indexImageView.bottomAnchor, constant: ServerRulesTableViewCell.margin),
|
||||||
|
indexImageView.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
||||||
|
indexImageView.widthAnchor.constraint(equalToConstant: 32).priority(.required - 1),
|
||||||
|
indexImageView.heightAnchor.constraint(equalToConstant: 32).priority(.required - 1),
|
||||||
|
])
|
||||||
|
|
||||||
|
ruleLabel.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
contentView.addSubview(ruleLabel)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
ruleLabel.topAnchor.constraint(greaterThanOrEqualTo: contentView.topAnchor, constant: ServerRulesTableViewCell.margin),
|
||||||
|
ruleLabel.leadingAnchor.constraint(equalTo: indexImageView.trailingAnchor, constant: 16),
|
||||||
|
ruleLabel.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor),
|
||||||
|
contentView.bottomAnchor.constraint(greaterThanOrEqualTo: ruleLabel.bottomAnchor, constant: ServerRulesTableViewCell.margin),
|
||||||
|
ruleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
|
||||||
|
])
|
||||||
|
|
||||||
|
separalerLine.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
contentView.addSubview(separalerLine)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
separalerLine.leadingAnchor.constraint(equalTo: contentView.readableContentGuide.leadingAnchor),
|
||||||
|
separalerLine.trailingAnchor.constraint(equalTo: contentView.readableContentGuide.trailingAnchor),
|
||||||
|
separalerLine.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
|
||||||
|
separalerLine.heightAnchor.constraint(equalToConstant: UIView.separatorLineHeight(of: contentView)).priority(.required - 1),
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,11 +6,14 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
import MastodonUI
|
||||||
|
|
||||||
final class NavigationActionView: UIView {
|
final class NavigationActionView: UIView {
|
||||||
|
|
||||||
static let buttonHeight: CGFloat = 50
|
static let buttonHeight: CGFloat = 50
|
||||||
|
|
||||||
|
private var observations = Set<NSKeyValueObservation>()
|
||||||
|
|
||||||
let buttonContainer: UIStackView = {
|
let buttonContainer: UIStackView = {
|
||||||
let stackView = UIStackView()
|
let stackView = UIStackView()
|
||||||
stackView.axis = .horizontal
|
stackView.axis = .horizontal
|
||||||
|
@ -18,6 +21,7 @@ final class NavigationActionView: UIView {
|
||||||
return stackView
|
return stackView
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
let backButtonShadowContainer = ShadowBackgroundContainer()
|
||||||
let backButton: PrimaryActionButton = {
|
let backButton: PrimaryActionButton = {
|
||||||
let button = PrimaryActionButton()
|
let button = PrimaryActionButton()
|
||||||
button.action = .back
|
button.action = .back
|
||||||
|
@ -25,6 +29,7 @@ final class NavigationActionView: UIView {
|
||||||
return button
|
return button
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
let nextButtonShadowContainer = ShadowBackgroundContainer()
|
||||||
let nextButton: PrimaryActionButton = {
|
let nextButton: PrimaryActionButton = {
|
||||||
let button = PrimaryActionButton()
|
let button = PrimaryActionButton()
|
||||||
button.action = .next
|
button.action = .next
|
||||||
|
@ -56,14 +61,33 @@ extension NavigationActionView {
|
||||||
safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: buttonContainer.bottomAnchor, constant: 8),
|
safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: buttonContainer.bottomAnchor, constant: 8),
|
||||||
])
|
])
|
||||||
|
|
||||||
backButton.translatesAutoresizingMaskIntoConstraints = false
|
backButtonShadowContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||||
buttonContainer.addArrangedSubview(backButton)
|
buttonContainer.addArrangedSubview(backButtonShadowContainer)
|
||||||
nextButton.translatesAutoresizingMaskIntoConstraints = false
|
nextButtonShadowContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||||
buttonContainer.addArrangedSubview(nextButton)
|
buttonContainer.addArrangedSubview(nextButtonShadowContainer)
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
backButton.heightAnchor.constraint(equalToConstant: NavigationActionView.buttonHeight).priority(.required - 1),
|
backButtonShadowContainer.heightAnchor.constraint(equalToConstant: NavigationActionView.buttonHeight).priority(.required - 1),
|
||||||
nextButton.heightAnchor.constraint(equalToConstant: NavigationActionView.buttonHeight).priority(.required - 1),
|
nextButtonShadowContainer.heightAnchor.constraint(equalToConstant: NavigationActionView.buttonHeight).priority(.required - 1),
|
||||||
nextButton.widthAnchor.constraint(equalTo: backButton.widthAnchor, multiplier: 2).priority(.required - 1),
|
nextButtonShadowContainer.widthAnchor.constraint(equalTo: backButtonShadowContainer.widthAnchor, multiplier: 2).priority(.required - 1),
|
||||||
|
])
|
||||||
|
|
||||||
|
backButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
backButtonShadowContainer.addSubview(backButton)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
backButton.topAnchor.constraint(equalTo: backButtonShadowContainer.topAnchor),
|
||||||
|
backButton.leadingAnchor.constraint(equalTo: backButtonShadowContainer.leadingAnchor),
|
||||||
|
backButton.trailingAnchor.constraint(equalTo: backButtonShadowContainer.trailingAnchor),
|
||||||
|
backButton.bottomAnchor.constraint(equalTo: backButtonShadowContainer.bottomAnchor),
|
||||||
|
])
|
||||||
|
|
||||||
|
nextButton.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
nextButtonShadowContainer.addSubview(nextButton)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
nextButton.topAnchor.constraint(equalTo: nextButtonShadowContainer.topAnchor),
|
||||||
|
nextButton.leadingAnchor.constraint(equalTo: nextButtonShadowContainer.leadingAnchor),
|
||||||
|
nextButton.trailingAnchor.constraint(equalTo: nextButtonShadowContainer.trailingAnchor),
|
||||||
|
nextButton.bottomAnchor.constraint(equalTo: nextButtonShadowContainer.bottomAnchor),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// PickServerTitleCell.swift
|
// OnboardingHeadlineTableViewCell.swift
|
||||||
// Mastodon
|
// Mastodon
|
||||||
//
|
//
|
||||||
// Created by BradGao on 2021/2/23.
|
// Created by BradGao on 2021/2/23.
|
||||||
|
@ -7,12 +7,12 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
final class PickServerTitleCell: UITableViewCell {
|
final class OnboardingHeadlineTableViewCell: UITableViewCell {
|
||||||
|
|
||||||
let titleLabel: UILabel = {
|
let titleLabel: UILabel = {
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 28, weight: .bold))
|
label.font = MastodonPickServerViewController.largeTitleFont
|
||||||
label.textColor = Asset.Colors.Label.primary.color
|
label.textColor = MastodonPickServerViewController.largeTitleTextColor
|
||||||
label.text = L10n.Scene.ServerPicker.title
|
label.text = L10n.Scene.ServerPicker.title
|
||||||
label.adjustsFontForContentSizeCategory = true
|
label.adjustsFontForContentSizeCategory = true
|
||||||
label.numberOfLines = 0
|
label.numberOfLines = 0
|
||||||
|
@ -21,8 +21,8 @@ final class PickServerTitleCell: UITableViewCell {
|
||||||
|
|
||||||
let subTitleLabel: UILabel = {
|
let subTitleLabel: UILabel = {
|
||||||
let label = UILabel()
|
let label = UILabel()
|
||||||
label.font = UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 17, weight: .regular))
|
label.font = MastodonPickServerViewController.subTitleFont
|
||||||
label.textColor = Asset.Colors.Label.secondary.color
|
label.textColor = MastodonPickServerViewController.subTitleTextColor
|
||||||
label.text = "Pick a community based on your interests, region, or a general purpose one. Each community is operated by an entirely independent organization or individual."
|
label.text = "Pick a community based on your interests, region, or a general purpose one. Each community is operated by an entirely independent organization or individual."
|
||||||
label.adjustsFontForContentSizeCategory = true
|
label.adjustsFontForContentSizeCategory = true
|
||||||
label.numberOfLines = 0
|
label.numberOfLines = 0
|
||||||
|
@ -40,7 +40,7 @@ final class PickServerTitleCell: UITableViewCell {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension PickServerTitleCell {
|
extension OnboardingHeadlineTableViewCell {
|
||||||
|
|
||||||
private func _init() {
|
private func _init() {
|
||||||
selectionStyle = .none
|
selectionStyle = .none
|
|
@ -21,6 +21,22 @@ extension OnboardingViewControllerAppearance {
|
||||||
static var viewBottomPaddingHeight: CGFloat { return 11 }
|
static var viewBottomPaddingHeight: CGFloat { return 11 }
|
||||||
static var viewBottomPaddingHeightExtend: CGFloat { return 22 }
|
static var viewBottomPaddingHeightExtend: CGFloat { return 22 }
|
||||||
|
|
||||||
|
static var largeTitleFont: UIFont {
|
||||||
|
return UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 28, weight: .bold))
|
||||||
|
}
|
||||||
|
|
||||||
|
static var largeTitleTextColor: UIColor {
|
||||||
|
return Asset.Colors.Label.primary.color
|
||||||
|
}
|
||||||
|
|
||||||
|
static var subTitleFont: UIFont {
|
||||||
|
return UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 17, weight: .regular))
|
||||||
|
}
|
||||||
|
|
||||||
|
static var subTitleTextColor: UIColor {
|
||||||
|
return Asset.Colors.Label.secondary.color
|
||||||
|
}
|
||||||
|
|
||||||
func setupOnboardingAppearance() {
|
func setupOnboardingAppearance() {
|
||||||
view.backgroundColor = Asset.Scene.Onboarding.onboardingBackground.color
|
view.backgroundColor = Asset.Scene.Onboarding.onboardingBackground.color
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,7 @@ final class WelcomeViewController: UIViewController, NeedsDependency {
|
||||||
button.setTitleColor(.black, for: .normal)
|
button.setTitleColor(.black, for: .normal)
|
||||||
return button
|
return button
|
||||||
}()
|
}()
|
||||||
|
let signUpButtonShadowView = UIView()
|
||||||
|
|
||||||
private(set) lazy var signInButton: PrimaryActionButton = {
|
private(set) lazy var signInButton: PrimaryActionButton = {
|
||||||
let button = PrimaryActionButton()
|
let button = PrimaryActionButton()
|
||||||
|
@ -72,7 +73,6 @@ final class WelcomeViewController: UIViewController, NeedsDependency {
|
||||||
}()
|
}()
|
||||||
let signInButtonShadowView = UIView()
|
let signInButtonShadowView = UIView()
|
||||||
|
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
|
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
|
||||||
}
|
}
|
||||||
|
@ -117,6 +117,16 @@ extension WelcomeViewController {
|
||||||
signInButton.heightAnchor.constraint(equalToConstant: WelcomeViewController.actionButtonHeight).priority(.required - 1),
|
signInButton.heightAnchor.constraint(equalToConstant: WelcomeViewController.actionButtonHeight).priority(.required - 1),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
signUpButtonShadowView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
buttonContainer.addSubview(signUpButtonShadowView)
|
||||||
|
buttonContainer.sendSubviewToBack(signUpButtonShadowView)
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
signUpButtonShadowView.topAnchor.constraint(equalTo: signUpButton.topAnchor),
|
||||||
|
signUpButtonShadowView.leadingAnchor.constraint(equalTo: signUpButton.leadingAnchor),
|
||||||
|
signUpButtonShadowView.trailingAnchor.constraint(equalTo: signUpButton.trailingAnchor),
|
||||||
|
signUpButtonShadowView.bottomAnchor.constraint(equalTo: signUpButton.bottomAnchor),
|
||||||
|
])
|
||||||
|
|
||||||
signInButtonShadowView.translatesAutoresizingMaskIntoConstraints = false
|
signInButtonShadowView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
buttonContainer.addSubview(signInButtonShadowView)
|
buttonContainer.addSubview(signInButtonShadowView)
|
||||||
buttonContainer.sendSubviewToBack(signInButtonShadowView)
|
buttonContainer.sendSubviewToBack(signInButtonShadowView)
|
||||||
|
@ -168,6 +178,17 @@ extension WelcomeViewController {
|
||||||
extension WelcomeViewController {
|
extension WelcomeViewController {
|
||||||
|
|
||||||
private func setupButtonShadowView() {
|
private func setupButtonShadowView() {
|
||||||
|
signUpButtonShadowView.layer.setupShadow(
|
||||||
|
color: .black,
|
||||||
|
alpha: 0.25,
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
blur: 2,
|
||||||
|
spread: 0,
|
||||||
|
roundedRect: signInButtonShadowView.bounds,
|
||||||
|
byRoundingCorners: .allCorners,
|
||||||
|
cornerRadii: CGSize(width: 10, height: 10)
|
||||||
|
)
|
||||||
signInButtonShadowView.layer.setupShadow(
|
signInButtonShadowView.layer.setupShadow(
|
||||||
color: .black,
|
color: .black,
|
||||||
alpha: 0.25,
|
alpha: 0.25,
|
||||||
|
|
|
@ -9,8 +9,8 @@ import UIKit
|
||||||
|
|
||||||
class PrimaryActionButton: UIButton {
|
class PrimaryActionButton: UIButton {
|
||||||
|
|
||||||
var isLoading: Bool = false
|
private var originalButtonTitle: String?
|
||||||
|
|
||||||
lazy var activityIndicator: UIActivityIndicatorView = {
|
lazy var activityIndicator: UIActivityIndicatorView = {
|
||||||
let indicator = UIActivityIndicatorView(style: .medium)
|
let indicator = UIActivityIndicatorView(style: .medium)
|
||||||
indicator.color = .white
|
indicator.color = .white
|
||||||
|
@ -18,16 +18,13 @@ class PrimaryActionButton: UIButton {
|
||||||
indicator.translatesAutoresizingMaskIntoConstraints = false
|
indicator.translatesAutoresizingMaskIntoConstraints = false
|
||||||
return indicator
|
return indicator
|
||||||
}()
|
}()
|
||||||
|
var adjustsBackgroundImageWhenUserInterfaceStyleChanges = true
|
||||||
private var originalButtonTitle: String?
|
|
||||||
|
|
||||||
var action: Action = .next {
|
var action: Action = .next {
|
||||||
didSet {
|
didSet {
|
||||||
setupAppearance(action: action)
|
setupAppearance(action: action)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var isLoading: Bool = false
|
||||||
var adjustsBackgroundImageWhenUserInterfaceStyleChanges = true
|
|
||||||
|
|
||||||
override init(frame: CGRect) {
|
override init(frame: CGRect) {
|
||||||
super.init(frame: frame)
|
super.init(frame: frame)
|
||||||
|
|
|
@ -9,7 +9,7 @@ import UIKit
|
||||||
|
|
||||||
extension CALayer {
|
extension CALayer {
|
||||||
|
|
||||||
func setupShadow(
|
public func setupShadow(
|
||||||
color: UIColor = .black,
|
color: UIColor = .black,
|
||||||
alpha: Float = 0.5,
|
alpha: Float = 0.5,
|
||||||
x: CGFloat = 0,
|
x: CGFloat = 0,
|
||||||
|
@ -43,9 +43,8 @@ extension CALayer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeShadow() {
|
public func removeShadow() {
|
||||||
shadowRadius = 0
|
shadowRadius = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -10,12 +10,28 @@ import CoreImage.CIFilterBuiltins
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
extension UIImage {
|
extension UIImage {
|
||||||
public static func placeholder(size: CGSize = CGSize(width: 1, height: 1), color: UIColor) -> UIImage {
|
public static func placeholder(
|
||||||
|
size: CGSize = CGSize(width: 1, height: 1),
|
||||||
|
color: UIColor,
|
||||||
|
cornerRadius: CGFloat = 0
|
||||||
|
) -> UIImage {
|
||||||
let render = UIGraphicsImageRenderer(size: size)
|
let render = UIGraphicsImageRenderer(size: size)
|
||||||
|
|
||||||
return render.image { (context: UIGraphicsImageRendererContext) in
|
return render.image { (context: UIGraphicsImageRendererContext) in
|
||||||
|
// set clear fill
|
||||||
context.cgContext.setFillColor(color.cgColor)
|
context.cgContext.setFillColor(color.cgColor)
|
||||||
context.fill(CGRect(origin: .zero, size: size))
|
|
||||||
|
let rect = CGRect(origin: .zero, size: size)
|
||||||
|
|
||||||
|
// clip corner if needs
|
||||||
|
if cornerRadius > 0 {
|
||||||
|
let path = UIBezierPath(roundedRect: rect, cornerRadius: cornerRadius).cgPath
|
||||||
|
context.cgContext.addPath(path)
|
||||||
|
context.cgContext.clip(using: .evenOdd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// set fill
|
||||||
|
context.fill(rect)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ extension Mastodon.Entity.Instance {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Mastodon.Entity.Instance {
|
extension Mastodon.Entity.Instance {
|
||||||
public struct Rule: Codable {
|
public struct Rule: Codable, Hashable {
|
||||||
public let id: String
|
public let id: String
|
||||||
public let text: String
|
public let text: String
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
//
|
||||||
|
// ShadowBackgroundContainer.swift
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Created by MainasuK on 2022-1-5.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import MastodonExtension
|
||||||
|
|
||||||
|
public final class ShadowBackgroundContainer: UIView {
|
||||||
|
|
||||||
|
public let shadowLayer = CALayer()
|
||||||
|
|
||||||
|
override init(frame: CGRect) {
|
||||||
|
super.init(frame: frame)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
_init()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ShadowBackgroundContainer {
|
||||||
|
private func _init() {
|
||||||
|
layer.insertSublayer(shadowLayer, at: 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
public override func layoutSubviews() {
|
||||||
|
super.layoutSubviews()
|
||||||
|
|
||||||
|
shadowLayer.frame = bounds
|
||||||
|
shadowLayer.setupShadow(
|
||||||
|
color: .black,
|
||||||
|
alpha: 0.25,
|
||||||
|
x: 0,
|
||||||
|
y: 1,
|
||||||
|
blur: 2,
|
||||||
|
spread: 0,
|
||||||
|
roundedRect: bounds,
|
||||||
|
byRoundingCorners: .allCorners,
|
||||||
|
cornerRadii: CGSize(width: 10, height: 10)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue