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 */; };
|
||||
0FAA102725E1126A0017CCDE /* MastodonPickServerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FAA102625E1126A0017CCDE /* MastodonPickServerViewController.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 */; };
|
||||
0FB3D30F25E525CD00AAD544 /* PickServerCategoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0FB3D30E25E525CD00AAD544 /* PickServerCategoryView.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 */; };
|
||||
DB0617EF277F12720030EE79 /* NavigationActionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0617EE277F12720030EE79 /* NavigationActionView.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 */; };
|
||||
DB0AC6FC25CD02E600D75117 /* APIService+Instance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */; };
|
||||
DB0C946526A6FD4D0088FB11 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = DB0C946426A6FD4D0088FB11 /* AlamofireImage */; };
|
||||
|
@ -244,7 +248,6 @@
|
|||
DB427DE225BAA00100D1B89D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DB427DE025BAA00100D1B89D /* LaunchScreen.storyboard */; };
|
||||
DB427DED25BAA00100D1B89D /* MastodonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DEC25BAA00100D1B89D /* MastodonTests.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 */; };
|
||||
DB44767B260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB44767A260B3B8C00B66B82 /* CustomEmojiPickerInputView.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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
|
@ -977,6 +980,10 @@
|
|||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
|
@ -1033,7 +1040,6 @@
|
|||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
|
@ -1598,7 +1604,6 @@
|
|||
0FB3D2FC25E4CB4B00AAD544 /* TableViewCell */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0FB3D2FD25E4CB6400AAD544 /* PickServerTitleCell.swift */,
|
||||
0FB3D33725E6401400AAD544 /* PickServerCell.swift */,
|
||||
DB0F814F264D1E2500F2A12B /* PickServerLoaderTableViewCell.swift */,
|
||||
);
|
||||
|
@ -1862,28 +1867,21 @@
|
|||
2D76319C25C151DE00929FB9 /* Diffiable */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2D76319D25C151F600929FB9 /* Section */,
|
||||
2D7631B125C159E700929FB9 /* Item */,
|
||||
DB4F097826A039B400D62E92 /* Onboarding */,
|
||||
DB0617FB27855B740030EE79 /* Account */,
|
||||
DB0617F827855B170030EE79 /* User */,
|
||||
DB0617F927855B460030EE79 /* Profile */,
|
||||
DB4F097926A039C400D62E92 /* Status */,
|
||||
DB0617F627855AF30030EE79 /* Poll */,
|
||||
DB4F097626A0398000D62E92 /* Compose */,
|
||||
DB0617F727855B010030EE79 /* Notification */,
|
||||
DB4F097726A039A200D62E92 /* Search */,
|
||||
DB0617FA27855B660030EE79 /* Settings */,
|
||||
DBCBED2226132E1D00B49291 /* FetchedResultsController */,
|
||||
);
|
||||
path = Diffiable;
|
||||
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 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1930,29 +1928,6 @@
|
|||
path = TableviewCell;
|
||||
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 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -2109,6 +2084,60 @@
|
|||
path = Deprecated;
|
||||
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 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -2360,10 +2389,15 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
DB66729525F9F91600D60309 /* ComposeStatusSection.swift */,
|
||||
DB66729B25F9F91F00D60309 /* ComposeStatusItem.swift */,
|
||||
DB36679E268ABAF20027D07F /* ComposeStatusAttachmentSection.swift */,
|
||||
DB3667A0268ABB2E0027D07F /* ComposeStatusAttachmentItem.swift */,
|
||||
DB3667A5268AE2620027D07F /* ComposeStatusPollSection.swift */,
|
||||
DB3667A7268AE2900027D07F /* ComposeStatusPollItem.swift */,
|
||||
DB447680260B3ED600B66B82 /* CustomEmojiPickerSection.swift */,
|
||||
DB44768A260B3F2100B66B82 /* CustomEmojiPickerItem.swift */,
|
||||
DBBF1DC82652538500E5B703 /* AutoCompleteSection.swift */,
|
||||
DBBF1DCA2652539E00E5B703 /* AutoCompleteItem.swift */,
|
||||
);
|
||||
path = Compose;
|
||||
sourceTree = "<group>";
|
||||
|
@ -2374,7 +2408,9 @@
|
|||
2DE0FAC02615F04D00CDF649 /* RecommendHashTagSection.swift */,
|
||||
2DE0FACD2615F7AD00CDF649 /* RecommendAccountSection.swift */,
|
||||
2D198648261C0B8500F0B013 /* SearchResultSection.swift */,
|
||||
2D198642261BF09500F0B013 /* SearchResultItem.swift */,
|
||||
DB4F097A26A039FF00D62E92 /* SearchHistorySection.swift */,
|
||||
DB4F097C26A03A5B00D62E92 /* SearchHistoryItem.swift */,
|
||||
);
|
||||
path = Search;
|
||||
sourceTree = "<group>";
|
||||
|
@ -2383,7 +2419,11 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
DB1FD44325F26CCC004CFCFC /* PickServerSection.swift */,
|
||||
DB1E347725F519300079D7DF /* PickServerItem.swift */,
|
||||
DB1E346725F518E20079D7DF /* CategoryPickerSection.swift */,
|
||||
DB1FD45925F27898004CFCFC /* CategoryPickerItem.swift */,
|
||||
DB0617F427855AB90030EE79 /* ServerRuleSection.swift */,
|
||||
DB0617FC27855BFE0030EE79 /* ServerRuleItem.swift */,
|
||||
);
|
||||
path = Onboarding;
|
||||
sourceTree = "<group>";
|
||||
|
@ -2392,8 +2432,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
2D76319E25C1521200929FB9 /* StatusSection.swift */,
|
||||
DB4481C525EE2ADA00BEFB67 /* PollSection.swift */,
|
||||
2D35237926256D920031AF25 /* NotificationSection.swift */,
|
||||
2D7631B225C159F700929FB9 /* Item.swift */,
|
||||
5BB04FF4262F0E6D0043BFF6 /* ReportSection.swift */,
|
||||
);
|
||||
path = Status;
|
||||
|
@ -2533,10 +2572,11 @@
|
|||
DB68A03825E900CC00CFDF14 /* Share */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
2D82B9FE25E7863200E36F0F /* OnboardingViewControllerAppearance.swift */,
|
||||
DB2F073325E8ECF000957B2D /* AuthenticationViewModel.swift */,
|
||||
DB029E94266A20430062874E /* MastodonAuthenticationController.swift */,
|
||||
2D82B9FE25E7863200E36F0F /* OnboardingViewControllerAppearance.swift */,
|
||||
DB0617EC277F02C50030EE79 /* OnboardingNavigationController.swift */,
|
||||
0FB3D2FD25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift */,
|
||||
DB0617EE277F12720030EE79 /* NavigationActionView.swift */,
|
||||
);
|
||||
path = Share;
|
||||
|
@ -2595,6 +2635,8 @@
|
|||
children = (
|
||||
DB72601B25E36A2100235243 /* MastodonServerRulesViewController.swift */,
|
||||
DB72602625E36A6F00235243 /* MastodonServerRulesViewModel.swift */,
|
||||
DB0617FE27855D6C0030EE79 /* MastodonServerRulesViewModel+Diffable.swift */,
|
||||
DB0618002785732C0030EE79 /* ServerRulesTableViewCell.swift */,
|
||||
);
|
||||
path = ServerRules;
|
||||
sourceTree = "<group>";
|
||||
|
@ -2797,7 +2839,6 @@
|
|||
2DF123A625C3B0210020F248 /* ActiveLabel.swift */,
|
||||
5DF1056325F887CB00D6C0D4 /* AVPlayer.swift */,
|
||||
0F20223826146553000C64BF /* Array.swift */,
|
||||
DB44384E25E8C1FA008912A2 /* CALayer.swift */,
|
||||
2D206B8525F5FB0900143C56 /* Double.swift */,
|
||||
DB97131E2666078B00BD1E90 /* Date.swift */,
|
||||
DBB3BA2926A81C020004F2D4 /* FLAnimatedImageView.swift */,
|
||||
|
@ -3954,6 +3995,7 @@
|
|||
DB68A06325E905E000CFDF14 /* UIApplication.swift in Sources */,
|
||||
DB02CDAB26256A9500D0A2AF /* ThreadReplyLoaderTableViewCell.swift in Sources */,
|
||||
DB63BE7F268DD1070011D3F9 /* NotificationViewController+StatusProvider.swift in Sources */,
|
||||
DB0617FF27855D6C0030EE79 /* MastodonServerRulesViewModel+Diffable.swift in Sources */,
|
||||
DBB5255E2611F07A002F1F29 /* ProfileViewModel.swift in Sources */,
|
||||
2D8434FB25FF46B300EECE90 /* HomeTimelineNavigationBarTitleView.swift in Sources */,
|
||||
0F1E2D0B2615C39400C38565 /* DoubleTitleLabelNavigationBarTitleView.swift in Sources */,
|
||||
|
@ -3990,6 +4032,7 @@
|
|||
DB789A0B25F9F2950071ACA0 /* ComposeViewController.swift in Sources */,
|
||||
DB938F0926240F3C00E5B6C1 /* RemoteThreadViewModel.swift in Sources */,
|
||||
DB0617ED277F02C50030EE79 /* OnboardingNavigationController.swift in Sources */,
|
||||
DB0617F527855AB90030EE79 /* ServerRuleSection.swift in Sources */,
|
||||
DBBC24AE26A53DC100398BB9 /* ReplicaStatusView.swift in Sources */,
|
||||
DB75BF1E263C1C1B00EDBF1F /* CustomScheduler.swift in Sources */,
|
||||
0FAA102725E1126A0017CCDE /* MastodonPickServerViewController.swift in Sources */,
|
||||
|
@ -4101,7 +4144,7 @@
|
|||
DB71FD3C25F8A1C500512AE1 /* APIService+Persist+PersistCache.swift in Sources */,
|
||||
2DA6055125F74407006356F9 /* AudioContainerViewModel.swift in Sources */,
|
||||
DB4F0968269ED8AD00D62E92 /* SearchHistoryTableHeaderView.swift in Sources */,
|
||||
0FB3D2FE25E4CB6400AAD544 /* PickServerTitleCell.swift in Sources */,
|
||||
0FB3D2FE25E4CB6400AAD544 /* OnboardingHeadlineTableViewCell.swift in Sources */,
|
||||
5DA732CC2629CEF500A92342 /* UIView+Remove.swift in Sources */,
|
||||
DBAEDE5C267A058D00D25FF5 /* BlurhashImageCacheService.swift in Sources */,
|
||||
2D38F1DF25CD46A400561493 /* HomeTimelineViewController+Provider.swift in Sources */,
|
||||
|
@ -4146,6 +4189,7 @@
|
|||
2D34D9D126148D9E0081BFC0 /* APIService+Recommend.swift in Sources */,
|
||||
DBB525562611EDCA002F1F29 /* UserTimelineViewModel.swift in Sources */,
|
||||
2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */,
|
||||
DB0618012785732C0030EE79 /* ServerRulesTableViewCell.swift in Sources */,
|
||||
DB221B16260C395900AEFE46 /* CustomEmojiPickerInputViewModel.swift in Sources */,
|
||||
DB0617EF277F12720030EE79 /* NavigationActionView.swift in Sources */,
|
||||
DB1FD43625F26899004CFCFC /* MastodonPickServerViewModel+LoadIndexedServerState.swift in Sources */,
|
||||
|
@ -4216,7 +4260,6 @@
|
|||
DB6180F826391D660018D199 /* MediaPreviewingViewController.swift in Sources */,
|
||||
DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */,
|
||||
DB6B75022730060700C70B6E /* UserProviderFacade+UITableViewDelegate.swift in Sources */,
|
||||
DB44384F25E8C1FA008912A2 /* CALayer.swift in Sources */,
|
||||
2D34D9CB261489930081BFC0 /* SearchViewController+Recommend.swift in Sources */,
|
||||
DB71C7CB271D5A0300BE3819 /* LineChartView.swift in Sources */,
|
||||
DB938F1526241FDF00E5B6C1 /* APIService+Thread.swift in Sources */,
|
||||
|
@ -4358,6 +4401,7 @@
|
|||
DBAFB7352645463500371D5F /* Emojis.swift in Sources */,
|
||||
DBCCC71E25F73297007E1AB6 /* APIService+Reblog.swift in Sources */,
|
||||
DBE3CE13261D7D4200430CC6 /* StatusTableViewControllerAspect.swift in Sources */,
|
||||
DB0617FD27855BFE0030EE79 /* ServerRuleItem.swift in Sources */,
|
||||
5BB04FD5262E7AFF0043BFF6 /* ReportViewController.swift in Sources */,
|
||||
DBAE3F942616E28B004B8251 /* APIService+Follow.swift in Sources */,
|
||||
);
|
||||
|
|
|
@ -1,6 +1,60 @@
|
|||
{
|
||||
"object": {
|
||||
"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",
|
||||
"repositoryURL": "https://github.com/Flipboard/FLAnimatedImage",
|
||||
|
@ -10,6 +64,42 @@
|
|||
"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",
|
||||
"repositoryURL": "https://github.com/kean/Nuke.git",
|
||||
|
@ -28,6 +118,42 @@
|
|||
"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",
|
||||
"repositoryURL": "https://github.com/apple/swift-nio.git",
|
||||
|
@ -63,6 +189,33 @@
|
|||
"revision": "b3dcd7dbd0d488e1a7077cb33b00f2083e382f07",
|
||||
"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 }
|
||||
switch item {
|
||||
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
|
||||
case .server(let server, let attribute):
|
||||
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 = 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(PickServerLoaderTableViewCell.self, forCellReuseIdentifier: String(describing: PickServerLoaderTableViewCell.self))
|
||||
tableView.rowHeight = UITableView.automaticDimension
|
||||
|
@ -236,6 +236,12 @@ extension MastodonPickServerViewController {
|
|||
viewModel.viewWillAppear.send()
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
tableView.flashScrollIndicators()
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
|
|
|
@ -14,8 +14,11 @@ import MetaTextKit
|
|||
|
||||
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 coordinator: SceneCoordinator! { willSet { precondition(!isViewLoaded) } }
|
||||
|
||||
|
@ -25,8 +28,8 @@ final class MastodonServerRulesViewController: UIViewController, NeedsDependency
|
|||
|
||||
let largeTitleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 34, weight: .bold))
|
||||
label.textColor = .label
|
||||
label.font = MastodonServerRulesViewController.largeTitleFont
|
||||
label.textColor = MastodonServerRulesViewController.largeTitleTextColor
|
||||
label.text = L10n.Scene.ServerRules.title
|
||||
label.numberOfLines = 0
|
||||
return label
|
||||
|
@ -34,56 +37,33 @@ final class MastodonServerRulesViewController: UIViewController, NeedsDependency
|
|||
|
||||
private(set) lazy var subtitleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = UIFontMetrics(forTextStyle: .title1).scaledFont(for: UIFont.systemFont(ofSize: 20))
|
||||
label.textColor = .secondaryLabel
|
||||
label.font = MastodonServerRulesViewController.subTitleFont
|
||||
label.textColor = MastodonServerRulesViewController.subTitleTextColor
|
||||
label.text = L10n.Scene.ServerRules.subtitle(viewModel.domain)
|
||||
label.numberOfLines = 0
|
||||
return label
|
||||
}()
|
||||
|
||||
let rulesLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold))
|
||||
label.textColor = Asset.Colors.Label.primary.color
|
||||
label.text = "Rules"
|
||||
label.numberOfLines = 0
|
||||
return label
|
||||
let tableView: UITableView = {
|
||||
let tableView = UITableView()
|
||||
tableView.register(OnboardingHeadlineTableViewCell.self, forCellReuseIdentifier: String(describing: OnboardingHeadlineTableViewCell.self))
|
||||
tableView.register(ServerRulesTableViewCell.self, forCellReuseIdentifier: String(describing: ServerRulesTableViewCell.self))
|
||||
tableView.rowHeight = UITableView.automaticDimension
|
||||
tableView.separatorStyle = .none
|
||||
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 view = UIView()
|
||||
view.backgroundColor = Asset.Theme.Mastodon.systemGroupedBackground.color
|
||||
return view
|
||||
}()
|
||||
|
||||
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
|
||||
|
||||
let navigationActionView: NavigationActionView = {
|
||||
let navigationActionView = NavigationActionView()
|
||||
navigationActionView.backgroundColor = Asset.Scene.Onboarding.onboardingBackground.color
|
||||
return navigationActionView
|
||||
}()
|
||||
|
||||
deinit {
|
||||
|
@ -97,224 +77,90 @@ extension MastodonServerRulesViewController {
|
|||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
navigationItem.leftBarButtonItem = UIBarButtonItem()
|
||||
|
||||
setupOnboardingAppearance()
|
||||
configureTitleLabel()
|
||||
configureMargin()
|
||||
configTextView()
|
||||
|
||||
defer { setupNavigationBarBackgroundView() }
|
||||
|
||||
bottomContainerView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(bottomContainerView)
|
||||
tableView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(tableView)
|
||||
NSLayoutConstraint.activate([
|
||||
view.bottomAnchor.constraint(equalTo: bottomContainerView.bottomAnchor),
|
||||
bottomContainerView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
bottomContainerView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
tableView.topAnchor.constraint(equalTo: view.topAnchor),
|
||||
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
|
||||
])
|
||||
bottomContainerView.preservesSuperviewLayoutMargins = true
|
||||
|
||||
navigationActionView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(navigationActionView)
|
||||
defer {
|
||||
view.bringSubviewToFront(bottomContainerView)
|
||||
view.bringSubviewToFront(navigationActionView)
|
||||
}
|
||||
|
||||
confirmButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
bottomContainerView.addSubview(confirmButton)
|
||||
NSLayoutConstraint.activate([
|
||||
bottomContainerView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: confirmButton.bottomAnchor, constant: MastodonServerRulesViewController.viewBottomPaddingHeight),
|
||||
confirmButton.leadingAnchor.constraint(equalTo: bottomContainerView.layoutMarginsGuide.leadingAnchor),
|
||||
bottomContainerView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: confirmButton.trailingAnchor),
|
||||
confirmButton.heightAnchor.constraint(equalToConstant: MastodonServerRulesViewController.actionButtonHeight).priority(.defaultHigh),
|
||||
navigationActionView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
navigationActionView.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
view.bottomAnchor.constraint(equalTo: navigationActionView.bottomAnchor),
|
||||
])
|
||||
|
||||
bottomPromptMetaText.textView.translatesAutoresizingMaskIntoConstraints = false
|
||||
bottomContainerView.addSubview(bottomPromptMetaText.textView)
|
||||
NSLayoutConstraint.activate([
|
||||
bottomPromptMetaText.textView.frameLayoutGuide.topAnchor.constraint(equalTo: bottomContainerView.topAnchor, constant: 20),
|
||||
bottomPromptMetaText.textView.frameLayoutGuide.leadingAnchor.constraint(equalTo: bottomContainerView.layoutMarginsGuide.leadingAnchor),
|
||||
bottomPromptMetaText.textView.frameLayoutGuide.trailingAnchor.constraint(equalTo: bottomContainerView.layoutMarginsGuide.trailingAnchor),
|
||||
confirmButton.topAnchor.constraint(equalTo: bottomPromptMetaText.textView.frameLayoutGuide.bottomAnchor, constant: 20),
|
||||
])
|
||||
navigationActionView
|
||||
.observe(\.bounds, options: [.initial, .new]) { [weak self] navigationActionView, _ in
|
||||
guard let self = self else { return }
|
||||
let inset = navigationActionView.frame.height
|
||||
self.tableView.contentInset.bottom = inset
|
||||
}
|
||||
.store(in: &observations)
|
||||
|
||||
scrollView.translatesAutoresizingMaskIntoConstraints = false
|
||||
view.addSubview(scrollView)
|
||||
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)
|
||||
tableView.delegate = self
|
||||
viewModel.setupDiffableDataSource(tableView: tableView)
|
||||
|
||||
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||
scrollView.addSubview(stackView)
|
||||
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)
|
||||
navigationActionView.backButton.addTarget(self, action: #selector(MastodonServerRulesViewController.backButtonPressed(_:)), for: .touchUpInside)
|
||||
navigationActionView.nextButton.addTarget(self, action: #selector(MastodonServerRulesViewController.nextButtonPressed(_:)), for: .touchUpInside)
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
scrollView.flashScrollIndicators()
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
updateScrollViewContentInset()
|
||||
}
|
||||
|
||||
override func viewSafeAreaInsetsDidChange() {
|
||||
super.viewSafeAreaInsetsDidChange()
|
||||
updateScrollViewContentInset()
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
setupNavigationBarAppearance()
|
||||
configureTitleLabel()
|
||||
configureMargin()
|
||||
tableView.flashScrollIndicators()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension MastodonServerRulesViewController {
|
||||
private func configureTitleLabel() {
|
||||
guard UIDevice.current.userInterfaceIdiom == .pad else {
|
||||
return
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@objc private func backButtonPressed(_ sender: UIButton) {
|
||||
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)")
|
||||
navigationController?.popViewController(animated: true)
|
||||
}
|
||||
|
||||
private func configureMargin() {
|
||||
switch traitCollection.horizontalSizeClass {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
@objc private func nextButtonPressed(_ sender: UIButton) {
|
||||
logger.log(level: .debug, "\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)")
|
||||
|
||||
extension MastodonServerRulesViewController {
|
||||
func updateScrollViewContentInset() {
|
||||
view.layoutIfNeeded()
|
||||
scrollView.contentInset.bottom = bottomContainerView.frame.height
|
||||
scrollView.verticalScrollIndicatorInsets.bottom = bottomContainerView.frame.height
|
||||
let viewModel = MastodonRegisterViewModel(domain: viewModel.domain, context: context, authenticateInfo: viewModel.authenticateInfo, instance: viewModel.instance, applicationToken: viewModel.applicationToken)
|
||||
coordinator.present(scene: .mastodonRegister(viewModel: viewModel), from: self, transition: .show)
|
||||
}
|
||||
|
||||
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
|
||||
extension MastodonServerRulesViewController: OnboardingViewControllerAppearance { }
|
||||
|
||||
#if canImport(SwiftUI) && DEBUG
|
||||
import SwiftUI
|
||||
|
||||
struct ServerRulesViewController_Previews: PreviewProvider {
|
||||
|
||||
static var previews: some View {
|
||||
UIViewControllerPreview {
|
||||
let viewController = MastodonServerRulesViewController()
|
||||
return viewController
|
||||
}
|
||||
.previewLayout(.fixed(width: 375, height: 800))
|
||||
// MARK: - UITableViewDelegate
|
||||
extension MastodonServerRulesViewController: UITableViewDelegate {
|
||||
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
||||
return UIView()
|
||||
}
|
||||
|
||||
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 applicationToken: Mastodon.Entity.Token
|
||||
|
||||
// output
|
||||
var diffableDataSource: UITableViewDiffableDataSource<ServerRuleSection, ServerRuleItem>?
|
||||
|
||||
init(
|
||||
domain: String,
|
||||
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 MastodonUI
|
||||
|
||||
final class NavigationActionView: UIView {
|
||||
|
||||
static let buttonHeight: CGFloat = 50
|
||||
|
||||
private var observations = Set<NSKeyValueObservation>()
|
||||
|
||||
let buttonContainer: UIStackView = {
|
||||
let stackView = UIStackView()
|
||||
stackView.axis = .horizontal
|
||||
|
@ -18,6 +21,7 @@ final class NavigationActionView: UIView {
|
|||
return stackView
|
||||
}()
|
||||
|
||||
let backButtonShadowContainer = ShadowBackgroundContainer()
|
||||
let backButton: PrimaryActionButton = {
|
||||
let button = PrimaryActionButton()
|
||||
button.action = .back
|
||||
|
@ -25,6 +29,7 @@ final class NavigationActionView: UIView {
|
|||
return button
|
||||
}()
|
||||
|
||||
let nextButtonShadowContainer = ShadowBackgroundContainer()
|
||||
let nextButton: PrimaryActionButton = {
|
||||
let button = PrimaryActionButton()
|
||||
button.action = .next
|
||||
|
@ -56,14 +61,33 @@ extension NavigationActionView {
|
|||
safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: buttonContainer.bottomAnchor, constant: 8),
|
||||
])
|
||||
|
||||
backButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
buttonContainer.addArrangedSubview(backButton)
|
||||
nextButton.translatesAutoresizingMaskIntoConstraints = false
|
||||
buttonContainer.addArrangedSubview(nextButton)
|
||||
backButtonShadowContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||
buttonContainer.addArrangedSubview(backButtonShadowContainer)
|
||||
nextButtonShadowContainer.translatesAutoresizingMaskIntoConstraints = false
|
||||
buttonContainer.addArrangedSubview(nextButtonShadowContainer)
|
||||
NSLayoutConstraint.activate([
|
||||
backButton.heightAnchor.constraint(equalToConstant: NavigationActionView.buttonHeight).priority(.required - 1),
|
||||
nextButton.heightAnchor.constraint(equalToConstant: NavigationActionView.buttonHeight).priority(.required - 1),
|
||||
nextButton.widthAnchor.constraint(equalTo: backButton.widthAnchor, multiplier: 2).priority(.required - 1),
|
||||
backButtonShadowContainer.heightAnchor.constraint(equalToConstant: NavigationActionView.buttonHeight).priority(.required - 1),
|
||||
nextButtonShadowContainer.heightAnchor.constraint(equalToConstant: NavigationActionView.buttonHeight).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
|
||||
//
|
||||
// Created by BradGao on 2021/2/23.
|
||||
|
@ -7,12 +7,12 @@
|
|||
|
||||
import UIKit
|
||||
|
||||
final class PickServerTitleCell: UITableViewCell {
|
||||
final class OnboardingHeadlineTableViewCell: UITableViewCell {
|
||||
|
||||
let titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 28, weight: .bold))
|
||||
label.textColor = Asset.Colors.Label.primary.color
|
||||
label.font = MastodonPickServerViewController.largeTitleFont
|
||||
label.textColor = MastodonPickServerViewController.largeTitleTextColor
|
||||
label.text = L10n.Scene.ServerPicker.title
|
||||
label.adjustsFontForContentSizeCategory = true
|
||||
label.numberOfLines = 0
|
||||
|
@ -21,8 +21,8 @@ final class PickServerTitleCell: UITableViewCell {
|
|||
|
||||
let subTitleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = UIFontMetrics(forTextStyle: .largeTitle).scaledFont(for: .systemFont(ofSize: 17, weight: .regular))
|
||||
label.textColor = Asset.Colors.Label.secondary.color
|
||||
label.font = MastodonPickServerViewController.subTitleFont
|
||||
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.adjustsFontForContentSizeCategory = true
|
||||
label.numberOfLines = 0
|
||||
|
@ -40,7 +40,7 @@ final class PickServerTitleCell: UITableViewCell {
|
|||
}
|
||||
}
|
||||
|
||||
extension PickServerTitleCell {
|
||||
extension OnboardingHeadlineTableViewCell {
|
||||
|
||||
private func _init() {
|
||||
selectionStyle = .none
|
|
@ -21,6 +21,22 @@ extension OnboardingViewControllerAppearance {
|
|||
static var viewBottomPaddingHeight: CGFloat { return 11 }
|
||||
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() {
|
||||
view.backgroundColor = Asset.Scene.Onboarding.onboardingBackground.color
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ final class WelcomeViewController: UIViewController, NeedsDependency {
|
|||
button.setTitleColor(.black, for: .normal)
|
||||
return button
|
||||
}()
|
||||
let signUpButtonShadowView = UIView()
|
||||
|
||||
private(set) lazy var signInButton: PrimaryActionButton = {
|
||||
let button = PrimaryActionButton()
|
||||
|
@ -72,7 +73,6 @@ final class WelcomeViewController: UIViewController, NeedsDependency {
|
|||
}()
|
||||
let signInButtonShadowView = UIView()
|
||||
|
||||
|
||||
deinit {
|
||||
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),
|
||||
])
|
||||
|
||||
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
|
||||
buttonContainer.addSubview(signInButtonShadowView)
|
||||
buttonContainer.sendSubviewToBack(signInButtonShadowView)
|
||||
|
@ -168,6 +178,17 @@ extension WelcomeViewController {
|
|||
extension WelcomeViewController {
|
||||
|
||||
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(
|
||||
color: .black,
|
||||
alpha: 0.25,
|
||||
|
|
|
@ -9,8 +9,8 @@ import UIKit
|
|||
|
||||
class PrimaryActionButton: UIButton {
|
||||
|
||||
var isLoading: Bool = false
|
||||
|
||||
private var originalButtonTitle: String?
|
||||
|
||||
lazy var activityIndicator: UIActivityIndicatorView = {
|
||||
let indicator = UIActivityIndicatorView(style: .medium)
|
||||
indicator.color = .white
|
||||
|
@ -18,16 +18,13 @@ class PrimaryActionButton: UIButton {
|
|||
indicator.translatesAutoresizingMaskIntoConstraints = false
|
||||
return indicator
|
||||
}()
|
||||
|
||||
private var originalButtonTitle: String?
|
||||
|
||||
var adjustsBackgroundImageWhenUserInterfaceStyleChanges = true
|
||||
var action: Action = .next {
|
||||
didSet {
|
||||
setupAppearance(action: action)
|
||||
}
|
||||
}
|
||||
|
||||
var adjustsBackgroundImageWhenUserInterfaceStyleChanges = true
|
||||
var isLoading: Bool = false
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
|
|
@ -9,7 +9,7 @@ import UIKit
|
|||
|
||||
extension CALayer {
|
||||
|
||||
func setupShadow(
|
||||
public func setupShadow(
|
||||
color: UIColor = .black,
|
||||
alpha: Float = 0.5,
|
||||
x: CGFloat = 0,
|
||||
|
@ -43,9 +43,8 @@ extension CALayer {
|
|||
}
|
||||
}
|
||||
|
||||
func removeShadow() {
|
||||
public func removeShadow() {
|
||||
shadowRadius = 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -10,12 +10,28 @@ import CoreImage.CIFilterBuiltins
|
|||
import UIKit
|
||||
|
||||
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)
|
||||
|
||||
return render.image { (context: UIGraphicsImageRendererContext) in
|
||||
// set clear fill
|
||||
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 {
|
||||
public struct Rule: Codable {
|
||||
public struct Rule: Codable, Hashable {
|
||||
public let id: 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