diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index 62b32d90..0819c72d 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -276,14 +276,12 @@ D6C82B5725C5F3F20017F1E6 /* ExpandThreadTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6C82B5525C5F3F20017F1E6 /* ExpandThreadTableViewCell.xib */; }; D6C94D872139E62700CB5196 /* LargeImageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C94D862139E62700CB5196 /* LargeImageViewController.swift */; }; D6C94D892139E6EC00CB5196 /* AttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C94D882139E6EC00CB5196 /* AttachmentView.swift */; }; - D6C99FC724FACFAB005C74D3 /* ActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C99FC624FACFAB005C74D3 /* ActivityIndicatorView.swift */; }; D6C99FCB24FADC91005C74D3 /* MainComposeTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C99FCA24FADC91005C74D3 /* MainComposeTextView.swift */; }; D6CA6A92249FAD8900AD45C1 /* AudioSessionHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CA6A91249FAD8900AD45C1 /* AudioSessionHelper.swift */; }; D6CA6A94249FADE700AD45C1 /* GalleryPlayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CA6A93249FADE700AD45C1 /* GalleryPlayerViewController.swift */; }; D6D3F4C424FDB6B700EC4A6A /* View+ConditionalModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D3F4C324FDB6B700EC4A6A /* View+ConditionalModifier.swift */; }; D6D3FDE024F41B8400FF50A5 /* ComposeContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D3FDDF24F41B8400FF50A5 /* ComposeContainerView.swift */; }; D6D3FDE224F46A8D00FF50A5 /* ComposeUIState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D3FDE124F46A8D00FF50A5 /* ComposeUIState.swift */; }; - D6D4CC91250D2C3100FCCF8D /* UIAccessibility.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4CC90250D2C3100FCCF8D /* UIAccessibility.swift */; }; D6D4CC94250DB86A00FCCF8D /* ComposeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4CC93250DB86A00FCCF8D /* ComposeTests.swift */; }; D6D4DDD0212518A000E1C4BB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */; }; D6D4DDD7212518A200E1C4BB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD6212518A200E1C4BB /* Assets.xcassets */; }; @@ -297,7 +295,6 @@ D6DFC6A0242C4CCC00ACC392 /* WeakArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DFC69F242C4CCC00ACC392 /* WeakArray.swift */; }; D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E0DC8D216EDF1E00369478 /* Previewing.swift */; }; D6E4267725327FB400C02E1C /* ComposeAutocompleteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E4267625327FB400C02E1C /* ComposeAutocompleteView.swift */; }; - D6E426812532814100C02E1C /* MaybeLazyStack.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E426802532814100C02E1C /* MaybeLazyStack.swift */; }; D6E4269D2532A3E100C02E1C /* FuzzyMatcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E4269C2532A3E100C02E1C /* FuzzyMatcher.swift */; }; D6E426AD25334DA500C02E1C /* FuzzyMatcherTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E426AC25334DA500C02E1C /* FuzzyMatcherTests.swift */; }; D6E426B325337C7000C02E1C /* CustomEmojiImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E426B225337C7000C02E1C /* CustomEmojiImageView.swift */; }; @@ -640,14 +637,12 @@ D6C82B5525C5F3F20017F1E6 /* ExpandThreadTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ExpandThreadTableViewCell.xib; sourceTree = ""; }; D6C94D862139E62700CB5196 /* LargeImageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageViewController.swift; sourceTree = ""; }; D6C94D882139E6EC00CB5196 /* AttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentView.swift; sourceTree = ""; }; - D6C99FC624FACFAB005C74D3 /* ActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorView.swift; sourceTree = ""; }; D6C99FCA24FADC91005C74D3 /* MainComposeTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainComposeTextView.swift; sourceTree = ""; }; D6CA6A91249FAD8900AD45C1 /* AudioSessionHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioSessionHelper.swift; sourceTree = ""; }; D6CA6A93249FADE700AD45C1 /* GalleryPlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GalleryPlayerViewController.swift; sourceTree = ""; }; D6D3F4C324FDB6B700EC4A6A /* View+ConditionalModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+ConditionalModifier.swift"; sourceTree = ""; }; D6D3FDDF24F41B8400FF50A5 /* ComposeContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeContainerView.swift; sourceTree = ""; }; D6D3FDE124F46A8D00FF50A5 /* ComposeUIState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeUIState.swift; sourceTree = ""; }; - D6D4CC90250D2C3100FCCF8D /* UIAccessibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAccessibility.swift; sourceTree = ""; }; D6D4CC93250DB86A00FCCF8D /* ComposeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeTests.swift; sourceTree = ""; }; D6D4DDCC212518A000E1C4BB /* Tusker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Tusker.app; sourceTree = BUILT_PRODUCTS_DIR; }; D6D4DDCF212518A000E1C4BB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; @@ -667,7 +662,6 @@ D6DFC69F242C4CCC00ACC392 /* WeakArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakArray.swift; sourceTree = ""; }; D6E0DC8D216EDF1E00369478 /* Previewing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Previewing.swift; sourceTree = ""; }; D6E4267625327FB400C02E1C /* ComposeAutocompleteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeAutocompleteView.swift; sourceTree = ""; }; - D6E426802532814100C02E1C /* MaybeLazyStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MaybeLazyStack.swift; sourceTree = ""; }; D6E4269C2532A3E100C02E1C /* FuzzyMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FuzzyMatcher.swift; sourceTree = ""; }; D6E426AC25334DA500C02E1C /* FuzzyMatcherTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FuzzyMatcherTests.swift; sourceTree = ""; }; D6E426B225337C7000C02E1C /* CustomEmojiImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiImageView.swift; sourceTree = ""; }; @@ -1207,7 +1201,6 @@ D67895BB24671E6D00D4CD9E /* PKDrawing+Render.swift */, D690797224A4EF9700023A34 /* UIBezierPath+Helpers.swift */, D6D3F4C324FDB6B700EC4A6A /* View+ConditionalModifier.swift */, - D6D4CC90250D2C3100FCCF8D /* UIAccessibility.swift */, D6620ACD2511A0ED00312CA0 /* StatusStateResolver.swift */, D69693F32585941A00F4E116 /* UIWindowSceneDelegate+Close.swift */, ); @@ -1370,10 +1363,8 @@ D627943123A5466600D38C68 /* SelectableTableViewCell.swift */, D627944623A6AC9300D38C68 /* BasicTableViewCell.xib */, D6403CC124A6B72D00E81C55 /* VisualEffectImageButton.swift */, - D6C99FC624FACFAB005C74D3 /* ActivityIndicatorView.swift */, D686BBE224FBF8110068E6AA /* WrappedProgressView.swift */, D6B4A4FE2506B81A000C81C1 /* AccountDisplayNameLabel.swift */, - D6E426802532814100C02E1C /* MaybeLazyStack.swift */, D6E426B225337C7000C02E1C /* CustomEmojiImageView.swift */, D6EAE0DA2550CC8A002DB0AC /* FocusableTextField.swift */, D67C57A721E2649B00C3118B /* Account Detail */, @@ -1910,7 +1901,6 @@ D6C7D27D22B6EBF800071952 /* AttachmentsContainerView.swift in Sources */, D620483823D38190008A63EF /* StatusContentTextView.swift in Sources */, D6D3FDE224F46A8D00FF50A5 /* ComposeUIState.swift in Sources */, - D6C99FC724FACFAB005C74D3 /* ActivityIndicatorView.swift in Sources */, D6B22A0F2560D52D004D82EF /* TabbedPageViewController.swift in Sources */, D6F953F021251A2900CF0F2B /* MastodonController.swift in Sources */, 0411610022B442870030A9B7 /* LoadingLargeImageViewController.swift in Sources */, @@ -1945,7 +1935,6 @@ D62D2424217ABF3F005076CC /* NSUserActivity+Extensions.swift in Sources */, D6B30E09254BAF63009CAEE5 /* ImageGrayscalifier.swift in Sources */, D6A6C10F25B62D2400298D0F /* DiskCache.swift in Sources */, - D6E426812532814100C02E1C /* MaybeLazyStack.swift in Sources */, D6B81F3C2560365300F6E31D /* RefreshableViewController.swift in Sources */, D646C958213B367000269FB5 /* LargeImageShrinkAnimationController.swift in Sources */, D6A3BC852321F6C100FD64D5 /* AccountListTableViewController.swift in Sources */, @@ -2007,7 +1996,6 @@ D6B053AE23BD322B00A066FA /* AssetPickerSheetContainerViewController.swift in Sources */, D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */, D6C94D872139E62700CB5196 /* LargeImageViewController.swift in Sources */, - D6D4CC91250D2C3100FCCF8D /* UIAccessibility.swift in Sources */, D627943E23A564D400D38C68 /* ExploreViewController.swift in Sources */, D6B053AB23BD2F1400A066FA /* AssetCollectionViewCell.swift in Sources */, D622757A24EE21D900B82A16 /* ComposeAttachmentRow.swift in Sources */, diff --git a/Tusker/Controllers/MenuController.swift b/Tusker/Controllers/MenuController.swift index 4b61b701..0c86608e 100644 --- a/Tusker/Controllers/MenuController.swift +++ b/Tusker/Controllers/MenuController.swift @@ -11,20 +11,13 @@ import UIKit struct MenuController { static let composeCommand: UIKeyCommand = { - let selector: Selector - if #available(iOS 14.0, *) { - selector = #selector(MainSplitViewController.presentCompose) - } else { - selector = #selector(MainTabBarViewController.presentCompose) - } - return UIKeyCommand(title: "Compose", action: selector, input: "n", modifierFlags: .command) + return UIKeyCommand(title: "Compose", action: #selector(MainSplitViewController.presentCompose), input: "n", modifierFlags: .command) }() static func refreshCommand(discoverabilityTitle: String?) -> UIKeyCommand { return UIKeyCommand(title: "Refresh", action: #selector(RefreshableViewController.refresh), input: "r", modifierFlags: .command, discoverabilityTitle: discoverabilityTitle) } - @available(iOS 14.0, *) static func sidebarCommand(item: MainSidebarViewController.Item, command: String) -> UIKeyCommand { let data: Any if case let .tab(tab) = item { @@ -46,7 +39,6 @@ struct MenuController { ) } - @available(iOS 14.0, *) static let sidebarItemKeyCommands: [UIKeyCommand] = [ sidebarCommand(item: .tab(.timelines), command: "1"), sidebarCommand(item: .tab(.notifications), command: "2"), @@ -92,25 +84,18 @@ struct MenuController { } private static func buildSidebarShortcuts() -> UIMenu { - let children: [UIMenuElement] - if #available(iOS 14.0, *) { - children = sidebarItemKeyCommands - } else { - children = [] - } return UIMenu( title: "", image: nil, identifier: nil, options: .displayInline, - children: children + children: sidebarItemKeyCommands ) } } extension MenuController { - @available(iOS 14.0, *) class SidebarItem: NSObject, NSCopying { let item: MainSidebarViewController.Item diff --git a/Tusker/Extensions/UIAccessibility.swift b/Tusker/Extensions/UIAccessibility.swift deleted file mode 100644 index a612f505..00000000 --- a/Tusker/Extensions/UIAccessibility.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// UIAccessibility.swift -// Tusker -// -// Created by Shadowfacts on 9/12/20. -// Copyright © 2020 Shadowfacts. All rights reserved. -// - -import UIKit - -extension UIAccessibility { - - static var prefersCrossFadeTransitionsBackwardsCompat: Bool { - if #available(iOS 14.0, *) { - return prefersCrossFadeTransitions - } else { - return isReduceMotionEnabled - } - } - -} diff --git a/Tusker/MainSceneDelegate.swift b/Tusker/MainSceneDelegate.swift index d03ee87c..cf693152 100644 --- a/Tusker/MainSceneDelegate.swift +++ b/Tusker/MainSceneDelegate.swift @@ -176,11 +176,7 @@ class MainSceneDelegate: UIResponder, UIWindowSceneDelegate { mastodonController.getOwnAccount() mastodonController.getOwnInstance() - if #available(iOS 14.0, *) { - return MainSplitViewController(mastodonController: mastodonController) - } else { - return MainTabBarViewController(mastodonController: mastodonController) - } + return MainSplitViewController(mastodonController: mastodonController) } func createOnboardingUI() -> UIViewController { diff --git a/Tusker/Screens/Compose/ComposeAttachmentRow.swift b/Tusker/Screens/Compose/ComposeAttachmentRow.swift index 759cd2ad..15929762 100644 --- a/Tusker/Screens/Compose/ComposeAttachmentRow.swift +++ b/Tusker/Screens/Compose/ComposeAttachmentRow.swift @@ -34,25 +34,11 @@ struct ComposeAttachmentRow: View { .contextMenu { if case .drawing(_) = attachment.data { Button(action: self.editDrawing) { - if #available(iOS 14.0, *) { - Label("Edit Drawing", systemImage: "hand.draw") - } else { - HStack { - Text("Edit Drawing") - Image(systemName: "hand.draw") - } - } + Label("Edit Drawing", systemImage: "hand.draw") } } else if attachment.data.type == .image { Button(action: self.recognizeText) { - if #available(iOS 14.0, *) { - Label("Recognize Text", systemImage: "doc.text.viewfinder") - } else { - HStack { - Text("Recognize Text") - Image(systemName: "doc.text.viewfinder") - } - } + Label("Recognize Text", systemImage: "doc.text.viewfinder") } } } @@ -65,11 +51,7 @@ struct ComposeAttachmentRow: View { .fontSize(17) case .recognizingText: - if #available(iOS 14.0, *) { - ProgressView() - } else { - ActivityIndicatorView() - } + ProgressView() } diff --git a/Tusker/Screens/Compose/ComposeAttachmentsList.swift b/Tusker/Screens/Compose/ComposeAttachmentsList.swift index c4028bf2..7c015589 100644 --- a/Tusker/Screens/Compose/ComposeAttachmentsList.swift +++ b/Tusker/Screens/Compose/ComposeAttachmentsList.swift @@ -45,14 +45,7 @@ struct ComposeAttachmentsList: View { } Button(action: self.addAttachment) { - if #available(iOS 14.0, *) { - Label("Add photo or video", systemImage: addButtonImageName) - } else { - HStack { - Image(systemName: addButtonImageName) - Text("Add photo or video") - } - } + Label("Add photo or video", systemImage: addButtonImageName) } .disabled(!canAddAttachment) .foregroundColor(.blue) @@ -61,14 +54,7 @@ struct ComposeAttachmentsList: View { .listRowInsets(EdgeInsets(top: cellPadding / 2, leading: cellPadding / 2, bottom: cellPadding / 2, trailing: cellPadding / 2)) Button(action: self.createDrawing) { - if #available(iOS 14.0, *) { - Label("Draw something", systemImage: "hand.draw") - } else { - HStack(alignment: .lastTextBaseline) { - Image(systemName: "hand.draw") - Text("Draw something") - } - } + Label("Draw something", systemImage: "hand.draw") } .disabled(!canAddAttachment) .foregroundColor(.blue) diff --git a/Tusker/Screens/Compose/ComposeAutocompleteView.swift b/Tusker/Screens/Compose/ComposeAutocompleteView.swift index dcd2a397..5fb018f3 100644 --- a/Tusker/Screens/Compose/ComposeAutocompleteView.swift +++ b/Tusker/Screens/Compose/ComposeAutocompleteView.swift @@ -44,19 +44,6 @@ struct ComposeAutocompleteView: View { } } -fileprivate extension View { - @ViewBuilder - func iOS13OnlyPadding() -> some View { - // on iOS 13, if the scroll view content's height changes after the view is added to the hierarchy, - // it doesn't appear on screen until interactive keyboard dismissal is started and then cancelled :S - if #available(iOS 14.0, *) { - self - } else { - self.frame(height: 46) - } - } -} - struct ComposeAutocompleteMentionsView: View { @EnvironmentObject private var mastodonController: MastodonController @EnvironmentObject private var uiState: ComposeUIState @@ -104,7 +91,6 @@ struct ComposeAutocompleteMentionsView: View { Spacer() } .padding(.horizontal, 8) - .iOS13OnlyPadding() } .onReceive(uiState.$autocompleteState.debounce(for: .milliseconds(250), scheduler: DispatchQueue.main), perform: queryChanged) .onDisappear { @@ -333,7 +319,6 @@ struct ComposeAutocompleteHashtagsView: View { Spacer() } .padding(.horizontal, 8) - .iOS13OnlyPadding() } .onReceive(uiState.$autocompleteState.debounce(for: .milliseconds(250), scheduler: DispatchQueue.main), perform: queryChanged) .onDisappear { diff --git a/Tusker/Screens/Compose/ComposeDrawingViewController.swift b/Tusker/Screens/Compose/ComposeDrawingViewController.swift index 14945e62..213cde6f 100644 --- a/Tusker/Screens/Compose/ComposeDrawingViewController.swift +++ b/Tusker/Screens/Compose/ComposeDrawingViewController.swift @@ -58,11 +58,7 @@ class ComposeDrawingViewController: UIViewController { canvasView.drawing = initialDrawing } canvasView.delegate = self - if #available(iOS 14.0, *) { - canvasView.drawingPolicy = .anyInput - } else { - canvasView.allowsFingerDrawing = true - } + canvasView.drawingPolicy = .anyInput canvasView.minimumZoomScale = 0.5 canvasView.maximumZoomScale = 2 canvasView.backgroundColor = .systemBackground diff --git a/Tusker/Screens/Compose/ComposeHostingController.swift b/Tusker/Screens/Compose/ComposeHostingController.swift index 7d97053e..63676e40 100644 --- a/Tusker/Screens/Compose/ComposeHostingController.swift +++ b/Tusker/Screens/Compose/ComposeHostingController.swift @@ -27,7 +27,6 @@ class ComposeHostingController: UIHostingController { private var cancellables = [AnyCancellable]() - private var keyboardHeight: CGFloat = 0 private var toolbarHeight: CGFloat = 44 private var mainToolbar: UIToolbar! @@ -115,13 +114,7 @@ class ComposeHostingController: UIHostingController { toolbar.translatesAutoresizingMaskIntoConstraints = false toolbar.isAccessibilityElement = true - let visibilityAction: Selector? - if #available(iOS 14.0, *) { - visibilityAction = nil - } else { - visibilityAction = #selector(visibilityButtonPressed(_:)) - } - let visibilityItem = UIBarButtonItem(image: UIImage(systemName: draft.visibility.imageName), style: .plain, target: self, action: visibilityAction) + let visibilityItem = UIBarButtonItem(image: UIImage(systemName: draft.visibility.imageName), style: .plain, target: nil, action: nil) visibilityBarButtonItems.append(visibilityItem) visibilityChanged(draft.visibility) @@ -135,7 +128,7 @@ class ComposeHostingController: UIHostingController { } private func updateAdditionalSafeAreaInsets() { - additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: toolbarHeight + keyboardHeight, right: 0) + additionalSafeAreaInsets = UIEdgeInsets(top: 0, left: 0, bottom: toolbarHeight, right: 0) } @objc private func keyboardWillShow(_ notification: Foundation.Notification) { @@ -147,19 +140,6 @@ class ComposeHostingController: UIHostingController { accessoryView.alpha = 1 accessoryView.isHidden = false - - // on iOS 14, SwiftUI safe area automatically includes the keyboard - if #available(iOS 14.0, *) { - } else { - let userInfo = notification.userInfo! - let frame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! CGRect - // temporarily reset add'l safe area insets so we can access the default inset - additionalSafeAreaInsets = .zero - // there are a few extra points that come from somewhere, it seems to be four - // and without it, the autocomplete suggestions are cut off :S - keyboardHeight = frame.height - view.safeAreaInsets.bottom - accessoryView.frame.height + 4 - updateAdditionalSafeAreaInsets() - } } @objc private func keyboardWillHide(_ notification: Foundation.Notification) { @@ -192,13 +172,6 @@ class ComposeHostingController: UIHostingController { } completion: { (finished) in accessoryView.alpha = 1 } - - // on iOS 14, SwiftUI safe area automatically includes the keyboard - if #available(iOS 14.0, *) { - } else { - keyboardHeight = 0 - updateAdditionalSafeAreaInsets() - } } @objc private func keyboardDidHide(_ notification: Foundation.Notification) { @@ -214,15 +187,13 @@ class ComposeHostingController: UIHostingController { item.image = UIImage(systemName: newVisibility.imageName) item.image!.accessibilityLabel = String(format: NSLocalizedString("Visibility: %@", comment: "compose visiblity accessibility label"), draft.visibility.displayName) item.accessibilityLabel = String(format: NSLocalizedString("Visibility: %@", comment: "compose visiblity accessibility label"), draft.visibility.displayName) - if #available(iOS 14.0, *) { - let elements = Status.Visibility.allCases.map { (visibility) -> UIMenuElement in - let state = visibility == newVisibility ? UIMenuElement.State.on : .off - return UIAction(title: visibility.displayName, image: UIImage(systemName: visibility.unfilledImageName), identifier: nil, discoverabilityTitle: nil, attributes: [], state: state) { (_) in - self.draft.visibility = visibility - } + let elements = Status.Visibility.allCases.map { (visibility) -> UIMenuElement in + let state = visibility == newVisibility ? UIMenuElement.State.on : .off + return UIAction(title: visibility.displayName, image: UIImage(systemName: visibility.unfilledImageName), identifier: nil, discoverabilityTitle: nil, attributes: [], state: state) { (_) in + self.draft.visibility = visibility } - item.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: elements) } + item.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: elements) } } @@ -255,18 +226,6 @@ class ComposeHostingController: UIHostingController { draft.contentWarningEnabled = !draft.contentWarningEnabled } - @objc func visibilityButtonPressed(_ sender: UIBarButtonItem) { -// if #available(iOS 14.0, *) { -// } else { - let alertController = UIAlertController(currentVisibility: draft.visibility) { (visibility) in - guard let visibility = visibility else { return } - self.draft.visibility = visibility - } - alertController.popoverPresentationController?.barButtonItem = sender - present(alertController, animated: true) -// } - } - @objc func draftsButtonPresed() { let draftsVC = DraftsTableViewController(account: mastodonController.accountInfo!, exclude: draft) draftsVC.delegate = self diff --git a/Tusker/Screens/Compose/ComposeView.swift b/Tusker/Screens/Compose/ComposeView.swift index 4fbdf3cf..4add71e5 100644 --- a/Tusker/Screens/Compose/ComposeView.swift +++ b/Tusker/Screens/Compose/ComposeView.swift @@ -44,14 +44,9 @@ struct ComposeView: View { } var body: some View { - // the pre-iOS 14 API does not result in the correct pointer interactions for nav bar buttons, see FB8595468 - if #available(iOS 14.0, *) { - mostOfTheBody.toolbar { - ToolbarItem(placement: .cancellationAction) { cancelButton } - ToolbarItem(placement: .confirmationAction) { postButton } - } - } else { - mostOfTheBody.navigationBarItems(leading: cancelButton, trailing: postButton) + mostOfTheBody.toolbar { + ToolbarItem(placement: .cancellationAction) { cancelButton } + ToolbarItem(placement: .confirmationAction) { postButton } } } @@ -82,24 +77,14 @@ struct ComposeView: View { @ViewBuilder var autocompleteSuggestions: some View { - // on iOS 13, the transition causes SwiftUI to hang on the main thread when the view appears, so it's disabled - if #available(iOS 14.0, *) { - VStack(spacing: 0) { - Spacer() - if let state = uiState.autocompleteState { - ComposeAutocompleteView(autocompleteState: state) - } - } - .transition(.move(edge: .bottom)) - .animation(.default) - } else { - VStack(spacing: 0) { - Spacer() - if let state = uiState.autocompleteState { - ComposeAutocompleteView(autocompleteState: state) - } + VStack(spacing: 0) { + Spacer() + if let state = uiState.autocompleteState { + ComposeAutocompleteView(autocompleteState: state) } } + .transition(.move(edge: .bottom)) + .animation(.default) } func mainStack(outerMinY: CGFloat) -> some View { diff --git a/Tusker/Screens/Compose/MainComposeTextView.swift b/Tusker/Screens/Compose/MainComposeTextView.swift index b32784d9..d6750951 100644 --- a/Tusker/Screens/Compose/MainComposeTextView.swift +++ b/Tusker/Screens/Compose/MainComposeTextView.swift @@ -69,13 +69,7 @@ struct MainComposeWrappedTextView: UIViewRepresentable { uiState.autocompleteHandler = context.coordinator - let visibilityAction: Selector? - if #available(iOS 14.0, *) { - visibilityAction = nil - } else { - visibilityAction = #selector(ComposeHostingController.visibilityButtonPressed(_:)) - } - let visibilityButton = UIBarButtonItem(image: UIImage(systemName: visibility.imageName), style: .plain, target: nil, action: visibilityAction) + let visibilityButton = UIBarButtonItem(image: UIImage(systemName: visibility.imageName), style: .plain, target: nil, action: nil) updateVisibilityMenu(visibilityButton) let toolbar = UIToolbar() toolbar.translatesAutoresizingMaskIntoConstraints = false @@ -131,15 +125,13 @@ struct MainComposeWrappedTextView: UIViewRepresentable { } private func updateVisibilityMenu(_ visibilityButton: UIBarButtonItem) { - if #available(iOS 14.0, *) { - let elements = Status.Visibility.allCases.map { (visibility) -> UIMenuElement in - let state = visibility == self.visibility ? UIMenuElement.State.on : .off - return UIAction(title: visibility.displayName, image: UIImage(systemName: visibility.unfilledImageName), identifier: nil, discoverabilityTitle: nil, attributes: [], state: state) { (_) in - self.uiState.draft.visibility = visibility - } + let elements = Status.Visibility.allCases.map { (visibility) -> UIMenuElement in + let state = visibility == self.visibility ? UIMenuElement.State.on : .off + return UIAction(title: visibility.displayName, image: UIImage(systemName: visibility.unfilledImageName), identifier: nil, discoverabilityTitle: nil, attributes: [], state: state) { (_) in + self.uiState.draft.visibility = visibility } - visibilityButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: elements) } + visibilityButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: elements) } func updateUIView(_ uiView: UITextView, context: Context) { diff --git a/Tusker/Screens/Fast Account Switcher/FastAccountSwitcherViewController.swift b/Tusker/Screens/Fast Account Switcher/FastAccountSwitcherViewController.swift index 5bc917c1..70fcaa12 100644 --- a/Tusker/Screens/Fast Account Switcher/FastAccountSwitcherViewController.swift +++ b/Tusker/Screens/Fast Account Switcher/FastAccountSwitcherViewController.swift @@ -54,7 +54,7 @@ class FastAccountSwitcherViewController: UIViewController { view.isHidden = false - if UIAccessibility.prefersCrossFadeTransitionsBackwardsCompat { + if UIAccessibility.prefersCrossFadeTransitions { view.alpha = 0 UIView.animate(withDuration: 0.2, delay: 0, options: [.curveEaseInOut, .allowUserInteraction]) { self.view.alpha = 1 diff --git a/Tusker/Screens/Large Image/Transitions/LargeImageExpandAnimationController.swift b/Tusker/Screens/Large Image/Transitions/LargeImageExpandAnimationController.swift index 6d35fe2b..0e025449 100644 --- a/Tusker/Screens/Large Image/Transitions/LargeImageExpandAnimationController.swift +++ b/Tusker/Screens/Large Image/Transitions/LargeImageExpandAnimationController.swift @@ -38,7 +38,7 @@ extension LargeImageAnimatableViewController { class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTransitioning { func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { - if UIAccessibility.prefersCrossFadeTransitionsBackwardsCompat { + if UIAccessibility.prefersCrossFadeTransitions { return 0.2 } else { return 0.4 @@ -51,7 +51,7 @@ class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTra return } - if UIAccessibility.prefersCrossFadeTransitionsBackwardsCompat { + if UIAccessibility.prefersCrossFadeTransitions { animateCrossFadeTransition(using: transitionContext) return } diff --git a/Tusker/Screens/Large Image/Transitions/LargeImageShrinkAnimationController.swift b/Tusker/Screens/Large Image/Transitions/LargeImageShrinkAnimationController.swift index 456c665c..60612105 100644 --- a/Tusker/Screens/Large Image/Transitions/LargeImageShrinkAnimationController.swift +++ b/Tusker/Screens/Large Image/Transitions/LargeImageShrinkAnimationController.swift @@ -27,7 +27,7 @@ class LargeImageShrinkAnimationController: NSObject, UIViewControllerAnimatedTra return } - if UIAccessibility.prefersCrossFadeTransitionsBackwardsCompat && !transitionContext.isInteractive { + if UIAccessibility.prefersCrossFadeTransitions && !transitionContext.isInteractive { animateCrossFadeTransition(using: transitionContext) return } diff --git a/Tusker/Screens/Main/AccountSwitchingContainerViewController.swift b/Tusker/Screens/Main/AccountSwitchingContainerViewController.swift index 88ecfa40..9dbaf7b2 100644 --- a/Tusker/Screens/Main/AccountSwitchingContainerViewController.swift +++ b/Tusker/Screens/Main/AccountSwitchingContainerViewController.swift @@ -37,7 +37,7 @@ class AccountSwitchingContainerViewController: UIViewController { embedChild(newRoot) if direction != .none { - if UIAccessibility.prefersCrossFadeTransitionsBackwardsCompat { + if UIAccessibility.prefersCrossFadeTransitions { newRoot.view.alpha = 0 UIView.animate(withDuration: 0.4, delay: 0, options: .curveEaseInOut) { diff --git a/Tusker/Screens/Main/MainSidebarViewController.swift b/Tusker/Screens/Main/MainSidebarViewController.swift index c111cdeb..a0ff71ee 100644 --- a/Tusker/Screens/Main/MainSidebarViewController.swift +++ b/Tusker/Screens/Main/MainSidebarViewController.swift @@ -9,13 +9,11 @@ import UIKit import Pachyderm -@available(iOS 14.0, *) protocol MainSidebarViewControllerDelegate: class { func sidebarRequestPresentCompose(_ sidebarViewController: MainSidebarViewController) func sidebar(_ sidebarViewController: MainSidebarViewController, didSelectItem item: MainSidebarViewController.Item) } -@available(iOS 14.0, *) class MainSidebarViewController: UIViewController { private weak var mastodonController: MastodonController! @@ -252,7 +250,6 @@ class MainSidebarViewController: UIViewController { } -@available(iOS 14.0, *) extension MainSidebarViewController { enum Section: Int, Hashable, CaseIterable { case tabs @@ -362,7 +359,6 @@ fileprivate extension MainTabBarViewController.Tab { } } -@available(iOS 14.0, *) extension MainSidebarViewController: UICollectionViewDelegate { func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool { previouslySelectedItem = selectedItem @@ -397,7 +393,6 @@ extension MainSidebarViewController: UICollectionViewDelegate { } } -@available(iOS 14.0, *) extension MainSidebarViewController: UICollectionViewDragDelegate { func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] { guard let item = dataSource.itemIdentifier(for: indexPath), @@ -410,7 +405,6 @@ extension MainSidebarViewController: UICollectionViewDragDelegate { } } -@available(iOS 14.0, *) extension MainSidebarViewController: InstanceTimelineViewControllerDelegate { func didSaveInstance(url: URL) { dismiss(animated: true) { diff --git a/Tusker/Screens/Main/MainSplitViewController.swift b/Tusker/Screens/Main/MainSplitViewController.swift index 105c534c..ae4489f6 100644 --- a/Tusker/Screens/Main/MainSplitViewController.swift +++ b/Tusker/Screens/Main/MainSplitViewController.swift @@ -8,7 +8,6 @@ import UIKit -@available(iOS 14.0, *) class MainSplitViewController: UISplitViewController { weak var mastodonController: MastodonController! @@ -103,7 +102,6 @@ class MainSplitViewController: UISplitViewController { } -@available(iOS 14.0, *) extension MainSplitViewController: UISplitViewControllerDelegate { /// Transfer the navigation stack for a sidebar item to a destination navgiation controller. /// - Parameter dropFirst: Remove the first view controller from the item's navigation stack before transferring. @@ -307,7 +305,6 @@ extension MainSplitViewController: UISplitViewControllerDelegate { } } -@available(iOS 14.0, *) extension MainSplitViewController: MainSidebarViewControllerDelegate { func sidebarRequestPresentCompose(_ sidebarViewController: MainSidebarViewController) { presentCompose() @@ -322,7 +319,6 @@ extension MainSplitViewController: MainSidebarViewControllerDelegate { } } -@available(iOS 14.0, *) fileprivate extension MainSidebarViewController.Item { func createRootViewController(_ mastodonController: MastodonController) -> UIViewController? { switch self { @@ -344,7 +340,6 @@ fileprivate extension MainSidebarViewController.Item { } } -@available(iOS 14.0, *) extension MainSplitViewController: TuskerRootViewController { @objc func presentCompose() { let vc = ComposeHostingController(mastodonController: mastodonController) @@ -381,7 +376,6 @@ extension MainSplitViewController: TuskerRootViewController { } } -@available(iOS 14.0, *) extension MainSplitViewController: BackgroundableViewController { func sceneDidEnterBackground() { if traitCollection.horizontalSizeClass == .compact { diff --git a/Tusker/Screens/Preferences/AdvancedPrefsView.swift b/Tusker/Screens/Preferences/AdvancedPrefsView.swift index 15190e7c..a4a4bab6 100644 --- a/Tusker/Screens/Preferences/AdvancedPrefsView.swift +++ b/Tusker/Screens/Preferences/AdvancedPrefsView.swift @@ -17,7 +17,7 @@ struct AdvancedPrefsView : View { automationSection cachingSection } - .insetOrGroupedListStyle() + .listStyle(InsetGroupedListStyle()) .navigationBarTitle(Text("Advanced")) } diff --git a/Tusker/Screens/Preferences/AppearancePrefsView.swift b/Tusker/Screens/Preferences/AppearancePrefsView.swift index 1d9d3e7d..ef9e4698 100644 --- a/Tusker/Screens/Preferences/AppearancePrefsView.swift +++ b/Tusker/Screens/Preferences/AppearancePrefsView.swift @@ -33,7 +33,7 @@ struct AppearancePrefsView : View { accountsSection postsSection } - .insetOrGroupedListStyle() + .listStyle(InsetGroupedListStyle()) .navigationBarTitle(Text("Appearance")) } diff --git a/Tusker/Screens/Preferences/BehaviorPrefsView.swift b/Tusker/Screens/Preferences/BehaviorPrefsView.swift index 73f9ee95..8657d117 100644 --- a/Tusker/Screens/Preferences/BehaviorPrefsView.swift +++ b/Tusker/Screens/Preferences/BehaviorPrefsView.swift @@ -16,7 +16,7 @@ struct BehaviorPrefsView: View { linksSection contentWarningsSection } - .insetOrGroupedListStyle() + .listStyle(InsetGroupedListStyle()) .navigationBarTitle(Text("Behavior")) } diff --git a/Tusker/Screens/Preferences/ComposingPrefsView.swift b/Tusker/Screens/Preferences/ComposingPrefsView.swift index 3eb20dfb..de875ee4 100644 --- a/Tusker/Screens/Preferences/ComposingPrefsView.swift +++ b/Tusker/Screens/Preferences/ComposingPrefsView.swift @@ -17,7 +17,7 @@ struct ComposingPrefsView: View { composingSection replyingSection } - .insetOrGroupedListStyle() + .listStyle(InsetGroupedListStyle()) .navigationBarTitle("Composing") } diff --git a/Tusker/Screens/Preferences/MediaPrefsView.swift b/Tusker/Screens/Preferences/MediaPrefsView.swift index e644dc36..fc1abae3 100644 --- a/Tusker/Screens/Preferences/MediaPrefsView.swift +++ b/Tusker/Screens/Preferences/MediaPrefsView.swift @@ -15,7 +15,7 @@ struct MediaPrefsView: View { List { viewingSection } - .insetOrGroupedListStyle() + .listStyle(InsetGroupedListStyle()) .navigationBarTitle("Media") } diff --git a/Tusker/Screens/Preferences/PreferencesView.swift b/Tusker/Screens/Preferences/PreferencesView.swift index da5ab0a9..158192fd 100644 --- a/Tusker/Screens/Preferences/PreferencesView.swift +++ b/Tusker/Screens/Preferences/PreferencesView.swift @@ -89,7 +89,7 @@ struct PreferencesView: View { } } } - .insetOrGroupedListStyle() + .listStyle(InsetGroupedListStyle()) .navigationBarTitle(Text("Preferences"), displayMode: .inline) // } } @@ -99,17 +99,6 @@ struct PreferencesView: View { } } -extension View { - @ViewBuilder - func insetOrGroupedListStyle() -> some View { - if #available(iOS 14.0, *) { - self.listStyle(InsetGroupedListStyle()) - } else { - self.listStyle(GroupedListStyle()) - } - } -} - #if DEBUG struct PreferencesView_Previews : PreviewProvider { static var previews: some View { diff --git a/Tusker/Screens/Preferences/SilentActionPrefs.swift b/Tusker/Screens/Preferences/SilentActionPrefs.swift index a49b0edf..8e9d1e1e 100644 --- a/Tusker/Screens/Preferences/SilentActionPrefs.swift +++ b/Tusker/Screens/Preferences/SilentActionPrefs.swift @@ -14,7 +14,7 @@ struct SilentActionPrefs : View { List(Array(preferences.silentActions.keys), id: \.self) { source in SilentActionPermissionCell(source: source) } - .insetOrGroupedListStyle() + .listStyle(InsetGroupedListStyle()) // .navigationBarTitle("Silent Action Permissions") // see FB6838291 } diff --git a/Tusker/Screens/Preferences/WellnessPrefsView.swift b/Tusker/Screens/Preferences/WellnessPrefsView.swift index 0c6e1636..3b95867c 100644 --- a/Tusker/Screens/Preferences/WellnessPrefsView.swift +++ b/Tusker/Screens/Preferences/WellnessPrefsView.swift @@ -17,7 +17,7 @@ struct WellnessPrefsView: View { notificationsMode grayscaleImages } - .insetOrGroupedListStyle() + .listStyle(InsetGroupedListStyle()) .navigationBarTitle(Text("Digital Wellness")) } diff --git a/Tusker/Screens/Profile/ProfileViewController.swift b/Tusker/Screens/Profile/ProfileViewController.swift index 08347e4d..ecf83b51 100644 --- a/Tusker/Screens/Profile/ProfileViewController.swift +++ b/Tusker/Screens/Profile/ProfileViewController.swift @@ -69,13 +69,11 @@ class ProfileViewController: UIPageViewController { view.backgroundColor = .systemBackground let composeButton = UIBarButtonItem(barButtonSystemItem: .compose, target: self, action: #selector(composeMentioning)) - if #available(iOS 14.0, *) { - composeButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: [ - UIAction(title: "Direct Message", image: UIImage(systemName: Status.Visibility.direct.unfilledImageName), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off, handler: { (_) in - self.composeDirectMentioning() - }) - ]) - } + composeButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: [ + UIAction(title: "Direct Message", image: UIImage(systemName: Status.Visibility.direct.unfilledImageName), identifier: nil, discoverabilityTitle: nil, attributes: [], state: .off, handler: { (_) in + self.composeDirectMentioning() + }) + ]) navigationItem.rightBarButtonItem = composeButton headerView = ProfileHeaderView.create() diff --git a/Tusker/Screens/Utilities/Previewing.swift b/Tusker/Screens/Utilities/Previewing.swift index 4b807484..4017f17c 100644 --- a/Tusker/Screens/Utilities/Previewing.swift +++ b/Tusker/Screens/Utilities/Previewing.swift @@ -54,14 +54,14 @@ extension MenuPreviewProvider { }), ] - if accountID != mastodonController.account.id, - #available(iOS 14.0, *) { + if accountID != mastodonController.account.id { actionsSection.append(UIDeferredMenuElement({ (elementHandler) in guard let mastodonController = self.mastodonController else { elementHandler([]) return } let request = Client.getRelationships(accounts: [account.id]) + // talk about callback hell :/ mastodonController.run(request) { [weak self] (response) in if let self = self, case let .success(results, _) = response, diff --git a/Tusker/Screens/Utilities/TrackpadScrollGestureRecognizer.swift b/Tusker/Screens/Utilities/TrackpadScrollGestureRecognizer.swift index 285474d2..2df1d28b 100644 --- a/Tusker/Screens/Utilities/TrackpadScrollGestureRecognizer.swift +++ b/Tusker/Screens/Utilities/TrackpadScrollGestureRecognizer.swift @@ -8,7 +8,6 @@ import UIKit -@available(iOS 13.4, *) class TrackpadScrollGestureRecognizer: UIPanGestureRecognizer { override init(target: Any?, action: Selector?) { diff --git a/Tusker/TuskerNavigationDelegate.swift b/Tusker/TuskerNavigationDelegate.swift index e8c55bb2..39d4c353 100644 --- a/Tusker/TuskerNavigationDelegate.swift +++ b/Tusker/TuskerNavigationDelegate.swift @@ -125,41 +125,13 @@ extension TuskerNavigationDelegate { guard let status = apiController.persistentContainer.status(for: statusID) else { fatalError("Missing cached status \(statusID)") } guard let url = status.url else { fatalError("Missing url for status \(statusID)") } - // on iOS 14+, all these custom actions are in the context menu and don't need to be in the share sheet - if #available(iOS 14.0, *) { - return UIActivityViewController(activityItems: [url, StatusActivityItemSource(status)], applicationActivities: nil) - } else { - var customActivites: [UIActivity] = [ - OpenInSafariActivity(), - (status.bookmarked ?? false) ? UnbookmarkStatusActivity() : BookmarkStatusActivity(), - status.muted ? UnmuteConversationActivity() : MuteConversationActivity(), - ] - - if apiController.account != nil, status.account.id == apiController.account.id { - let pinned = status.pinned ?? false - customActivites.insert(pinned ? UnpinStatusActivity() : PinStatusActivity(), at: 1) - } - - let activityController = UIActivityViewController(activityItems: [url, StatusActivityItemSource(status)], applicationActivities: customActivites) - activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(navigator: self, url: url) - return activityController - } + return UIActivityViewController(activityItems: [url, StatusActivityItemSource(status)], applicationActivities: nil) } private func moreOptions(forAccount accountID: String) -> UIActivityViewController { guard let account = apiController.persistentContainer.account(for: accountID) else { fatalError("Missing cached account \(accountID)") } - if #available(iOS 14.0, *) { - return UIActivityViewController(activityItems: [account.url, AccountActivityItemSource(account)], applicationActivities: nil) - } else { - let customActivities: [UIActivity] = [ - OpenInSafariActivity(), - ] - - let activityController = UIActivityViewController(activityItems: [account.url, AccountActivityItemSource(account)], applicationActivities: customActivities) - activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(navigator: self, url: account.url) - return activityController - } + return UIActivityViewController(activityItems: [account.url, AccountActivityItemSource(account)], applicationActivities: nil) } func showMoreOptions(forStatus statusID: String, sourceView: UIView?) { diff --git a/Tusker/Views/AccountDisplayNameLabel.swift b/Tusker/Views/AccountDisplayNameLabel.swift index 1e2368d9..2c368c44 100644 --- a/Tusker/Views/AccountDisplayNameLabel.swift +++ b/Tusker/Views/AccountDisplayNameLabel.swift @@ -24,18 +24,11 @@ struct AccountDisplayNameLabel: View { } var body: some View { - if #available(iOS 14.0, *) { - text - .font(.system(size: CGFloat(fontSize), weight: .semibold)) - .onAppear(perform: self.loadEmojis) - } else { - text - .font(.system(size: CGFloat(fontSize), weight: .semibold)) - } + text + .font(.system(size: CGFloat(fontSize), weight: .semibold)) + .onAppear(perform: self.loadEmojis) } - // embedding Image inside Text is only available on iOS 14 - @available(iOS 14.0, *) private func loadEmojis() { let fullRange = NSRange(account.displayName.startIndex..., in: account.displayName) let matches = emojiRegex.matches(in: account.displayName, options: [], range: fullRange) diff --git a/Tusker/Views/ActivityIndicatorView.swift b/Tusker/Views/ActivityIndicatorView.swift deleted file mode 100644 index 89c916df..00000000 --- a/Tusker/Views/ActivityIndicatorView.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// ActivityIndicatorView.swift -// Tusker -// -// Created by Shadowfacts on 8/29/20. -// Copyright © 2020 Shadowfacts. All rights reserved. -// - -import SwiftUI - -struct ActivityIndicatorView: UIViewRepresentable { - typealias UIViewType = UIActivityIndicatorView - - func makeUIView(context: Context) -> UIActivityIndicatorView { - let view = UIActivityIndicatorView() - view.startAnimating() - return view - } - - func updateUIView(_ uiView: UIActivityIndicatorView, context: Context) { - } - -} diff --git a/Tusker/Views/MaybeLazyStack.swift b/Tusker/Views/MaybeLazyStack.swift deleted file mode 100644 index 2e2a67da..00000000 --- a/Tusker/Views/MaybeLazyStack.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// MaybeLazyStack.swift -// Tusker -// -// Created by Shadowfacts on 10/10/20. -// Copyright © 2020 Shadowfacts. All rights reserved. -// - -import SwiftUI - -struct MaybeLazyVStack: View { - private let alignment: HorizontalAlignment - private let spacing: CGFloat? - private let content: Content - - init(alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content) { - self.alignment = alignment - self.spacing = spacing - self.content = content() - } - - @ViewBuilder - var body: some View { - if #available(iOS 14.0, *) { - LazyVStack(alignment: alignment, spacing: spacing) { - content - } - } else { - VStack(alignment: alignment, spacing: spacing) { - content - } - } - } -} - -struct MaybeLazyHStack: View { - private let alignment: VerticalAlignment - private let spacing: CGFloat? - private let content: Content - - init(alignment: VerticalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content) { - self.alignment = alignment - self.spacing = spacing - self.content = content() - } - - @ViewBuilder - var body: some View { - if #available(iOS 14.0, *) { - LazyHStack(alignment: alignment, spacing: spacing) { - content - } - } else { - HStack(alignment: alignment, spacing: spacing) { - content - } - } - } -} diff --git a/Tusker/Views/Profile Header/ProfileHeaderView.swift b/Tusker/Views/Profile Header/ProfileHeaderView.swift index 6940a67d..16a92cb1 100644 --- a/Tusker/Views/Profile Header/ProfileHeaderView.swift +++ b/Tusker/Views/Profile Header/ProfileHeaderView.swift @@ -74,10 +74,8 @@ class ProfileHeaderView: UIView { NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil) moreButton.addInteraction(UIPointerInteraction(delegate: self)) - if #available(iOS 14.0, *) { - moreButton.showsMenuAsPrimaryAction = true - moreButton.isContextMenuInteractionEnabled = true - } + moreButton.showsMenuAsPrimaryAction = true + moreButton.isContextMenuInteractionEnabled = true } private func createObservers() { @@ -110,9 +108,7 @@ class ProfileHeaderView: UIView { updateImages(account: account) - if #available(iOS 14.0, *) { - moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: actionsForProfile(accountID: accountID, sourceView: moreButton)) - } + moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: actionsForProfile(accountID: accountID, sourceView: moreButton)) noteTextView.navigationDelegate = delegate noteTextView.setTextFromHtml(account.note) @@ -224,14 +220,6 @@ class ProfileHeaderView: UIView { // MARK: Interaction - @IBAction func morePressed(_ sender: Any) { - guard #available(iOS 14.0, *) else { - // can't use TuskerNavigationDelegate method, because it doesn't know about the (un)follow activity - delegate?.profileHeader(self, showMoreOptionsFor: accountID, sourceView: moreButton) - return - } - } - @objc func avatarPressed() { guard let account = mastodonController.persistentContainer.account(for: accountID) else { return @@ -253,7 +241,6 @@ class ProfileHeaderView: UIView { } -@available(iOS 13.4, *) extension ProfileHeaderView: UIPointerInteractionDelegate { func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? { let preview = UITargetedPreview(view: moreButton) diff --git a/Tusker/Views/Profile Header/ProfileHeaderView.xib b/Tusker/Views/Profile Header/ProfileHeaderView.xib index 9f388373..8a9fccd8 100644 --- a/Tusker/Views/Profile Header/ProfileHeaderView.xib +++ b/Tusker/Views/Profile Header/ProfileHeaderView.xib @@ -1,9 +1,8 @@ - + - - + @@ -58,9 +57,6 @@ - - - diff --git a/Tusker/Views/Status/BaseStatusTableViewCell.swift b/Tusker/Views/Status/BaseStatusTableViewCell.swift index 5799057c..05364e72 100644 --- a/Tusker/Views/Status/BaseStatusTableViewCell.swift +++ b/Tusker/Views/Status/BaseStatusTableViewCell.swift @@ -96,9 +96,7 @@ class BaseStatusTableViewCell: UITableViewCell { accessibilityElements = [displayNameLabel!, contentWarningLabel!, collapseButton!, contentTextView!, attachmentsView!] attachmentsView.isAccessibilityElement = true - if #available(iOS 14.0, *) { - moreButton.showsMenuAsPrimaryAction = true - } + moreButton.showsMenuAsPrimaryAction = true NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil) @@ -213,10 +211,8 @@ class BaseStatusTableViewCell: UITableViewCell { reblogButton.accessibilityLabel = NSLocalizedString("Reblog", comment: "reblog button accessibility label") } - if #available(iOS 14.0, *) { - // keep menu in sync with changed states e.g. bookmarked, muted - moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: actionsForStatus(status, sourceView: moreButton)) - } + // keep menu in sync with changed states e.g. bookmarked, muted + moreButton.menu = UIMenu(title: "", image: nil, identifier: nil, options: [], children: actionsForStatus(status, sourceView: moreButton)) } func updateUI(account: AccountMO) { diff --git a/Tusker/Views/Status/TimelineStatusTableViewCell.swift b/Tusker/Views/Status/TimelineStatusTableViewCell.swift index 3580f121..1a8d9b3d 100644 --- a/Tusker/Views/Status/TimelineStatusTableViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusTableViewCell.swift @@ -266,28 +266,17 @@ extension TimelineStatusTableViewCell: TableViewSwipeActionProvider { } func trailingSwipeActionsConfiguration() -> UISwipeActionsConfiguration? { - let moreTitle: String - let moreImage: UIImage - // on iOS 14+, more actions are in the context menu so display this as 'Share' - if #available(iOS 14.0, *) { - moreTitle = "Share" - // Bold to more closely match the other action symbols - let config = UIImage.SymbolConfiguration(weight: .bold) - moreImage = UIImage(systemName: "square.and.arrow.up")!.applyingSymbolConfiguration(config)! - } else { - moreTitle = "More" - moreImage = UIImage(systemName: "ellipsis.circle.fill")! - } - - let more = UIContextualAction(style: .normal, title: moreTitle) { (action, view, completion) in + let share = UIContextualAction(style: .normal, title: "Share") { (action, view, completion) in completion(true) self.delegate?.showMoreOptions(forStatus: self.statusID, sourceView: self) } - more.image = moreImage - more.backgroundColor = .lightGray + // Bold to more closely match the other action symbols + let config = UIImage.SymbolConfiguration(weight: .bold) + share.image = UIImage(systemName: "square.and.arrow.up")!.applyingSymbolConfiguration(config)! + share.backgroundColor = .lightGray guard mastodonController.loggedIn else { - return UISwipeActionsConfiguration(actions: [more]) + return UISwipeActionsConfiguration(actions: [share]) } let reply = UIContextualAction(style: .normal, title: "Reply") { (action, view, completion) in @@ -297,7 +286,7 @@ extension TimelineStatusTableViewCell: TableViewSwipeActionProvider { reply.image = UIImage(systemName: "arrowshape.turn.up.left.fill") reply.backgroundColor = tintColor - return UISwipeActionsConfiguration(actions: [reply, more]) + return UISwipeActionsConfiguration(actions: [reply, share]) } } diff --git a/TuskerUITests/ComposeTests.swift b/TuskerUITests/ComposeTests.swift index 9a6f6419..704d08e8 100644 --- a/TuskerUITests/ComposeTests.swift +++ b/TuskerUITests/ComposeTests.swift @@ -82,13 +82,8 @@ class ComposeTests: TuskerUITests { XCTAssertTrue(app.staticTexts["500 characters remaining"].exists) cwField.tap() - let str: String - // on iOS 14, the first type text is typed into a SwiftUI TextField, the 2nd character is inexplicably dropped >.< - if #available(iOS 14.0, *) { - str = "fooo" - } else { - str = "foo" - } + // on iOS 14, the first type text is typed into a SwiftUI TextField by a test has the 1st character is inexplicably dropped >.< + let str = "fooo" cwField.typeText(str) XCTAssertTrue(app.staticTexts["497 characters remaining"].exists) // CharacterCounter is not used => '@' is counted diff --git a/TuskerUITests/MyProfileTests.swift b/TuskerUITests/MyProfileTests.swift index a46a1612..2412177c 100644 --- a/TuskerUITests/MyProfileTests.swift +++ b/TuskerUITests/MyProfileTests.swift @@ -36,38 +36,28 @@ class MyProfileTests: TuskerUITests { XCTAssertTrue(app.buttons["More Actions"].exists) app.buttons["More Actions"].tap() - if #available(iOS 14.0, *) { - XCTAssertTrue(app.buttons["Open in Safari"].exists) - XCTAssertTrue(app.buttons["Share..."].exists) - XCTAssertTrue(app.buttons["Send Message"].exists) - - app.buttons["Open in Safari"].tap() - XCTAssertTrue(app.otherElements["TopBrowserBar"].exists) - app.buttons["Done"].tap() - XCTAssertFalse(app.otherElements["TopBrowserBar"].exists) - - app.buttons["More Actions"].tap() - app.buttons["Share..."].tap() - let activityListView = app.otherElements["ActivityListView"] - XCTAssertTrue(activityListView.waitForExistence(timeout: 0.2)) - activityListView.buttons["Close"].tap() - XCTAssertFalse(activityListView.exists) - - app.buttons["More Actions"].tap() - app.buttons["Send Message"].tap() - XCTAssertTrue(app.staticTexts["Compose"].exists) - XCTAssertTrue(app.buttons["Cancel"].exists) - XCTAssertTrue(app.buttons["Post"].exists) - app.buttons["Cancel"].tap() - } else { - // first tap doesn't trigger share sheet for some reason - app.buttons["More Actions"].tap() - let activityListView = app.otherElements["ActivityListView"] - XCTAssertTrue(activityListView.waitForExistence(timeout: 0.2)) - activityListView.buttons["Close"].tap() - XCTAssertFalse(activityListView.exists) - // can't test individual actions :/ - } + XCTAssertTrue(app.buttons["Open in Safari"].exists) + XCTAssertTrue(app.buttons["Share..."].exists) + XCTAssertTrue(app.buttons["Send Message"].exists) + + app.buttons["Open in Safari"].tap() + XCTAssertTrue(app.otherElements["TopBrowserBar"].exists) + app.buttons["Done"].tap() + XCTAssertFalse(app.otherElements["TopBrowserBar"].exists) + + app.buttons["More Actions"].tap() + app.buttons["Share..."].tap() + let activityListView = app.otherElements["ActivityListView"] + XCTAssertTrue(activityListView.waitForExistence(timeout: 0.2)) + activityListView.buttons["Close"].tap() + XCTAssertFalse(activityListView.exists) + + app.buttons["More Actions"].tap() + app.buttons["Send Message"].tap() + XCTAssertTrue(app.staticTexts["Compose"].exists) + XCTAssertTrue(app.buttons["Cancel"].exists) + XCTAssertTrue(app.buttons["Post"].exists) + app.buttons["Cancel"].tap() } }