mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-25 09:41:00 +00:00
Select multiple statuses to report
This commit is contained in:
parent
5b360c6bc1
commit
7f2f192995
11 changed files with 417 additions and 289 deletions
|
@ -265,11 +265,14 @@
|
||||||
"report.target-%@" = "Report %@";
|
"report.target-%@" = "Report %@";
|
||||||
"report.forward.hint" = "The account is from another server. Send an anonymized copy of the report there as well?";
|
"report.forward.hint" = "The account is from another server. Send an anonymized copy of the report there as well?";
|
||||||
"report.forward-%@" = "Forward report to %@";
|
"report.forward-%@" = "Forward report to %@";
|
||||||
|
"report.select-additional.hint.post" = "Select additional posts to report:";
|
||||||
|
"report.select-additional.hint.toot" = "Select additional toots to report:";
|
||||||
"search.scope.all" = "All";
|
"search.scope.all" = "All";
|
||||||
"search.scope.accounts" = "People";
|
"search.scope.accounts" = "People";
|
||||||
"search.scope.statuses.post" = "Posts";
|
"search.scope.statuses.post" = "Posts";
|
||||||
"search.scope.statuses.toot" = "Toots";
|
"search.scope.statuses.toot" = "Toots";
|
||||||
"search.scope.tags" = "Hashtags";
|
"search.scope.tags" = "Hashtags";
|
||||||
|
"selected" = "Selected";
|
||||||
"send" = "Send";
|
"send" = "Send";
|
||||||
"share" = "Share";
|
"share" = "Share";
|
||||||
"share-extension-error.no-account-found" = "No account found";
|
"share-extension-error.no-account-found" = "No account found";
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
D0030982250C6C8500EACB32 /* URL+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0030981250C6C8500EACB32 /* URL+Extensions.swift */; };
|
D0030982250C6C8500EACB32 /* URL+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0030981250C6C8500EACB32 /* URL+Extensions.swift */; };
|
||||||
|
D005A1D825EF189A008B2E63 /* ReportViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D005A1D725EF189A008B2E63 /* ReportViewController.swift */; };
|
||||||
|
D005A1E625EF3D11008B2E63 /* ReportHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D005A1E525EF3D11008B2E63 /* ReportHeaderView.swift */; };
|
||||||
D00702292555E51200F38136 /* ConversationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00702282555E51200F38136 /* ConversationTableViewCell.swift */; };
|
D00702292555E51200F38136 /* ConversationTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00702282555E51200F38136 /* ConversationTableViewCell.swift */; };
|
||||||
D00702312555F4AE00F38136 /* ConversationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00702302555F4AE00F38136 /* ConversationView.swift */; };
|
D00702312555F4AE00F38136 /* ConversationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00702302555F4AE00F38136 /* ConversationView.swift */; };
|
||||||
D00702362555F4C500F38136 /* ConversationContentConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00702352555F4C500F38136 /* ConversationContentConfiguration.swift */; };
|
D00702362555F4C500F38136 /* ConversationContentConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = D00702352555F4C500F38136 /* ConversationContentConfiguration.swift */; };
|
||||||
|
@ -132,7 +134,6 @@
|
||||||
D09D971825C64682007E6394 /* InstanceCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09D971725C64682007E6394 /* InstanceCollectionViewCell.swift */; };
|
D09D971825C64682007E6394 /* InstanceCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09D971725C64682007E6394 /* InstanceCollectionViewCell.swift */; };
|
||||||
D09D972225C65682007E6394 /* SeparatorConfiguredCollectionViewListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09D972125C65682007E6394 /* SeparatorConfiguredCollectionViewListCell.swift */; };
|
D09D972225C65682007E6394 /* SeparatorConfiguredCollectionViewListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09D972125C65682007E6394 /* SeparatorConfiguredCollectionViewListCell.swift */; };
|
||||||
D0A1F4F7252E7D4B004435BF /* TableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A1F4F6252E7D4B004435BF /* TableViewDataSource.swift */; };
|
D0A1F4F7252E7D4B004435BF /* TableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A1F4F6252E7D4B004435BF /* TableViewDataSource.swift */; };
|
||||||
D0A7AC7325748BFF00E4E8AB /* ReportStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0A7AC7225748BFF00E4E8AB /* ReportStatusView.swift */; };
|
|
||||||
D0B325EB25E88ADC00C24BEA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0C7D45724F76169001EBDBB /* Localizable.strings */; };
|
D0B325EB25E88ADC00C24BEA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0C7D45724F76169001EBDBB /* Localizable.strings */; };
|
||||||
D0B32F50250B373600311912 /* RegistrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B32F4F250B373600311912 /* RegistrationView.swift */; };
|
D0B32F50250B373600311912 /* RegistrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B32F4F250B373600311912 /* RegistrationView.swift */; };
|
||||||
D0B5FE9B251583DB00478838 /* ProfileCollection+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B5FE9A251583DB00478838 /* ProfileCollection+Extensions.swift */; };
|
D0B5FE9B251583DB00478838 /* ProfileCollection+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B5FE9A251583DB00478838 /* ProfileCollection+Extensions.swift */; };
|
||||||
|
@ -187,7 +188,6 @@
|
||||||
D0D93ED025D9C9ED00C622ED /* AutocompleteItemCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D93ECF25D9C9ED00C622ED /* AutocompleteItemCollectionViewCell.swift */; };
|
D0D93ED025D9C9ED00C622ED /* AutocompleteItemCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D93ECF25D9C9ED00C622ED /* AutocompleteItemCollectionViewCell.swift */; };
|
||||||
D0D93ED925D9CBE200C622ED /* AutocompleteItemCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D93ECF25D9C9ED00C622ED /* AutocompleteItemCollectionViewCell.swift */; };
|
D0D93ED925D9CBE200C622ED /* AutocompleteItemCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0D93ECF25D9C9ED00C622ED /* AutocompleteItemCollectionViewCell.swift */; };
|
||||||
D0D93EDE25DA014700C622ED /* SeparatorConfiguredCollectionViewListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09D972125C65682007E6394 /* SeparatorConfiguredCollectionViewListCell.swift */; };
|
D0D93EDE25DA014700C622ED /* SeparatorConfiguredCollectionViewListCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D09D972125C65682007E6394 /* SeparatorConfiguredCollectionViewListCell.swift */; };
|
||||||
D0DD50CB256B1F24004A04F7 /* ReportView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DD50CA256B1F24004A04F7 /* ReportView.swift */; };
|
|
||||||
D0DDA76B25C5F20800FA0F91 /* ExploreDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DDA76A25C5F20800FA0F91 /* ExploreDataSource.swift */; };
|
D0DDA76B25C5F20800FA0F91 /* ExploreDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DDA76A25C5F20800FA0F91 /* ExploreDataSource.swift */; };
|
||||||
D0DDA77525C5F73F00FA0F91 /* TagCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DDA77425C5F73F00FA0F91 /* TagCollectionViewCell.swift */; };
|
D0DDA77525C5F73F00FA0F91 /* TagCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DDA77425C5F73F00FA0F91 /* TagCollectionViewCell.swift */; };
|
||||||
D0DDA77F25C6058300FA0F91 /* ExploreSectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DDA77E25C6058300FA0F91 /* ExploreSectionHeaderView.swift */; };
|
D0DDA77F25C6058300FA0F91 /* ExploreSectionHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0DDA77E25C6058300FA0F91 /* ExploreSectionHeaderView.swift */; };
|
||||||
|
@ -260,6 +260,8 @@
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
D0030981250C6C8500EACB32 /* URL+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Extensions.swift"; sourceTree = "<group>"; };
|
D0030981250C6C8500EACB32 /* URL+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Extensions.swift"; sourceTree = "<group>"; };
|
||||||
|
D005A1D725EF189A008B2E63 /* ReportViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportViewController.swift; sourceTree = "<group>"; };
|
||||||
|
D005A1E525EF3D11008B2E63 /* ReportHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportHeaderView.swift; sourceTree = "<group>"; };
|
||||||
D00702282555E51200F38136 /* ConversationTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationTableViewCell.swift; sourceTree = "<group>"; };
|
D00702282555E51200F38136 /* ConversationTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
D00702302555F4AE00F38136 /* ConversationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationView.swift; sourceTree = "<group>"; };
|
D00702302555F4AE00F38136 /* ConversationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationView.swift; sourceTree = "<group>"; };
|
||||||
D00702352555F4C500F38136 /* ConversationContentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationContentConfiguration.swift; sourceTree = "<group>"; };
|
D00702352555F4C500F38136 /* ConversationContentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConversationContentConfiguration.swift; sourceTree = "<group>"; };
|
||||||
|
@ -353,7 +355,6 @@
|
||||||
D09D971725C64682007E6394 /* InstanceCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceCollectionViewCell.swift; sourceTree = "<group>"; };
|
D09D971725C64682007E6394 /* InstanceCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstanceCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
D09D972125C65682007E6394 /* SeparatorConfiguredCollectionViewListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorConfiguredCollectionViewListCell.swift; sourceTree = "<group>"; };
|
D09D972125C65682007E6394 /* SeparatorConfiguredCollectionViewListCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeparatorConfiguredCollectionViewListCell.swift; sourceTree = "<group>"; };
|
||||||
D0A1F4F6252E7D4B004435BF /* TableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewDataSource.swift; sourceTree = "<group>"; };
|
D0A1F4F6252E7D4B004435BF /* TableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewDataSource.swift; sourceTree = "<group>"; };
|
||||||
D0A7AC7225748BFF00E4E8AB /* ReportStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportStatusView.swift; sourceTree = "<group>"; };
|
|
||||||
D0B32F4F250B373600311912 /* RegistrationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationView.swift; sourceTree = "<group>"; };
|
D0B32F4F250B373600311912 /* RegistrationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationView.swift; sourceTree = "<group>"; };
|
||||||
D0B5FE9A251583DB00478838 /* ProfileCollection+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProfileCollection+Extensions.swift"; sourceTree = "<group>"; };
|
D0B5FE9A251583DB00478838 /* ProfileCollection+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProfileCollection+Extensions.swift"; sourceTree = "<group>"; };
|
||||||
D0B8510B25259E56004E0744 /* LoadMoreTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadMoreTableViewCell.swift; sourceTree = "<group>"; };
|
D0B8510B25259E56004E0744 /* LoadMoreTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadMoreTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
|
@ -403,7 +404,6 @@
|
||||||
D0D93EB925D9C70400C622ED /* AutocompleteItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocompleteItemView.swift; sourceTree = "<group>"; };
|
D0D93EB925D9C70400C622ED /* AutocompleteItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocompleteItemView.swift; sourceTree = "<group>"; };
|
||||||
D0D93EBF25D9C71D00C622ED /* AutocompleteItemContentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocompleteItemContentConfiguration.swift; sourceTree = "<group>"; };
|
D0D93EBF25D9C71D00C622ED /* AutocompleteItemContentConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocompleteItemContentConfiguration.swift; sourceTree = "<group>"; };
|
||||||
D0D93ECF25D9C9ED00C622ED /* AutocompleteItemCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocompleteItemCollectionViewCell.swift; sourceTree = "<group>"; };
|
D0D93ECF25D9C9ED00C622ED /* AutocompleteItemCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutocompleteItemCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
D0DD50CA256B1F24004A04F7 /* ReportView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReportView.swift; sourceTree = "<group>"; };
|
|
||||||
D0DDA76A25C5F20800FA0F91 /* ExploreDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreDataSource.swift; sourceTree = "<group>"; };
|
D0DDA76A25C5F20800FA0F91 /* ExploreDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreDataSource.swift; sourceTree = "<group>"; };
|
||||||
D0DDA77425C5F73F00FA0F91 /* TagCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagCollectionViewCell.swift; sourceTree = "<group>"; };
|
D0DDA77425C5F73F00FA0F91 /* TagCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TagCollectionViewCell.swift; sourceTree = "<group>"; };
|
||||||
D0DDA77E25C6058300FA0F91 /* ExploreSectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreSectionHeaderView.swift; sourceTree = "<group>"; };
|
D0DDA77E25C6058300FA0F91 /* ExploreSectionHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExploreSectionHeaderView.swift; sourceTree = "<group>"; };
|
||||||
|
@ -509,6 +509,7 @@
|
||||||
D08B8D812544D80000B1EBEF /* PollOptionButton.swift */,
|
D08B8D812544D80000B1EBEF /* PollOptionButton.swift */,
|
||||||
D08B8D8C2544E6EC00B1EBEF /* PollResultView.swift */,
|
D08B8D8C2544E6EC00B1EBEF /* PollResultView.swift */,
|
||||||
D08B8D71254246E200B1EBEF /* PollView.swift */,
|
D08B8D71254246E200B1EBEF /* PollView.swift */,
|
||||||
|
D005A1E525EF3D11008B2E63 /* ReportHeaderView.swift */,
|
||||||
D08DFAF625CE20EA0005DA98 /* ScrollableToTop.swift */,
|
D08DFAF625CE20EA0005DA98 /* ScrollableToTop.swift */,
|
||||||
D035F8C625B96A4000DC75ED /* SecondaryNavigationButton.swift */,
|
D035F8C625B96A4000DC75ED /* SecondaryNavigationButton.swift */,
|
||||||
D03D87F325C23C44004DCBB2 /* SecondaryNavigationTitleView.swift */,
|
D03D87F325C23C44004DCBB2 /* SecondaryNavigationTitleView.swift */,
|
||||||
|
@ -535,7 +536,6 @@
|
||||||
D0C7D42D24F76169001EBDBB /* NotificationTypesPreferencesView.swift */,
|
D0C7D42D24F76169001EBDBB /* NotificationTypesPreferencesView.swift */,
|
||||||
D0C7D42624F76169001EBDBB /* PreferencesView.swift */,
|
D0C7D42624F76169001EBDBB /* PreferencesView.swift */,
|
||||||
D0B32F4F250B373600311912 /* RegistrationView.swift */,
|
D0B32F4F250B373600311912 /* RegistrationView.swift */,
|
||||||
D0DD50CA256B1F24004A04F7 /* ReportView.swift */,
|
|
||||||
D0C7D42724F76169001EBDBB /* RootView.swift */,
|
D0C7D42724F76169001EBDBB /* RootView.swift */,
|
||||||
D0C7D42924F76169001EBDBB /* SecondaryNavigationView.swift */,
|
D0C7D42924F76169001EBDBB /* SecondaryNavigationView.swift */,
|
||||||
D021A66925C3E19D008A0C0D /* View Controller Representables */,
|
D021A66925C3E19D008A0C0D /* View Controller Representables */,
|
||||||
|
@ -621,7 +621,6 @@
|
||||||
D021A67225C3E2C8008A0C0D /* View Repesentables */ = {
|
D021A67225C3E2C8008A0C0D /* View Repesentables */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
D0A7AC7225748BFF00E4E8AB /* ReportStatusView.swift */,
|
|
||||||
);
|
);
|
||||||
path = "View Repesentables";
|
path = "View Repesentables";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -758,6 +757,7 @@
|
||||||
D0FCC104259C4E61000B67DF /* NewStatusViewController.swift */,
|
D0FCC104259C4E61000B67DF /* NewStatusViewController.swift */,
|
||||||
D097F4C025BFA04C00859F2C /* NotificationsViewController.swift */,
|
D097F4C025BFA04C00859F2C /* NotificationsViewController.swift */,
|
||||||
D06BC5E525202AD90079541D /* ProfileViewController.swift */,
|
D06BC5E525202AD90079541D /* ProfileViewController.swift */,
|
||||||
|
D005A1D725EF189A008B2E63 /* ReportViewController.swift */,
|
||||||
D0F0B12D251A97E400942152 /* TableViewController.swift */,
|
D0F0B12D251A97E400942152 /* TableViewController.swift */,
|
||||||
D035F87C25B7F61600DC75ED /* TimelinesViewController.swift */,
|
D035F87C25B7F61600DC75ED /* TimelinesViewController.swift */,
|
||||||
);
|
);
|
||||||
|
@ -1063,7 +1063,6 @@
|
||||||
D08B8D622540DE3B00B1EBEF /* ZoomTransitionController.swift in Sources */,
|
D08B8D622540DE3B00B1EBEF /* ZoomTransitionController.swift in Sources */,
|
||||||
D0F0B12E251A97E400942152 /* TableViewController.swift in Sources */,
|
D0F0B12E251A97E400942152 /* TableViewController.swift in Sources */,
|
||||||
D0477F2C25C6EBAD005C5368 /* OpenInDefaultBrowserActivity.swift in Sources */,
|
D0477F2C25C6EBAD005C5368 /* OpenInDefaultBrowserActivity.swift in Sources */,
|
||||||
D0DD50CB256B1F24004A04F7 /* ReportView.swift in Sources */,
|
|
||||||
D07F4D9825D493E300F61133 /* MuteView.swift in Sources */,
|
D07F4D9825D493E300F61133 /* MuteView.swift in Sources */,
|
||||||
D02D338D25EDA593000A35CC /* CopyableLabel.swift in Sources */,
|
D02D338D25EDA593000A35CC /* CopyableLabel.swift in Sources */,
|
||||||
D097F41B25BE3E1A00859F2C /* SearchScope+Extensions.swift in Sources */,
|
D097F41B25BE3E1A00859F2C /* SearchScope+Extensions.swift in Sources */,
|
||||||
|
@ -1075,6 +1074,7 @@
|
||||||
D0CEC11025E3462B00FEF5A6 /* AnimatedAttachmentLabel.swift in Sources */,
|
D0CEC11025E3462B00FEF5A6 /* AnimatedAttachmentLabel.swift in Sources */,
|
||||||
D05E688525B55AE8001FB2C6 /* AVURLAsset+Extensions.swift in Sources */,
|
D05E688525B55AE8001FB2C6 /* AVURLAsset+Extensions.swift in Sources */,
|
||||||
D0D93EC025D9C71D00C622ED /* AutocompleteItemContentConfiguration.swift in Sources */,
|
D0D93EC025D9C71D00C622ED /* AutocompleteItemContentConfiguration.swift in Sources */,
|
||||||
|
D005A1E625EF3D11008B2E63 /* ReportHeaderView.swift in Sources */,
|
||||||
D09D970E25C64539007E6394 /* InstanceContentConfiguration.swift in Sources */,
|
D09D970E25C64539007E6394 /* InstanceContentConfiguration.swift in Sources */,
|
||||||
D036AA02254B6101009094DF /* NotificationTableViewCell.swift in Sources */,
|
D036AA02254B6101009094DF /* NotificationTableViewCell.swift in Sources */,
|
||||||
D08B8D42253F92B600B1EBEF /* ImagePageViewController.swift in Sources */,
|
D08B8D42253F92B600B1EBEF /* ImagePageViewController.swift in Sources */,
|
||||||
|
@ -1094,6 +1094,7 @@
|
||||||
D021A61A25C36C1A008A0C0D /* IdentityContentConfiguration.swift in Sources */,
|
D021A61A25C36C1A008A0C0D /* IdentityContentConfiguration.swift in Sources */,
|
||||||
D0C7D49E24F7616A001EBDBB /* SecondaryNavigationView.swift in Sources */,
|
D0C7D49E24F7616A001EBDBB /* SecondaryNavigationView.swift in Sources */,
|
||||||
D08B8D602540DE3B00B1EBEF /* ZoomAnimator.swift in Sources */,
|
D08B8D602540DE3B00B1EBEF /* ZoomAnimator.swift in Sources */,
|
||||||
|
D005A1D825EF189A008B2E63 /* ReportViewController.swift in Sources */,
|
||||||
D08B8D672540DEB200B1EBEF /* ZoomAnimatableView.swift in Sources */,
|
D08B8D672540DEB200B1EBEF /* ZoomAnimatableView.swift in Sources */,
|
||||||
D0CEC0F725E3303200FEF5A6 /* AnimatingLayoutManager.swift in Sources */,
|
D0CEC0F725E3303200FEF5A6 /* AnimatingLayoutManager.swift in Sources */,
|
||||||
D08B8D822544D80000B1EBEF /* PollOptionButton.swift in Sources */,
|
D08B8D822544D80000B1EBEF /* PollOptionButton.swift in Sources */,
|
||||||
|
@ -1163,7 +1164,6 @@
|
||||||
D0FCC105259C4E61000B67DF /* NewStatusViewController.swift in Sources */,
|
D0FCC105259C4E61000B67DF /* NewStatusViewController.swift in Sources */,
|
||||||
D087671625BAA8C0001FDD43 /* ExploreViewController.swift in Sources */,
|
D087671625BAA8C0001FDD43 /* ExploreViewController.swift in Sources */,
|
||||||
D0D2AC6725BD0484003D5DF2 /* LineChartView.swift in Sources */,
|
D0D2AC6725BD0484003D5DF2 /* LineChartView.swift in Sources */,
|
||||||
D0A7AC7325748BFF00E4E8AB /* ReportStatusView.swift in Sources */,
|
|
||||||
D0C7D4C324F7616A001EBDBB /* MetatextApp.swift in Sources */,
|
D0C7D4C324F7616A001EBDBB /* MetatextApp.swift in Sources */,
|
||||||
D097F4C125BFA04C00859F2C /* NotificationsViewController.swift in Sources */,
|
D097F4C125BFA04C00859F2C /* NotificationsViewController.swift in Sources */,
|
||||||
D02D33EF25EE04CC000A35CC /* AddRemoveFromListsView.swift in Sources */,
|
D02D33EF25EE04CC000A35CC /* AddRemoveFromListsView.swift in Sources */,
|
||||||
|
|
112
View Controllers/ReportViewController.swift
Normal file
112
View Controllers/ReportViewController.swift
Normal file
|
@ -0,0 +1,112 @@
|
||||||
|
// Copyright © 2021 Metabolist. All rights reserved.
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import UIKit
|
||||||
|
import ViewModels
|
||||||
|
|
||||||
|
final class ReportViewController: TableViewController {
|
||||||
|
private let reportButton = UIBarButtonItem(
|
||||||
|
title: nil,
|
||||||
|
style: .done,
|
||||||
|
target: nil,
|
||||||
|
action: nil)
|
||||||
|
private let activityIndicatorView = UIActivityIndicatorView(style: .large)
|
||||||
|
private let viewModel: ReportViewModel
|
||||||
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
init(viewModel: ReportViewModel) {
|
||||||
|
self.viewModel = viewModel
|
||||||
|
|
||||||
|
super.init(viewModel: viewModel)
|
||||||
|
}
|
||||||
|
|
||||||
|
override func viewDidLoad() {
|
||||||
|
super.viewDidLoad()
|
||||||
|
|
||||||
|
navigationItem.title = String.localizedStringWithFormat(
|
||||||
|
NSLocalizedString("report.target-%@", comment: ""),
|
||||||
|
viewModel.accountName)
|
||||||
|
navigationItem.leftBarButtonItem = UIBarButtonItem(
|
||||||
|
systemItem: .cancel,
|
||||||
|
primaryAction: UIAction { [weak self] _ in self?.presentingViewController?.dismiss(animated: true) })
|
||||||
|
navigationItem.rightBarButtonItem = reportButton
|
||||||
|
reportButton.primaryAction = UIAction(title: NSLocalizedString("report", comment: "")) { [weak self] _ in
|
||||||
|
self?.viewModel.report()
|
||||||
|
}
|
||||||
|
|
||||||
|
tableView.tableHeaderView = ReportHeaderView(viewModel: viewModel)
|
||||||
|
|
||||||
|
view.addSubview(activityIndicatorView)
|
||||||
|
activityIndicatorView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
activityIndicatorView.hidesWhenStopped = true
|
||||||
|
|
||||||
|
viewModel.$reportingState
|
||||||
|
.sink { [weak self] in self?.apply(reportingState: $0) }
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
activityIndicatorView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
|
||||||
|
activityIndicatorView.centerYAnchor.constraint(equalTo: view.centerYAnchor)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView,
|
||||||
|
willDisplay cell: UITableViewCell,
|
||||||
|
forRowAt indexPath: IndexPath) {
|
||||||
|
super.tableView(tableView, willDisplay: cell, forRowAt: indexPath)
|
||||||
|
|
||||||
|
guard let statusView = cell.contentView as? StatusView else { return }
|
||||||
|
|
||||||
|
statusView.alpha = 0.75
|
||||||
|
statusView.buttonsStackView.isHidden = true
|
||||||
|
statusView.reportSelectionSwitch.isHidden = false
|
||||||
|
|
||||||
|
for subview in statusView.subviews {
|
||||||
|
subview.isUserInteractionEnabled = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override func configureRightBarButtonItem(expandAllState: ExpandAllState) {
|
||||||
|
// no-op
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||||
|
tableView.deselectRow(at: indexPath, animated: true)
|
||||||
|
|
||||||
|
guard let statusViewModel = viewModel.viewModel(indexPath: indexPath) as? StatusViewModel else { return }
|
||||||
|
|
||||||
|
if viewModel.elements.statusIds.contains(statusViewModel.id) {
|
||||||
|
viewModel.elements.statusIds.remove(statusViewModel.id)
|
||||||
|
} else {
|
||||||
|
viewModel.elements.statusIds.insert(statusViewModel.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
let selectedForReport = viewModel.elements.statusIds.contains(statusViewModel.id)
|
||||||
|
|
||||||
|
statusViewModel.selectedForReport = selectedForReport
|
||||||
|
|
||||||
|
guard let statusView = tableView.cellForRow(at: indexPath)?.contentView as? StatusView else { return }
|
||||||
|
|
||||||
|
statusView.reportSelectionSwitch.setOn(selectedForReport, animated: true)
|
||||||
|
statusView.refreshAccessibilityLabel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension ReportViewController {
|
||||||
|
func apply(reportingState: ReportViewModel.ReportingState) {
|
||||||
|
switch reportingState {
|
||||||
|
case .composing:
|
||||||
|
activityIndicatorView.stopAnimating()
|
||||||
|
view.isUserInteractionEnabled = true
|
||||||
|
reportButton.isEnabled = true
|
||||||
|
view.alpha = 1
|
||||||
|
case .reporting:
|
||||||
|
activityIndicatorView.startAnimating()
|
||||||
|
view.isUserInteractionEnabled = false
|
||||||
|
reportButton.isEnabled = false
|
||||||
|
view.alpha = 0.5
|
||||||
|
case .done:
|
||||||
|
presentingViewController?.dismiss(animated: true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -179,6 +179,23 @@ class TableViewController: UITableViewController {
|
||||||
|
|
||||||
sizeTableHeaderFooterViews()
|
sizeTableHeaderFooterViews()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func configureRightBarButtonItem(expandAllState: ExpandAllState) {
|
||||||
|
switch expandAllState {
|
||||||
|
case .hidden:
|
||||||
|
navigationItem.rightBarButtonItem = nil
|
||||||
|
case .expand:
|
||||||
|
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
||||||
|
title: NSLocalizedString("status.show-more-all-button.accessibilty-label", comment: ""),
|
||||||
|
image: UIImage(systemName: "eye"),
|
||||||
|
primaryAction: UIAction { [weak self] _ in self?.viewModel.toggleExpandAll() })
|
||||||
|
case .collapse:
|
||||||
|
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
||||||
|
title: NSLocalizedString("status.show-less-all-button.accessibilty-label", comment: ""),
|
||||||
|
image: UIImage(systemName: "eye.slash"),
|
||||||
|
primaryAction: UIAction { [weak self] _ in self?.viewModel.toggleExpandAll() })
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TableViewController {
|
extension TableViewController {
|
||||||
|
@ -373,7 +390,7 @@ private extension TableViewController {
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
viewModel.expandAll.receive(on: DispatchQueue.main)
|
viewModel.expandAll.receive(on: DispatchQueue.main)
|
||||||
.sink { [weak self] in self?.set(expandAllState: $0) }
|
.sink { [weak self] in self?.configureRightBarButtonItem(expandAllState: $0) }
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
viewModel.loading.receive(on: DispatchQueue.main).assign(to: &$loading)
|
viewModel.loading.receive(on: DispatchQueue.main).assign(to: &$loading)
|
||||||
|
@ -741,23 +758,6 @@ private extension TableViewController {
|
||||||
viewModel.applyAccountListEdit(viewModel: accountViewModel, edit: edit)
|
viewModel.applyAccountListEdit(viewModel: accountViewModel, edit: edit)
|
||||||
}
|
}
|
||||||
|
|
||||||
func set(expandAllState: ExpandAllState) {
|
|
||||||
switch expandAllState {
|
|
||||||
case .hidden:
|
|
||||||
navigationItem.rightBarButtonItem = nil
|
|
||||||
case .expand:
|
|
||||||
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
|
||||||
title: NSLocalizedString("status.show-more-all-button.accessibilty-label", comment: ""),
|
|
||||||
image: UIImage(systemName: "eye"),
|
|
||||||
primaryAction: UIAction { [weak self] _ in self?.viewModel.toggleExpandAll() })
|
|
||||||
case .collapse:
|
|
||||||
navigationItem.rightBarButtonItem = UIBarButtonItem(
|
|
||||||
title: NSLocalizedString("status.show-less-all-button.accessibilty-label", comment: ""),
|
|
||||||
image: UIImage(systemName: "eye.slash"),
|
|
||||||
primaryAction: UIAction { [weak self] _ in self?.viewModel.toggleExpandAll() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func share(url: URL) {
|
func share(url: URL) {
|
||||||
let activityViewController = UIActivityViewController(
|
let activityViewController = UIActivityViewController(
|
||||||
activityItems: [url],
|
activityItems: [url],
|
||||||
|
|
|
@ -95,116 +95,6 @@ public class CollectionItemsViewModel: ObservableObject {
|
||||||
|
|
||||||
request(maxId: maxId, minId: nil, search: nil)
|
request(maxId: maxId, minId: nil, search: nil)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
extension CollectionItemsViewModel: CollectionViewModel {
|
|
||||||
public var title: AnyPublisher<String, Never> { collectionService.title }
|
|
||||||
|
|
||||||
public var titleLocalizationComponents: AnyPublisher<[String], Never> {
|
|
||||||
collectionService.titleLocalizationComponents
|
|
||||||
}
|
|
||||||
|
|
||||||
public var expandAll: AnyPublisher<ExpandAllState, Never> {
|
|
||||||
expandAllSubject.eraseToAnyPublisher()
|
|
||||||
}
|
|
||||||
|
|
||||||
public var alertItems: AnyPublisher<AlertItem, Never> { $alertItem.compactMap { $0 }.eraseToAnyPublisher() }
|
|
||||||
|
|
||||||
public var loading: AnyPublisher<Bool, Never> { loadingSubject.eraseToAnyPublisher() }
|
|
||||||
|
|
||||||
public var events: AnyPublisher<CollectionItemEvent, Never> {
|
|
||||||
eventsSubject.flatMap { [weak self] eventPublisher -> AnyPublisher<CollectionItemEvent, Never> in
|
|
||||||
guard let self = self else { return Empty().eraseToAnyPublisher() }
|
|
||||||
|
|
||||||
return eventPublisher.assignErrorsToAlertItem(to: \.alertItem, on: self).eraseToAnyPublisher()
|
|
||||||
}
|
|
||||||
.eraseToAnyPublisher()
|
|
||||||
}
|
|
||||||
|
|
||||||
public var searchScopeChanges: AnyPublisher<SearchScope, Never> { searchScopeChangesSubject.eraseToAnyPublisher() }
|
|
||||||
|
|
||||||
public var canRefresh: Bool { collectionService.canRefresh }
|
|
||||||
|
|
||||||
public var announcesNewItems: Bool { collectionService.announcesNewItems }
|
|
||||||
|
|
||||||
public func request(maxId: String? = nil, minId: String? = nil, search: Search?) {
|
|
||||||
collectionService.request(maxId: realMaxId(maxId: maxId), minId: minId, search: search)
|
|
||||||
.receive(on: DispatchQueue.main)
|
|
||||||
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
|
||||||
.handleEvents(
|
|
||||||
receiveSubscription: { [weak self] _ in self?.loadingSubject.send(true) },
|
|
||||||
receiveCompletion: { [weak self] _ in self?.loadingSubject.send(false) })
|
|
||||||
.sink { _ in }
|
|
||||||
.store(in: &cancellables)
|
|
||||||
collectionService.requestMarkerLastReadId()
|
|
||||||
.sink { _ in } receiveValue: { [weak self] in self?.markerLastReadId = $0 }
|
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public func select(indexPath: IndexPath) {
|
|
||||||
let item = lastUpdate.sections[indexPath.section].items[indexPath.item]
|
|
||||||
|
|
||||||
switch item {
|
|
||||||
case let .status(status, _, _):
|
|
||||||
send(event: .navigation(.collection(collectionService
|
|
||||||
.navigationService
|
|
||||||
.contextService(id: status.displayStatus.id))))
|
|
||||||
case let .loadMore(loadMore):
|
|
||||||
lastSelectedLoadMore = loadMore
|
|
||||||
(viewModel(indexPath: indexPath) as? LoadMoreViewModel)?.loadMore()
|
|
||||||
case let .account(account, _, relationship):
|
|
||||||
send(event: .navigation(.profile(collectionService
|
|
||||||
.navigationService
|
|
||||||
.profileService(account: account, relationship: relationship))))
|
|
||||||
case let .notification(notification, _):
|
|
||||||
if let status = notification.status {
|
|
||||||
send(event: .navigation(.collection(collectionService
|
|
||||||
.navigationService
|
|
||||||
.contextService(id: status.displayStatus.id))))
|
|
||||||
} else {
|
|
||||||
send(event: .navigation(.profile(collectionService
|
|
||||||
.navigationService
|
|
||||||
.profileService(account: notification.account))))
|
|
||||||
}
|
|
||||||
case let .conversation(conversation):
|
|
||||||
guard let status = conversation.lastStatus else { break }
|
|
||||||
|
|
||||||
(collectionService as? ConversationsService)?.markConversationAsRead(id: conversation.id)
|
|
||||||
.sink { _ in } receiveValue: { _ in }
|
|
||||||
.store(in: &cancellables)
|
|
||||||
|
|
||||||
send(event: .navigation(.collection(collectionService
|
|
||||||
.navigationService
|
|
||||||
.contextService(id: status.displayStatus.id))))
|
|
||||||
case let .tag(tag):
|
|
||||||
send(event: .navigation(.collection(collectionService
|
|
||||||
.navigationService
|
|
||||||
.timelineService(timeline: .tag(tag.name)))))
|
|
||||||
case let .moreResults(moreResults):
|
|
||||||
searchScopeChangesSubject.send(moreResults.scope)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func viewedAtTop(indexPath: IndexPath) {
|
|
||||||
topVisibleIndexPath = indexPath
|
|
||||||
|
|
||||||
if lastUpdate.sections.count > indexPath.section,
|
|
||||||
lastUpdate.sections[indexPath.section].items.count > indexPath.item {
|
|
||||||
lastReadId.send(lastUpdate.sections[indexPath.section].items[indexPath.item].itemId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public func canSelect(indexPath: IndexPath) -> Bool {
|
|
||||||
switch lastUpdate.sections[indexPath.section].items[indexPath.item] {
|
|
||||||
case let .status(_, configuration, _):
|
|
||||||
return !configuration.isContextParent
|
|
||||||
case .loadMore:
|
|
||||||
return !((viewModel(indexPath: indexPath) as? LoadMoreViewModel)?.loading ?? false)
|
|
||||||
default:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// swiftlint:disable:next function_body_length cyclomatic_complexity
|
// swiftlint:disable:next function_body_length cyclomatic_complexity
|
||||||
public func viewModel(indexPath: IndexPath) -> Any {
|
public func viewModel(indexPath: IndexPath) -> Any {
|
||||||
|
@ -317,6 +207,116 @@ extension CollectionItemsViewModel: CollectionViewModel {
|
||||||
return viewModel
|
return viewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension CollectionItemsViewModel: CollectionViewModel {
|
||||||
|
public var title: AnyPublisher<String, Never> { collectionService.title }
|
||||||
|
|
||||||
|
public var titleLocalizationComponents: AnyPublisher<[String], Never> {
|
||||||
|
collectionService.titleLocalizationComponents
|
||||||
|
}
|
||||||
|
|
||||||
|
public var expandAll: AnyPublisher<ExpandAllState, Never> {
|
||||||
|
expandAllSubject.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
public var alertItems: AnyPublisher<AlertItem, Never> { $alertItem.compactMap { $0 }.eraseToAnyPublisher() }
|
||||||
|
|
||||||
|
public var loading: AnyPublisher<Bool, Never> { loadingSubject.eraseToAnyPublisher() }
|
||||||
|
|
||||||
|
public var events: AnyPublisher<CollectionItemEvent, Never> {
|
||||||
|
eventsSubject.flatMap { [weak self] eventPublisher -> AnyPublisher<CollectionItemEvent, Never> in
|
||||||
|
guard let self = self else { return Empty().eraseToAnyPublisher() }
|
||||||
|
|
||||||
|
return eventPublisher.assignErrorsToAlertItem(to: \.alertItem, on: self).eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
.eraseToAnyPublisher()
|
||||||
|
}
|
||||||
|
|
||||||
|
public var searchScopeChanges: AnyPublisher<SearchScope, Never> { searchScopeChangesSubject.eraseToAnyPublisher() }
|
||||||
|
|
||||||
|
public var canRefresh: Bool { collectionService.canRefresh }
|
||||||
|
|
||||||
|
public var announcesNewItems: Bool { collectionService.announcesNewItems }
|
||||||
|
|
||||||
|
public func request(maxId: String? = nil, minId: String? = nil, search: Search?) {
|
||||||
|
collectionService.request(maxId: realMaxId(maxId: maxId), minId: minId, search: search)
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
||||||
|
.handleEvents(
|
||||||
|
receiveSubscription: { [weak self] _ in self?.loadingSubject.send(true) },
|
||||||
|
receiveCompletion: { [weak self] _ in self?.loadingSubject.send(false) })
|
||||||
|
.sink { _ in }
|
||||||
|
.store(in: &cancellables)
|
||||||
|
collectionService.requestMarkerLastReadId()
|
||||||
|
.sink { _ in } receiveValue: { [weak self] in self?.markerLastReadId = $0 }
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public func select(indexPath: IndexPath) {
|
||||||
|
let item = lastUpdate.sections[indexPath.section].items[indexPath.item]
|
||||||
|
|
||||||
|
switch item {
|
||||||
|
case let .status(status, _, _):
|
||||||
|
send(event: .navigation(.collection(collectionService
|
||||||
|
.navigationService
|
||||||
|
.contextService(id: status.displayStatus.id))))
|
||||||
|
case let .loadMore(loadMore):
|
||||||
|
lastSelectedLoadMore = loadMore
|
||||||
|
(viewModel(indexPath: indexPath) as? LoadMoreViewModel)?.loadMore()
|
||||||
|
case let .account(account, _, relationship):
|
||||||
|
send(event: .navigation(.profile(collectionService
|
||||||
|
.navigationService
|
||||||
|
.profileService(account: account, relationship: relationship))))
|
||||||
|
case let .notification(notification, _):
|
||||||
|
if let status = notification.status {
|
||||||
|
send(event: .navigation(.collection(collectionService
|
||||||
|
.navigationService
|
||||||
|
.contextService(id: status.displayStatus.id))))
|
||||||
|
} else {
|
||||||
|
send(event: .navigation(.profile(collectionService
|
||||||
|
.navigationService
|
||||||
|
.profileService(account: notification.account))))
|
||||||
|
}
|
||||||
|
case let .conversation(conversation):
|
||||||
|
guard let status = conversation.lastStatus else { break }
|
||||||
|
|
||||||
|
(collectionService as? ConversationsService)?.markConversationAsRead(id: conversation.id)
|
||||||
|
.sink { _ in } receiveValue: { _ in }
|
||||||
|
.store(in: &cancellables)
|
||||||
|
|
||||||
|
send(event: .navigation(.collection(collectionService
|
||||||
|
.navigationService
|
||||||
|
.contextService(id: status.displayStatus.id))))
|
||||||
|
case let .tag(tag):
|
||||||
|
send(event: .navigation(.collection(collectionService
|
||||||
|
.navigationService
|
||||||
|
.timelineService(timeline: .tag(tag.name)))))
|
||||||
|
case let .moreResults(moreResults):
|
||||||
|
searchScopeChangesSubject.send(moreResults.scope)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func viewedAtTop(indexPath: IndexPath) {
|
||||||
|
topVisibleIndexPath = indexPath
|
||||||
|
|
||||||
|
if lastUpdate.sections.count > indexPath.section,
|
||||||
|
lastUpdate.sections[indexPath.section].items.count > indexPath.item {
|
||||||
|
lastReadId.send(lastUpdate.sections[indexPath.section].items[indexPath.item].itemId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public func canSelect(indexPath: IndexPath) -> Bool {
|
||||||
|
switch lastUpdate.sections[indexPath.section].items[indexPath.item] {
|
||||||
|
case let .status(_, configuration, _):
|
||||||
|
return !configuration.isContextParent
|
||||||
|
case .loadMore:
|
||||||
|
return !((viewModel(indexPath: indexPath) as? LoadMoreViewModel)?.loading ?? false)
|
||||||
|
default:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func toggleExpandAll() {
|
public func toggleExpandAll() {
|
||||||
let statusIds = Set(lastUpdate.sections.map(\.items).reduce([], +).compactMap { item -> Status.Id? in
|
let statusIds = Set(lastUpdate.sections.map(\.items).reduce([], +).compactMap { item -> Status.Id? in
|
||||||
|
|
|
@ -5,36 +5,44 @@ import Foundation
|
||||||
import Mastodon
|
import Mastodon
|
||||||
import ServiceLayer
|
import ServiceLayer
|
||||||
|
|
||||||
public final class ReportViewModel: ObservableObject {
|
public final class ReportViewModel: CollectionItemsViewModel {
|
||||||
@Published public var elements: ReportElements
|
@Published public var elements: ReportElements
|
||||||
public let events: AnyPublisher<Event, Never>
|
@Published public private(set) var reportingState = ReportingState.composing
|
||||||
public let statusViewModel: StatusViewModel?
|
|
||||||
@Published public private(set) var loading = false
|
|
||||||
@Published public var alertItem: AlertItem?
|
|
||||||
|
|
||||||
private let accountService: AccountService
|
private let accountService: AccountService
|
||||||
private let eventsSubject = PassthroughSubject<Event, Never>()
|
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
public init(accountService: AccountService, statusService: StatusService? = nil, identityContext: IdentityContext) {
|
public init(accountService: AccountService, statusId: Status.Id? = nil, identityContext: IdentityContext) {
|
||||||
self.accountService = accountService
|
self.accountService = accountService
|
||||||
elements = ReportElements(accountId: accountService.account.id)
|
elements = ReportElements(accountId: accountService.account.id)
|
||||||
events = eventsSubject.eraseToAnyPublisher()
|
|
||||||
|
|
||||||
if let statusService = statusService {
|
super.init(
|
||||||
statusViewModel = StatusViewModel(statusService: statusService,
|
collectionService: identityContext.service.navigationService.timelineService(
|
||||||
identityContext: identityContext,
|
timeline: .profile(accountId: accountService.account.id, profileCollection: .statusesAndReplies)),
|
||||||
eventsSubject: .init())
|
identityContext: identityContext)
|
||||||
elements.statusIds.insert(statusService.status.displayStatus.id)
|
|
||||||
} else {
|
if let statusId = statusId {
|
||||||
statusViewModel = nil
|
elements.statusIds.insert(statusId)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override func viewModel(indexPath: IndexPath) -> Any {
|
||||||
|
let viewModel = super.viewModel(indexPath: indexPath)
|
||||||
|
|
||||||
|
if let statusViewModel = viewModel as? StatusViewModel {
|
||||||
|
statusViewModel.showReportSelectionToggle = true
|
||||||
|
statusViewModel.selectedForReport = elements.statusIds.contains(statusViewModel.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
return viewModel
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension ReportViewModel {
|
public extension ReportViewModel {
|
||||||
enum Event {
|
enum ReportingState {
|
||||||
case reported
|
case composing
|
||||||
|
case reporting
|
||||||
|
case done
|
||||||
}
|
}
|
||||||
|
|
||||||
var accountName: String { "@".appending(accountService.account.acct) }
|
var accountName: String { "@".appending(accountService.account.acct) }
|
||||||
|
@ -48,15 +56,16 @@ public extension ReportViewModel {
|
||||||
func report() {
|
func report() {
|
||||||
accountService.report(elements)
|
accountService.report(elements)
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
.handleEvents(receiveSubscription: { [weak self] _ in self?.loading = true })
|
.handleEvents(receiveSubscription: { [weak self] _ in self?.reportingState = .reporting })
|
||||||
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
|
||||||
.sink { [weak self] in
|
.sink { [weak self] in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
|
|
||||||
self.loading = false
|
switch $0 {
|
||||||
|
case .finished:
|
||||||
if $0 == .finished {
|
self.reportingState = .done
|
||||||
self.eventsSubject.send(.reported)
|
case let .failure(error):
|
||||||
|
self.alertItem = AlertItem(error: error)
|
||||||
|
self.reportingState = .composing
|
||||||
}
|
}
|
||||||
} receiveValue: { _ in }
|
} receiveValue: { _ in }
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
|
@ -17,6 +17,8 @@ public final class StatusViewModel: AttachmentsRenderingViewModel, ObservableObj
|
||||||
public let pollEmojis: [Emoji]
|
public let pollEmojis: [Emoji]
|
||||||
@Published public var pollOptionSelections = Set<Int>()
|
@Published public var pollOptionSelections = Set<Int>()
|
||||||
public var configuration = CollectionItem.StatusConfiguration.default
|
public var configuration = CollectionItem.StatusConfiguration.default
|
||||||
|
public var showReportSelectionToggle = false
|
||||||
|
public var selectedForReport = false
|
||||||
public let identityContext: IdentityContext
|
public let identityContext: IdentityContext
|
||||||
|
|
||||||
private let statusService: StatusService
|
private let statusService: StatusService
|
||||||
|
@ -349,7 +351,7 @@ public extension StatusViewModel {
|
||||||
Just(.report(ReportViewModel(
|
Just(.report(ReportViewModel(
|
||||||
accountService: statusService.navigationService.accountService(
|
accountService: statusService.navigationService.accountService(
|
||||||
account: statusService.status.displayStatus.account),
|
account: statusService.status.displayStatus.account),
|
||||||
statusService: statusService,
|
statusId: statusService.status.displayStatus.id,
|
||||||
identityContext: identityContext)))
|
identityContext: identityContext)))
|
||||||
.setFailureType(to: Error.self)
|
.setFailureType(to: Error.self)
|
||||||
.eraseToAnyPublisher())
|
.eraseToAnyPublisher())
|
||||||
|
|
|
@ -1,99 +0,0 @@
|
||||||
// Copyright © 2020 Metabolist. All rights reserved.
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
import ViewModels
|
|
||||||
|
|
||||||
struct ReportView: View {
|
|
||||||
@StateObject var viewModel: ReportViewModel
|
|
||||||
|
|
||||||
@Environment(\.presentationMode) private var presentationMode
|
|
||||||
fileprivate var dismissHostingController: (() -> Void)?
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
Form {
|
|
||||||
if let statusViewModel = viewModel.statusViewModel {
|
|
||||||
Section {
|
|
||||||
ReportStatusView(viewModel: statusViewModel)
|
|
||||||
.frame(height: Self.statusHeight)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Section {
|
|
||||||
Text("report.hint")
|
|
||||||
}
|
|
||||||
Section(header: Text("report.additional-comments")) {
|
|
||||||
TextEditor(text: $viewModel.elements.comment)
|
|
||||||
.accessibility(label: Text("report.additional-comments"))
|
|
||||||
}
|
|
||||||
if !viewModel.isLocalAccount {
|
|
||||||
Section {
|
|
||||||
VStack(alignment: .leading) {
|
|
||||||
Text("report.forward.hint")
|
|
||||||
Toggle("report.forward-\(viewModel.accountHost)", isOn: $viewModel.elements.forward)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Section {
|
|
||||||
if viewModel.loading {
|
|
||||||
ProgressView()
|
|
||||||
} else {
|
|
||||||
Button("report.target-\(viewModel.accountName)") {
|
|
||||||
viewModel.report()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.alertItem($viewModel.alertItem)
|
|
||||||
.onReceive(viewModel.events) {
|
|
||||||
switch $0 {
|
|
||||||
case .reported:
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.navigationTitle("report.target-\(viewModel.accountName)")
|
|
||||||
.toolbar {
|
|
||||||
ToolbarItem(placement: .cancellationAction) {
|
|
||||||
Button("cancel") {
|
|
||||||
dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.navigationBarTitleDisplayMode(.inline)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension ReportView {
|
|
||||||
static let statusHeight: CGFloat = 100
|
|
||||||
|
|
||||||
func dismiss() {
|
|
||||||
if let dismissHostingController = dismissHostingController {
|
|
||||||
dismissHostingController()
|
|
||||||
} else {
|
|
||||||
presentationMode.wrappedValue.dismiss()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class ReportViewController: UIHostingController<ReportView> {
|
|
||||||
init(viewModel: ReportViewModel) {
|
|
||||||
super.init(rootView: ReportView(viewModel: viewModel))
|
|
||||||
|
|
||||||
rootView.dismissHostingController = { [weak self] in self?.dismiss(animated: true) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(*, unavailable)
|
|
||||||
@objc required dynamic init?(coder aDecoder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DEBUG
|
|
||||||
import PreviewViewModels
|
|
||||||
|
|
||||||
struct ReportView_Previews: PreviewProvider {
|
|
||||||
static var previews: some View {
|
|
||||||
NavigationView {
|
|
||||||
ReportView(viewModel: .preview)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,28 +0,0 @@
|
||||||
// Copyright © 2020 Metabolist. All rights reserved.
|
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
import ViewModels
|
|
||||||
|
|
||||||
struct ReportStatusView: UIViewRepresentable {
|
|
||||||
private let configuration: StatusContentConfiguration
|
|
||||||
|
|
||||||
init(viewModel: StatusViewModel) {
|
|
||||||
configuration = StatusContentConfiguration(viewModel: viewModel)
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeUIView(context: Context) -> StatusView {
|
|
||||||
let view = StatusView(configuration: configuration)
|
|
||||||
|
|
||||||
view.alpha = 0.5
|
|
||||||
view.buttonsStackView.isHidden = true
|
|
||||||
view.translatesAutoresizingMaskIntoConstraints = false
|
|
||||||
view.isUserInteractionEnabled = false
|
|
||||||
view.accessibilityLabel = view.accessibilityAttributedLabel?.string
|
|
||||||
|
|
||||||
return view
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateUIView(_ uiView: StatusView, context: Context) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,6 +29,7 @@ final class StatusView: UIView {
|
||||||
let shareButton = UIButton()
|
let shareButton = UIButton()
|
||||||
let menuButton = UIButton()
|
let menuButton = UIButton()
|
||||||
let buttonsStackView = UIStackView()
|
let buttonsStackView = UIStackView()
|
||||||
|
let reportSelectionSwitch = UISwitch()
|
||||||
|
|
||||||
private let containerStackView = UIStackView()
|
private let containerStackView = UIStackView()
|
||||||
private let sideStackView = UIStackView()
|
private let sideStackView = UIStackView()
|
||||||
|
@ -64,7 +65,7 @@ final class StatusView: UIView {
|
||||||
}
|
}
|
||||||
|
|
||||||
override func accessibilityActivate() -> Bool {
|
override func accessibilityActivate() -> Bool {
|
||||||
if !statusConfiguration.viewModel.shouldShowContent {
|
if reportSelectionSwitch.isHidden, !statusConfiguration.viewModel.shouldShowContent {
|
||||||
statusConfiguration.viewModel.toggleShowContent()
|
statusConfiguration.viewModel.toggleShowContent()
|
||||||
accessibilityAttributedLabel = accessibilityAttributedLabel(forceShowContent: true)
|
accessibilityAttributedLabel = accessibilityAttributedLabel(forceShowContent: true)
|
||||||
|
|
||||||
|
@ -103,6 +104,10 @@ extension StatusView {
|
||||||
|
|
||||||
return height
|
return height
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func refreshAccessibilityLabel() {
|
||||||
|
accessibilityAttributedLabel = accessibilityAttributedLabel(forceShowContent: false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension StatusView: UIContentView {
|
extension StatusView: UIContentView {
|
||||||
|
@ -377,6 +382,11 @@ private extension StatusView {
|
||||||
view.widthAnchor.constraint(equalToConstant: .hairline).isActive = true
|
view.widthAnchor.constraint(equalToConstant: .hairline).isActive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
containerStackView.addArrangedSubview(reportSelectionSwitch)
|
||||||
|
reportSelectionSwitch.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||||
|
reportSelectionSwitch.setContentHuggingPriority(.required, for: .horizontal)
|
||||||
|
reportSelectionSwitch.isHidden = true
|
||||||
|
|
||||||
NSLayoutConstraint.activate([
|
NSLayoutConstraint.activate([
|
||||||
containerStackView.topAnchor.constraint(equalTo: readableContentGuide.topAnchor),
|
containerStackView.topAnchor.constraint(equalTo: readableContentGuide.topAnchor),
|
||||||
containerStackView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor),
|
containerStackView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor),
|
||||||
|
@ -583,6 +593,8 @@ private extension StatusView {
|
||||||
|
|
||||||
menuButton.isEnabled = isAuthenticated
|
menuButton.isEnabled = isAuthenticated
|
||||||
|
|
||||||
|
reportSelectionSwitch.isOn = viewModel.selectedForReport
|
||||||
|
|
||||||
isAccessibilityElement = !viewModel.configuration.isContextParent
|
isAccessibilityElement = !viewModel.configuration.isContextParent
|
||||||
|
|
||||||
accessibilityAttributedLabel = accessibilityAttributedLabel(forceShowContent: false)
|
accessibilityAttributedLabel = accessibilityAttributedLabel(forceShowContent: false)
|
||||||
|
@ -721,6 +733,10 @@ private extension StatusView {
|
||||||
func accessibilityAttributedLabel(forceShowContent: Bool) -> NSAttributedString {
|
func accessibilityAttributedLabel(forceShowContent: Bool) -> NSAttributedString {
|
||||||
let accessibilityAttributedLabel = NSMutableAttributedString(string: "")
|
let accessibilityAttributedLabel = NSMutableAttributedString(string: "")
|
||||||
|
|
||||||
|
if !reportSelectionSwitch.isHidden, reportSelectionSwitch.isOn {
|
||||||
|
accessibilityAttributedLabel.appendWithSeparator(NSLocalizedString("selected", comment: ""))
|
||||||
|
}
|
||||||
|
|
||||||
if !infoLabel.isHidden, let infoText = infoLabel.attributedText {
|
if !infoLabel.isHidden, let infoText = infoLabel.attributedText {
|
||||||
accessibilityAttributedLabel.appendWithSeparator(infoText)
|
accessibilityAttributedLabel.appendWithSeparator(infoText)
|
||||||
}
|
}
|
||||||
|
@ -888,7 +904,7 @@ private extension StatusView {
|
||||||
|
|
||||||
// swiftlint:disable:next function_body_length cyclomatic_complexity
|
// swiftlint:disable:next function_body_length cyclomatic_complexity
|
||||||
func accessibilityCustomActions(viewModel: StatusViewModel) -> [UIAccessibilityCustomAction] {
|
func accessibilityCustomActions(viewModel: StatusViewModel) -> [UIAccessibilityCustomAction] {
|
||||||
guard !viewModel.configuration.isContextParent else {
|
guard !viewModel.configuration.isContextParent, reportSelectionSwitch.isHidden else {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
113
Views/UIKit/ReportHeaderView.swift
Normal file
113
Views/UIKit/ReportHeaderView.swift
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
// Copyright © 2021 Metabolist. All rights reserved.
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import ViewModels
|
||||||
|
|
||||||
|
final class ReportHeaderView: UIView {
|
||||||
|
private let viewModel: ReportViewModel
|
||||||
|
private let textView = UITextView()
|
||||||
|
|
||||||
|
init(viewModel: ReportViewModel) {
|
||||||
|
self.viewModel = viewModel
|
||||||
|
|
||||||
|
super.init(frame: .zero)
|
||||||
|
|
||||||
|
initialSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
required init?(coder: NSCoder) {
|
||||||
|
fatalError("init(coder:) has not been implemented")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension ReportHeaderView: UITextViewDelegate {
|
||||||
|
func textViewDidChange(_ textView: UITextView) {
|
||||||
|
viewModel.elements.comment = textView.text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension ReportHeaderView {
|
||||||
|
// swiftlint:disable:next function_body_length
|
||||||
|
func initialSetup() {
|
||||||
|
let stackView = UIStackView()
|
||||||
|
|
||||||
|
addSubview(stackView)
|
||||||
|
stackView.translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
stackView.axis = .vertical
|
||||||
|
stackView.spacing = .defaultSpacing
|
||||||
|
|
||||||
|
let hintLabel = UILabel()
|
||||||
|
|
||||||
|
stackView.addArrangedSubview(hintLabel)
|
||||||
|
hintLabel.adjustsFontForContentSizeCategory = true
|
||||||
|
hintLabel.font = .preferredFont(forTextStyle: .subheadline)
|
||||||
|
hintLabel.text = NSLocalizedString("report.hint", comment: "")
|
||||||
|
hintLabel.numberOfLines = 0
|
||||||
|
|
||||||
|
stackView.addArrangedSubview(textView)
|
||||||
|
textView.adjustsFontForContentSizeCategory = true
|
||||||
|
textView.font = .preferredFont(forTextStyle: .body)
|
||||||
|
textView.layer.borderWidth = .hairline
|
||||||
|
textView.layer.borderColor = UIColor.separator.cgColor
|
||||||
|
textView.layer.cornerRadius = .defaultCornerRadius
|
||||||
|
textView.delegate = self
|
||||||
|
textView.accessibilityLabel = NSLocalizedString("report.additional-comments", comment: "")
|
||||||
|
|
||||||
|
if !viewModel.isLocalAccount {
|
||||||
|
let forwardHintLabel = UILabel()
|
||||||
|
|
||||||
|
stackView.addArrangedSubview(forwardHintLabel)
|
||||||
|
forwardHintLabel.adjustsFontForContentSizeCategory = true
|
||||||
|
forwardHintLabel.font = .preferredFont(forTextStyle: .subheadline)
|
||||||
|
forwardHintLabel.text = NSLocalizedString("report.forward.hint", comment: "")
|
||||||
|
forwardHintLabel.numberOfLines = 0
|
||||||
|
|
||||||
|
let switchStackView = UIStackView()
|
||||||
|
|
||||||
|
stackView.addArrangedSubview(switchStackView)
|
||||||
|
switchStackView.spacing = .defaultSpacing
|
||||||
|
|
||||||
|
let switchLabel = UILabel()
|
||||||
|
|
||||||
|
switchStackView.addArrangedSubview(switchLabel)
|
||||||
|
switchLabel.adjustsFontForContentSizeCategory = true
|
||||||
|
switchLabel.font = .preferredFont(forTextStyle: .headline)
|
||||||
|
switchLabel.text = String.localizedStringWithFormat(
|
||||||
|
NSLocalizedString("report.forward-%@", comment: ""),
|
||||||
|
viewModel.accountHost)
|
||||||
|
switchLabel.textAlignment = .right
|
||||||
|
switchLabel.numberOfLines = 0
|
||||||
|
|
||||||
|
let forwardSwitch = UISwitch()
|
||||||
|
|
||||||
|
switchStackView.addArrangedSubview(forwardSwitch)
|
||||||
|
forwardSwitch.setContentHuggingPriority(.required, for: .horizontal)
|
||||||
|
forwardSwitch.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||||
|
forwardSwitch.addAction(
|
||||||
|
UIAction { [weak self] _ in self?.viewModel.elements.forward = forwardSwitch.isOn },
|
||||||
|
for: .valueChanged)
|
||||||
|
}
|
||||||
|
|
||||||
|
let selectAdditionalHintLabel = UILabel()
|
||||||
|
|
||||||
|
stackView.addArrangedSubview(selectAdditionalHintLabel)
|
||||||
|
selectAdditionalHintLabel.adjustsFontForContentSizeCategory = true
|
||||||
|
selectAdditionalHintLabel.font = .preferredFont(forTextStyle: .subheadline)
|
||||||
|
selectAdditionalHintLabel.numberOfLines = 0
|
||||||
|
|
||||||
|
switch viewModel.identityContext.appPreferences.statusWord {
|
||||||
|
case .toot:
|
||||||
|
selectAdditionalHintLabel.text = NSLocalizedString("report.select-additional.hint.toot", comment: "")
|
||||||
|
case .post:
|
||||||
|
selectAdditionalHintLabel.text = NSLocalizedString("report.select-additional.hint.post", comment: "")
|
||||||
|
}
|
||||||
|
|
||||||
|
NSLayoutConstraint.activate([
|
||||||
|
stackView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor),
|
||||||
|
stackView.topAnchor.constraint(equalTo: readableContentGuide.topAnchor),
|
||||||
|
stackView.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor),
|
||||||
|
stackView.bottomAnchor.constraint(equalTo: readableContentGuide.bottomAnchor),
|
||||||
|
textView.heightAnchor.constraint(equalToConstant: .minimumButtonDimension * 2)
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue