diff --git a/Pachyderm/Sources/Pachyderm/Model/Emoji.swift b/Pachyderm/Sources/Pachyderm/Model/Emoji.swift index cd6657e6..9d85a3da 100644 --- a/Pachyderm/Sources/Pachyderm/Model/Emoji.swift +++ b/Pachyderm/Sources/Pachyderm/Model/Emoji.swift @@ -39,3 +39,9 @@ extension Emoji: CustomDebugStringConvertible { return ":\(shortcode):" } } + +extension Emoji: Equatable { + public static func ==(lhs: Emoji, rhs: Emoji) -> Bool { + return lhs.shortcode == rhs.shortcode && lhs.url == rhs.url + } +} diff --git a/Tusker.xcodeproj/project.pbxproj b/Tusker.xcodeproj/project.pbxproj index deb31151..70b40ee2 100644 --- a/Tusker.xcodeproj/project.pbxproj +++ b/Tusker.xcodeproj/project.pbxproj @@ -219,13 +219,11 @@ D6AEBB4523216AF800E5038B /* FollowAccountActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6AEBB4423216AF800E5038B /* FollowAccountActivity.swift */; }; D6AEBB4823216B1D00E5038B /* AccountActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6AEBB4723216B1D00E5038B /* AccountActivity.swift */; }; D6AEBB4A23216F0400E5038B /* UnfollowAccountActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6AEBB4923216F0400E5038B /* UnfollowAccountActivity.swift */; }; - D6B0539F23BD2BA300A066FA /* SheetController in Frameworks */ = {isa = PBXBuildFile; productRef = D6B0539E23BD2BA300A066FA /* SheetController */; }; D6B053A223BD2C0600A066FA /* AssetPickerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B053A123BD2C0600A066FA /* AssetPickerViewController.swift */; }; D6B053A423BD2C8100A066FA /* AssetCollectionsListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B053A323BD2C8100A066FA /* AssetCollectionsListViewController.swift */; }; D6B053A623BD2D0C00A066FA /* AssetCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B053A523BD2D0C00A066FA /* AssetCollectionViewController.swift */; }; D6B053AB23BD2F1400A066FA /* AssetCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B053A923BD2F1400A066FA /* AssetCollectionViewCell.swift */; }; D6B053AC23BD2F1400A066FA /* AssetCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D6B053AA23BD2F1400A066FA /* AssetCollectionViewCell.xib */; }; - D6B053AE23BD322B00A066FA /* AssetPickerSheetContainerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B053AD23BD322B00A066FA /* AssetPickerSheetContainerViewController.swift */; }; D6B17255254F88B800128392 /* OppositeCollapseKeywordsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B17254254F88B800128392 /* OppositeCollapseKeywordsView.swift */; }; D6B22A0F2560D52D004D82EF /* TabbedPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B22A0E2560D52D004D82EF /* TabbedPageViewController.swift */; }; D6B30E09254BAF63009CAEE5 /* ImageGrayscalifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6B30E08254BAF63009CAEE5 /* ImageGrayscalifier.swift */; }; @@ -280,7 +278,6 @@ D6DFC69E242C490400ACC392 /* TrackpadScrollGestureRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DFC69D242C490400ACC392 /* TrackpadScrollGestureRecognizer.swift */; }; D6DFC6A0242C4CCC00ACC392 /* WeakArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6DFC69F242C4CCC00ACC392 /* WeakArray.swift */; }; D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E0DC8D216EDF1E00369478 /* Previewing.swift */; }; - D6E1EEF4285443EF00D20549 /* UIAction+Subtitle.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E1EEF3285443EF00D20549 /* UIAction+Subtitle.swift */; }; D6E343AB265AAD6B00C4AA01 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D6E343AA265AAD6B00C4AA01 /* Media.xcassets */; }; D6E343AD265AAD6B00C4AA01 /* ActionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E343AC265AAD6B00C4AA01 /* ActionViewController.swift */; }; D6E343B0265AAD6B00C4AA01 /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6E343AE265AAD6B00C4AA01 /* MainInterface.storyboard */; }; @@ -570,7 +567,6 @@ D6B053A523BD2D0C00A066FA /* AssetCollectionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetCollectionViewController.swift; sourceTree = ""; }; D6B053A923BD2F1400A066FA /* AssetCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetCollectionViewCell.swift; sourceTree = ""; }; D6B053AA23BD2F1400A066FA /* AssetCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AssetCollectionViewCell.xib; sourceTree = ""; }; - D6B053AD23BD322B00A066FA /* AssetPickerSheetContainerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssetPickerSheetContainerViewController.swift; sourceTree = ""; }; D6B17254254F88B800128392 /* OppositeCollapseKeywordsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OppositeCollapseKeywordsView.swift; sourceTree = ""; }; D6B22A0E2560D52D004D82EF /* TabbedPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabbedPageViewController.swift; sourceTree = ""; }; D6B30E08254BAF63009CAEE5 /* ImageGrayscalifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageGrayscalifier.swift; sourceTree = ""; }; @@ -631,7 +627,6 @@ D6DFC69D242C490400ACC392 /* TrackpadScrollGestureRecognizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackpadScrollGestureRecognizer.swift; sourceTree = ""; }; D6DFC69F242C4CCC00ACC392 /* WeakArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakArray.swift; sourceTree = ""; }; D6E0DC8D216EDF1E00369478 /* Previewing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Previewing.swift; sourceTree = ""; }; - D6E1EEF3285443EF00D20549 /* UIAction+Subtitle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIAction+Subtitle.swift"; sourceTree = ""; }; D6E343A8265AAD6B00C4AA01 /* OpenInTusker.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OpenInTusker.appex; sourceTree = BUILT_PRODUCTS_DIR; }; D6E343AA265AAD6B00C4AA01 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = ""; }; D6E343AC265AAD6B00C4AA01 /* ActionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActionViewController.swift; sourceTree = ""; }; @@ -665,7 +660,6 @@ buildActionMask = 2147483647; files = ( D674A50927F9128D00BA03AC /* Pachyderm in Frameworks */, - D6B0539F23BD2BA300A066FA /* SheetController in Frameworks */, D69CCBBF249E6EFD000AF167 /* CrashReporter in Frameworks */, D60CFFDB24A290BA00D00083 /* SwiftSoup in Frameworks */, D6676CA527A8D0020052936B /* WebURLFoundationExtras in Frameworks */, @@ -1120,7 +1114,6 @@ D6620ACD2511A0ED00312CA0 /* StatusStateResolver.swift */, D69693F32585941A00F4E116 /* UIWindowSceneDelegate+Close.swift */, D62E9984279CA23900C26176 /* URLSession+Development.swift */, - D6E1EEF3285443EF00D20549 /* UIAction+Subtitle.swift */, ); path = Extensions; sourceTree = ""; @@ -1239,7 +1232,6 @@ D6B053A523BD2D0C00A066FA /* AssetCollectionViewController.swift */, D626493E23C101C500612E6E /* AlbumAssetCollectionViewController.swift */, D64BC18523C1253A000D0238 /* AssetPreviewViewController.swift */, - D6B053AD23BD322B00A066FA /* AssetPickerSheetContainerViewController.swift */, ); path = "Asset Picker"; sourceTree = ""; @@ -1501,7 +1493,6 @@ ); name = Tusker; packageProductDependencies = ( - D6B0539E23BD2BA300A066FA /* SheetController */, D69CCBBE249E6EFD000AF167 /* CrashReporter */, D60CFFDA24A290BA00D00083 /* SwiftSoup */, D6676CA427A8D0020052936B /* WebURLFoundationExtras */, @@ -1611,7 +1602,6 @@ ); mainGroup = D6D4DDC3212518A000E1C4BB; packageReferences = ( - D6B0539D23BD2BA300A066FA /* XCRemoteSwiftPackageReference "SheetController" */, D69CCBBD249E6EFD000AF167 /* XCRemoteSwiftPackageReference "plcrashreporter" */, D60CFFD924A290BA00D00083 /* XCRemoteSwiftPackageReference "SwiftSoup" */, D6676CA127A8D0020052936B /* XCRemoteSwiftPackageReference "swift-url" */, @@ -1760,7 +1750,6 @@ D64BC18F23C18B9D000D0238 /* FollowRequestNotificationTableViewCell.swift in Sources */, D62E9989279DB2D100C26176 /* InstanceFeatures.swift in Sources */, D693DE5923FE24310061E07D /* InteractivePushTransition.swift in Sources */, - D6E1EEF4285443EF00D20549 /* UIAction+Subtitle.swift in Sources */, D69693FA25859A8000F4E116 /* ComposeSceneDelegate.swift in Sources */, D6A3BC8A2321F79B00FD64D5 /* AccountTableViewCell.swift in Sources */, D66A77BB233838DC0058F1EC /* UIFont+Traits.swift in Sources */, @@ -1883,7 +1872,6 @@ D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */, D6945C2F23AC47C3005C403C /* SavedDataManager.swift in Sources */, D6C94D892139E6EC00CB5196 /* AttachmentView.swift in Sources */, - D6B053AE23BD322B00A066FA /* AssetPickerSheetContainerViewController.swift in Sources */, D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */, D6C94D872139E62700CB5196 /* LargeImageViewController.swift in Sources */, D6B053AB23BD2F1400A066FA /* AssetCollectionViewCell.swift in Sources */, @@ -2201,7 +2189,7 @@ CURRENT_PROJECT_VERSION = 31; DEVELOPMENT_TEAM = V4WK9KR9U2; INFOPLIST_FILE = Tusker/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.3; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -2231,7 +2219,7 @@ CURRENT_PROJECT_VERSION = 31; DEVELOPMENT_TEAM = V4WK9KR9U2; INFOPLIST_FILE = Tusker/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.3; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -2459,14 +2447,6 @@ minimumVersion = 1.8.0; }; }; - D6B0539D23BD2BA300A066FA /* XCRemoteSwiftPackageReference "SheetController" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://git.shadowfacts.net/shadowfacts/SheetController.git"; - requirement = { - branch = master; - kind = branch; - }; - }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -2489,11 +2469,6 @@ package = D69CCBBD249E6EFD000AF167 /* XCRemoteSwiftPackageReference "plcrashreporter" */; productName = CrashReporter; }; - D6B0539E23BD2BA300A066FA /* SheetController */ = { - isa = XCSwiftPackageProductDependency; - package = D6B0539D23BD2BA300A066FA /* XCRemoteSwiftPackageReference "SheetController" */; - productName = SheetController; - }; /* End XCSwiftPackageProductDependency section */ /* Begin XCVersionGroup section */ diff --git a/Tusker/Caching/ImageCache.swift b/Tusker/Caching/ImageCache.swift index faf82b36..c14b172f 100644 --- a/Tusker/Caching/ImageCache.swift +++ b/Tusker/Caching/ImageCache.swift @@ -41,20 +41,14 @@ class ImageCache { let wrappedCompletion: ((Data?, UIImage?) -> Void)? if let completion = completion { wrappedCompletion = { (data, image) in - if #available(iOS 15.0, *) { - if !loadOriginal, - let size = self.desiredPixelSize { - image?.prepareThumbnail(of: size, completionHandler: { - completion(data, $0) - }) - } else { - image?.prepareForDisplay { - completion(data, $0) - } - } + if !loadOriginal, + let size = self.desiredPixelSize { + image?.prepareThumbnail(of: size, completionHandler: { + completion(data, $0) + }) } else { - self.backgroundQueue.async { - completion(data, image) + image?.prepareForDisplay { + completion(data, $0) } } } diff --git a/Tusker/Extensions/UIAction+Subtitle.swift b/Tusker/Extensions/UIAction+Subtitle.swift deleted file mode 100644 index 690ed97f..00000000 --- a/Tusker/Extensions/UIAction+Subtitle.swift +++ /dev/null @@ -1,19 +0,0 @@ -// -// UIAction+Subtitle.swift -// Tusker -// -// Created by Shadowfacts on 6/10/22. -// Copyright © 2022 Shadowfacts. All rights reserved. -// - -import UIKit - -extension UIAction { - convenience init(title: String, subtitle: String?, image: UIImage?, state: UIAction.State, handler: @escaping UIActionHandler) { - if #available(iOS 15.0, *) { - self.init(title: title, subtitle: subtitle, image: image, identifier: nil, discoverabilityTitle: nil, attributes: [], state: state, handler: handler) - } else { - self.init(title: title, image: image, identifier: nil, discoverabilityTitle: nil, attributes: [], state: state, handler: handler) - } - } -} diff --git a/Tusker/Screens/Asset Picker/AssetPickerSheetContainerViewController.swift b/Tusker/Screens/Asset Picker/AssetPickerSheetContainerViewController.swift deleted file mode 100644 index 64d6ad62..00000000 --- a/Tusker/Screens/Asset Picker/AssetPickerSheetContainerViewController.swift +++ /dev/null @@ -1,63 +0,0 @@ -// -// AssetPickerSheetContainerViewController.swift -// Tusker -// -// Created by Shadowfacts on 1/1/20. -// Copyright © 2020 Shadowfacts. All rights reserved. -// - -import UIKit -import SheetController -import Photos - -class AssetPickerSheetContainerViewController: SheetContainerViewController { - - let assetPicker = AssetPickerViewController() - - init() { - super.init(content: assetPicker) - - assetPicker.view.translatesAutoresizingMaskIntoConstraints = false - assetPicker.view.layer.masksToBounds = true - - delegate = self - assetPicker.delegate = self - detents = [.bottom, .middle, .top] - - overrideUserInterfaceStyle = .dark - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - - override func viewDidLoad() { - assetPicker.view.layer.cornerRadius = view.bounds.width * 0.02 - // don't round bottom corners, since they'll always be cut off by the device - assetPicker.view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] - - super.viewDidLoad() - } - -} - -extension AssetPickerSheetContainerViewController: SheetContainerViewControllerDelegate { - func sheetContainerContentScrollView(_ sheetContainer: SheetContainerViewController) -> UIScrollView? { - if let vc = assetPicker.visibleViewController as? UITableViewController { - return vc.tableView - } else if let vc = assetPicker.visibleViewController as? UICollectionViewController { - return vc.collectionView - } - return nil - } - func sheetContainer(_ sheetContainer: SheetContainerViewController, topContentOffsetForScrollView scrollView: UIScrollView) -> CGFloat { - return assetPicker.navigationBar.bounds.height - } -} - -extension AssetPickerSheetContainerViewController: UINavigationControllerDelegate { - func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { - contentScrollViewChanged() -// viewController.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(donePressed)) - } -} diff --git a/Tusker/Screens/Compose/ComposeAttachmentRow.swift b/Tusker/Screens/Compose/ComposeAttachmentRow.swift index a4aa7040..b02fd266 100644 --- a/Tusker/Screens/Compose/ComposeAttachmentRow.swift +++ b/Tusker/Screens/Compose/ComposeAttachmentRow.swift @@ -37,15 +37,9 @@ struct ComposeAttachmentRow: View { } } - if #available(iOS 15.0, *) { - Button(action: self.removeAttachment) { - Label("Delete", systemImage: "trash") - }.foregroundStyle(.red) - } else { - Button(action: self.removeAttachment) { - Label("Delete", systemImage: "trash") - } - } + Button(action: self.removeAttachment) { + Label("Delete", systemImage: "trash") + }.foregroundStyle(.red) } previewIfAvailable: { ComposeAttachmentImage(attachment: attachment, fullSize: true) } diff --git a/Tusker/Screens/Compose/ComposeAttachmentsList.swift b/Tusker/Screens/Compose/ComposeAttachmentsList.swift index 0576f688..0d2f30f5 100644 --- a/Tusker/Screens/Compose/ComposeAttachmentsList.swift +++ b/Tusker/Screens/Compose/ComposeAttachmentsList.swift @@ -191,16 +191,6 @@ struct ComposeAttachmentsList: View { } fileprivate extension View { - @available(iOS, obsoleted: 15.0) - @ViewBuilder - func onDragWithPreviewIfAvailable(_ data: @escaping () -> NSItemProvider, preview: () -> V) -> some View where V : View { - if #available(iOS 15.0, *) { - self.onDrag(data, preview: preview) - } else { - self.onDrag(data) - } - } - @available(iOS, obsoleted: 16.0) @ViewBuilder func sheetOrPopover(isPresented: Binding, @ViewBuilder content: @escaping () -> some View) -> some View { diff --git a/Tusker/Screens/Compose/ComposeAutocompleteView.swift b/Tusker/Screens/Compose/ComposeAutocompleteView.swift index 813b4777..b7b62fba 100644 --- a/Tusker/Screens/Compose/ComposeAutocompleteView.swift +++ b/Tusker/Screens/Compose/ComposeAutocompleteView.swift @@ -25,8 +25,6 @@ struct ComposeAutocompleteView: View { var body: some View { suggestionsView - // animate changes of the scroll view items - .animation(.default) .background(backgroundColor) .overlay(borderColor.frame(height: 0.5), alignment: .top) } @@ -85,8 +83,8 @@ struct ComposeAutocompleteMentionsView: View { } .frame(height: 30) .padding(.vertical, 8) - .animation(.linear(duration: 0.1)) } + .animation(.linear(duration: 0.1), value: accounts) Spacer() } @@ -167,7 +165,7 @@ struct ComposeAutocompleteMentionsView: View { .map(\.0) } - private enum EitherAccount { + private enum EitherAccount: Equatable { case pachyderm(Account) case coreData(AccountMO) @@ -197,6 +195,10 @@ struct ComposeAutocompleteMentionsView: View { return account.avatar } } + + static func ==(lhs: EitherAccount, rhs: EitherAccount) -> Bool { + return lhs.id == rhs.id + } } } @@ -212,7 +214,7 @@ struct ComposeAutocompleteEmojisView: View { HStack(alignment: expanded ? .top : .center, spacing: 0) { if case let .emoji(query) = uiState.autocompleteState { emojiList(query: query) - .animation(.default) + .animation(.default, value: expanded) .transition(.move(edge: .bottom)) } else { // when the autocomplete view is animating out, the autocomplete state is nil @@ -259,8 +261,8 @@ struct ComposeAutocompleteEmojisView: View { } .frame(height: 30) .padding(.vertical, 8) - .animation(.linear(duration: 0.2)) } + .animation(.linear(duration: 0.2), value: emojis) Spacer(minLength: 30) } @@ -319,8 +321,8 @@ struct ComposeAutocompleteHashtagsView: View { } .frame(height: 30) .padding(.vertical, 8) - .animation(.linear(duration: 0.1)) } + .animation(.linear(duration: 0.1), value: hashtags) Spacer() } diff --git a/Tusker/Screens/Compose/ComposeHostingController.swift b/Tusker/Screens/Compose/ComposeHostingController.swift index 6e7acee9..f420d08b 100644 --- a/Tusker/Screens/Compose/ComposeHostingController.swift +++ b/Tusker/Screens/Compose/ComposeHostingController.swift @@ -339,24 +339,14 @@ extension ComposeHostingController: ComposeUIStateDelegate { } func presentAssetPickerSheet() { - if #available(iOS 15.0, *) { - let picker = AssetPickerViewController() - picker.assetPickerDelegate = self - picker.modalPresentationStyle = .pageSheet - picker.overrideUserInterfaceStyle = .dark - let sheet = picker.sheetPresentationController! - sheet.detents = [.medium(), .large()] - sheet.prefersEdgeAttachedInCompactHeight = true - self.present(picker, animated: true) - } else { - presentOldAssetPickerSheet() - } - } - - private func presentOldAssetPickerSheet() { - let sheetContainer = AssetPickerSheetContainerViewController() - sheetContainer.assetPicker.assetPickerDelegate = self - self.present(sheetContainer, animated: true) + let picker = AssetPickerViewController() + picker.assetPickerDelegate = self + picker.modalPresentationStyle = .pageSheet + picker.overrideUserInterfaceStyle = .dark + let sheet = picker.sheetPresentationController! + sheet.detents = [.medium(), .large()] + sheet.prefersEdgeAttachedInCompactHeight = true + self.present(picker, animated: true) } func presentComposeDrawing() { diff --git a/Tusker/Screens/Compose/ComposePollView.swift b/Tusker/Screens/Compose/ComposePollView.swift index f4354e80..6c1d0d46 100644 --- a/Tusker/Screens/Compose/ComposePollView.swift +++ b/Tusker/Screens/Compose/ComposePollView.swift @@ -60,7 +60,9 @@ struct ComposePollView: View { HStack { // use .animation(nil) on pickers so frame doesn't have a size change animation when the text changes - Picker(selection: $poll.multiple, label: Text(poll.multiple ? "Allow multiple choices" : "Single choice")) { + // this is deprecated in iOS 15, but using .animation(nil, value: poll.multiple) does not work (it still animates) + // nor does setting that on the Text rather than the Picker + Picker(selection: $poll.multiple, label: Text(poll.multiple ? "Allow multiple choice" : "Single choice")) { Text("Allow multiple choices").tag(true) Text("Single choice").tag(false) } @@ -154,8 +156,7 @@ struct ComposePollOption: View { var body: some View { HStack(spacing: 4) { Checkbox(radiusFraction: poll.multiple ? 0.1 : 0.5, borderWidth: 2) - .animation(.default) - + .animation(.default, value: poll.multiple) textField diff --git a/Tusker/Screens/Compose/ComposeUIState.swift b/Tusker/Screens/Compose/ComposeUIState.swift index 4ff53ce5..ac07d190 100644 --- a/Tusker/Screens/Compose/ComposeUIState.swift +++ b/Tusker/Screens/Compose/ComposeUIState.swift @@ -49,7 +49,7 @@ extension ComposeUIState { } extension ComposeUIState { - enum AutocompleteState { + enum AutocompleteState: Equatable { case mention(String) case emoji(String) case hashtag(String) diff --git a/Tusker/Screens/Compose/ComposeView.swift b/Tusker/Screens/Compose/ComposeView.swift index 6654e86e..8ee358fc 100644 --- a/Tusker/Screens/Compose/ComposeView.swift +++ b/Tusker/Screens/Compose/ComposeView.swift @@ -119,7 +119,7 @@ struct ComposeView: View { } } .transition(.move(edge: .bottom)) - .animation(.default) + .animation(.default, value: uiState.autocompleteState) } func mainStack(outerMinY: CGFloat) -> some View { @@ -147,7 +147,6 @@ struct ComposeView: View { if let poll = draft.poll { ComposePollView(draft: draft, poll: poll) .transition(.opacity.combined(with: .asymmetric(insertion: .scale(scale: 0.5, anchor: .leading), removal: .scale(scale: 0.5, anchor: .trailing)))) - .animation(.default) } diff --git a/Tusker/Screens/Conversation/ConversationTableViewController.swift b/Tusker/Screens/Conversation/ConversationTableViewController.swift index 8eb61da2..3852ac3e 100644 --- a/Tusker/Screens/Conversation/ConversationTableViewController.swift +++ b/Tusker/Screens/Conversation/ConversationTableViewController.swift @@ -124,13 +124,8 @@ class ConversationTableViewController: EnhancedTableViewController { } }) - if #available(iOS 15.0, *) { - visibilityBarButtonItem = UIBarButtonItem(image: ConversationTableViewController.showPostsImage, style: .plain, target: self, action: #selector(toggleVisibilityButtonPressed)) - visibilityBarButtonItem.isSelected = showStatusesAutomatically - } else { - let initialImage = showStatusesAutomatically ? ConversationTableViewController.hidePostsImage : ConversationTableViewController.showPostsImage - visibilityBarButtonItem = UIBarButtonItem(image: initialImage, style: .plain, target: self, action: #selector(toggleVisibilityButtonPressed)) - } + visibilityBarButtonItem = UIBarButtonItem(image: ConversationTableViewController.showPostsImage, style: .plain, target: self, action: #selector(toggleVisibilityButtonPressed)) + visibilityBarButtonItem.isSelected = showStatusesAutomatically navigationItem.rightBarButtonItem = visibilityBarButtonItem // disable transparent background when scroll to top because it looks weird when items earlier in the thread load in // (it remains transparent slightly too long, resulting in a flash of the content under the transparent bar) @@ -396,15 +391,7 @@ class ConversationTableViewController: EnhancedTableViewController { tableView.beginUpdates() tableView.endUpdates() - if #available(iOS 15.0, *) { - visibilityBarButtonItem.isSelected = showStatusesAutomatically - } else { - if showStatusesAutomatically { - visibilityBarButtonItem.image = ConversationTableViewController.hidePostsImage - } else { - visibilityBarButtonItem.image = ConversationTableViewController.showPostsImage - } - } + visibilityBarButtonItem.isSelected = showStatusesAutomatically } } diff --git a/Tusker/Screens/Explore/TrendingHashtagsViewController.swift b/Tusker/Screens/Explore/TrendingHashtagsViewController.swift index 97833934..a48f5266 100644 --- a/Tusker/Screens/Explore/TrendingHashtagsViewController.swift +++ b/Tusker/Screens/Explore/TrendingHashtagsViewController.swift @@ -64,7 +64,7 @@ class TrendingHashtagsViewController: UIViewController { var snapshot = NSDiffableDataSourceSnapshot() snapshot.appendSections([.trendingTags]) snapshot.appendItems(hashtags.map { .tag($0) }) - dataSource.apply(snapshot) + await dataSource.apply(snapshot) } } diff --git a/Tusker/Screens/Main/MainSidebarViewController.swift b/Tusker/Screens/Main/MainSidebarViewController.swift index d5f67eb1..c95e8c66 100644 --- a/Tusker/Screens/Main/MainSidebarViewController.swift +++ b/Tusker/Screens/Main/MainSidebarViewController.swift @@ -550,8 +550,7 @@ extension MainSidebarViewController: UICollectionViewDelegate { } func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? { - guard #available(iOS 15.0, *), - let item = dataSource.itemIdentifier(for: indexPath), + guard let item = dataSource.itemIdentifier(for: indexPath), let activity = userActivityForItem(item) else { return nil } diff --git a/Tusker/Screens/Main/MainSplitViewController.swift b/Tusker/Screens/Main/MainSplitViewController.swift index 5ae30e54..cf6fa51b 100644 --- a/Tusker/Screens/Main/MainSplitViewController.swift +++ b/Tusker/Screens/Main/MainSplitViewController.swift @@ -380,7 +380,7 @@ fileprivate extension MainSidebarViewController.Item { extension MainSplitViewController: TuskerRootViewController { @objc func presentCompose() { - if #available(iOS 15.0, *), UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { + if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { let compose = UserActivityManager.newPostActivity(mentioning: nil, accountID: mastodonController.accountInfo!.id) let options = UIWindowScene.ActivationRequestOptions() options.preferredPresentationStyle = .prominent diff --git a/Tusker/Screens/Main/MainTabBarViewController.swift b/Tusker/Screens/Main/MainTabBarViewController.swift index 8319dfc4..318b39d3 100644 --- a/Tusker/Screens/Main/MainTabBarViewController.swift +++ b/Tusker/Screens/Main/MainTabBarViewController.swift @@ -230,7 +230,7 @@ extension MainTabBarViewController: FastAccountSwitcherViewControllerDelegate { extension MainTabBarViewController: TuskerRootViewController { @objc func presentCompose() { - if #available(iOS 15.0, *), UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { + if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { let compose = UserActivityManager.newPostActivity(mentioning: nil, accountID: mastodonController.accountInfo!.id) let options = UIWindowScene.ActivationRequestOptions() options.preferredPresentationStyle = .prominent diff --git a/Tusker/Screens/Preferences/OppositeCollapseKeywordsView.swift b/Tusker/Screens/Preferences/OppositeCollapseKeywordsView.swift index e8be84d0..9cb844ff 100644 --- a/Tusker/Screens/Preferences/OppositeCollapseKeywordsView.swift +++ b/Tusker/Screens/Preferences/OppositeCollapseKeywordsView.swift @@ -38,7 +38,7 @@ struct OppositeCollapseKeywordsView: View { FocusableTextField(placeholder: "Add Keyword", text: $valueToAdd, becomeFirstResponder: $makeAddFieldFirstResponder, onCommit: self.addKeyword) } } - .animation(.default) + .animation(.default, value: keywords.map(\.id)) .listStyle(GroupedListStyle()) } .onAppear(perform: updateAppearance) diff --git a/Tusker/Screens/Preferences/WellnessPrefsView.swift b/Tusker/Screens/Preferences/WellnessPrefsView.swift index d96b3a60..100c26fe 100644 --- a/Tusker/Screens/Preferences/WellnessPrefsView.swift +++ b/Tusker/Screens/Preferences/WellnessPrefsView.swift @@ -16,9 +16,7 @@ struct WellnessPrefsView: View { showFavAndReblogCount notificationsMode grayscaleImages - if #available(iOS 15.0, *) { - disableInfiniteScrolling - } + disableInfiniteScrolling hideDiscover } .listStyle(InsetGroupedListStyle()) diff --git a/Tusker/Screens/Timeline/TimelineTableViewController.swift b/Tusker/Screens/Timeline/TimelineTableViewController.swift index 04aaf676..3b117abf 100644 --- a/Tusker/Screens/Timeline/TimelineTableViewController.swift +++ b/Tusker/Screens/Timeline/TimelineTableViewController.swift @@ -164,8 +164,7 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController NSUserActivity) { - if #available(iOS 15.0, *) { - let options = UIWindowScene.ActivationRequestOptions() - options.preferredPresentationStyle = .automatic - actions.append(UIWindowScene.ActivationAction { (_) in - let activity = activity() - activity.displaysAuxiliaryScene = true - return .init(userActivity: activity, options: options, preview: nil) - }) - } else if UIApplication.shared.supportsMultipleScenes { - actions.append(createAction(identifier: "new_window", title: "Open in New Window", systemImageName: "rectangle.badge.plus", handler: { (_) in - let activity = activity() - activity.displaysAuxiliaryScene = true - UIApplication.shared.requestSceneSessionActivation(nil, userActivity: activity, options: nil, errorHandler: nil) - })) - } + let options = UIWindowScene.ActivationRequestOptions() + options.preferredPresentationStyle = .automatic + actions.append(UIWindowScene.ActivationAction { (_) in + let activity = activity() + activity.displaysAuxiliaryScene = true + return .init(userActivity: activity, options: options, preview: nil) + }) } private func followAction(for accountID: String, mastodonController: MastodonController) async -> UIMenuElement? { @@ -423,13 +415,3 @@ extension SFSafariViewController: CustomPreviewPresenting { presenter.present(self, animated: true) } } - -private extension UIDeferredMenuElement { - static func uncachedIfPossible(_ elementProvider: @escaping (@escaping ([UIMenuElement]) -> Void) -> Void) -> UIDeferredMenuElement { - if #available(iOS 15.0, *) { - return UIDeferredMenuElement.uncached(elementProvider) - } else { - return UIDeferredMenuElement(elementProvider) - } - } -} diff --git a/Tusker/TuskerNavigationDelegate.swift b/Tusker/TuskerNavigationDelegate.swift index a65ffcb4..5816f866 100644 --- a/Tusker/TuskerNavigationDelegate.swift +++ b/Tusker/TuskerNavigationDelegate.swift @@ -89,7 +89,7 @@ extension TuskerNavigationDelegate { } func compose(editing draft: Draft) { - if #available(iOS 15.0, *), UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { + if UIDevice.current.userInterfaceIdiom == .pad || UIDevice.current.userInterfaceIdiom == .mac { let compose = UserActivityManager.editDraftActivity(id: draft.id, accountID: apiController.accountInfo!.id) let options = UIWindowScene.ActivationRequestOptions() options.preferredPresentationStyle = .prominent diff --git a/Tusker/Views/Confirm Load More Cell/ConfirmLoadMoreTableViewCell.swift b/Tusker/Views/Confirm Load More Cell/ConfirmLoadMoreTableViewCell.swift index 13425605..844170cd 100644 --- a/Tusker/Views/Confirm Load More Cell/ConfirmLoadMoreTableViewCell.swift +++ b/Tusker/Views/Confirm Load More Cell/ConfirmLoadMoreTableViewCell.swift @@ -23,15 +23,13 @@ class ConfirmLoadMoreTableViewCell: UITableViewCell { override func awakeFromNib() { super.awakeFromNib() - if #available(iOS 15.0, *) { - var config = UIButton.Configuration.tinted() - config.title = "Load More" - config.showsActivityIndicator = false - config.imagePadding = 4 - confirmButton.configuration = config - confirmButton.configurationUpdateHandler = { [unowned self] button in - button.configuration?.showsActivityIndicator = self.isLoading - } + var config = UIButton.Configuration.tinted() + config.title = "Load More" + config.showsActivityIndicator = false + config.imagePadding = 4 + confirmButton.configuration = config + confirmButton.configurationUpdateHandler = { [unowned self] button in + button.configuration?.showsActivityIndicator = self.isLoading } } @@ -39,17 +37,13 @@ class ConfirmLoadMoreTableViewCell: UITableViewCell { super.prepareForReuse() isLoading = false - if #available(iOS 15.0, *) { - confirmButton.setNeedsUpdateConfiguration() - } + confirmButton.setNeedsUpdateConfiguration() } @IBAction func loadMorePressed(_ sender: Any) { confirmLoadMore?() - if #available(iOS 15.0, *) { - isLoading = true - confirmButton.setNeedsUpdateConfiguration() - } + isLoading = true + confirmButton.setNeedsUpdateConfiguration() } } diff --git a/Tusker/Views/Timeline Description Cell/PublicTimelineDescriptionTableViewCell.swift b/Tusker/Views/Timeline Description Cell/PublicTimelineDescriptionTableViewCell.swift index 6cf2955d..7faa8568 100644 --- a/Tusker/Views/Timeline Description Cell/PublicTimelineDescriptionTableViewCell.swift +++ b/Tusker/Views/Timeline Description Cell/PublicTimelineDescriptionTableViewCell.swift @@ -24,11 +24,7 @@ class PublicTimelineDescriptionTableViewCell: UITableViewCell { override func awakeFromNib() { super.awakeFromNib() - if #available(iOS 15.0, *) { - contentView.backgroundColor = .tintColor - } else { - contentView.backgroundColor = .systemBlue - } + contentView.backgroundColor = .tintColor } private func updateLabel() {