Remove unused pre-iOS 14 code
This commit is contained in:
parent
f44d127110
commit
669d55500a
|
@ -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 = "<group>"; };
|
||||
D6C94D862139E62700CB5196 /* LargeImageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LargeImageViewController.swift; sourceTree = "<group>"; };
|
||||
D6C94D882139E6EC00CB5196 /* AttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentView.swift; sourceTree = "<group>"; };
|
||||
D6C99FC624FACFAB005C74D3 /* ActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorView.swift; sourceTree = "<group>"; };
|
||||
D6C99FCA24FADC91005C74D3 /* MainComposeTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainComposeTextView.swift; sourceTree = "<group>"; };
|
||||
D6CA6A91249FAD8900AD45C1 /* AudioSessionHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AudioSessionHelper.swift; sourceTree = "<group>"; };
|
||||
D6CA6A93249FADE700AD45C1 /* GalleryPlayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GalleryPlayerViewController.swift; sourceTree = "<group>"; };
|
||||
D6D3F4C324FDB6B700EC4A6A /* View+ConditionalModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+ConditionalModifier.swift"; sourceTree = "<group>"; };
|
||||
D6D3FDDF24F41B8400FF50A5 /* ComposeContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeContainerView.swift; sourceTree = "<group>"; };
|
||||
D6D3FDE124F46A8D00FF50A5 /* ComposeUIState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeUIState.swift; sourceTree = "<group>"; };
|
||||
D6D4CC90250D2C3100FCCF8D /* UIAccessibility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIAccessibility.swift; sourceTree = "<group>"; };
|
||||
D6D4CC93250DB86A00FCCF8D /* ComposeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeTests.swift; sourceTree = "<group>"; };
|
||||
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 = "<group>"; };
|
||||
|
@ -667,7 +662,6 @@
|
|||
D6DFC69F242C4CCC00ACC392 /* WeakArray.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WeakArray.swift; sourceTree = "<group>"; };
|
||||
D6E0DC8D216EDF1E00369478 /* Previewing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Previewing.swift; sourceTree = "<group>"; };
|
||||
D6E4267625327FB400C02E1C /* ComposeAutocompleteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeAutocompleteView.swift; sourceTree = "<group>"; };
|
||||
D6E426802532814100C02E1C /* MaybeLazyStack.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MaybeLazyStack.swift; sourceTree = "<group>"; };
|
||||
D6E4269C2532A3E100C02E1C /* FuzzyMatcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FuzzyMatcher.swift; sourceTree = "<group>"; };
|
||||
D6E426AC25334DA500C02E1C /* FuzzyMatcherTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FuzzyMatcherTests.swift; sourceTree = "<group>"; };
|
||||
D6E426B225337C7000C02E1C /* CustomEmojiImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomEmojiImageView.swift; sourceTree = "<group>"; };
|
||||
|
@ -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 */,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -27,7 +27,6 @@ class ComposeHostingController: UIHostingController<ComposeContainerView> {
|
|||
|
||||
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<ComposeContainerView> {
|
|||
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<ComposeContainerView> {
|
|||
}
|
||||
|
||||
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<ComposeContainerView> {
|
|||
|
||||
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<ComposeContainerView> {
|
|||
} 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<ComposeContainerView> {
|
|||
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<ComposeContainerView> {
|
|||
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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ class LargeImageShrinkAnimationController: NSObject, UIViewControllerAnimatedTra
|
|||
return
|
||||
}
|
||||
|
||||
if UIAccessibility.prefersCrossFadeTransitionsBackwardsCompat && !transitionContext.isInteractive {
|
||||
if UIAccessibility.prefersCrossFadeTransitions && !transitionContext.isInteractive {
|
||||
animateCrossFadeTransition(using: transitionContext)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -17,7 +17,7 @@ struct AdvancedPrefsView : View {
|
|||
automationSection
|
||||
cachingSection
|
||||
}
|
||||
.insetOrGroupedListStyle()
|
||||
.listStyle(InsetGroupedListStyle())
|
||||
.navigationBarTitle(Text("Advanced"))
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ struct AppearancePrefsView : View {
|
|||
accountsSection
|
||||
postsSection
|
||||
}
|
||||
.insetOrGroupedListStyle()
|
||||
.listStyle(InsetGroupedListStyle())
|
||||
.navigationBarTitle(Text("Appearance"))
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ struct BehaviorPrefsView: View {
|
|||
linksSection
|
||||
contentWarningsSection
|
||||
}
|
||||
.insetOrGroupedListStyle()
|
||||
.listStyle(InsetGroupedListStyle())
|
||||
.navigationBarTitle(Text("Behavior"))
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ struct ComposingPrefsView: View {
|
|||
composingSection
|
||||
replyingSection
|
||||
}
|
||||
.insetOrGroupedListStyle()
|
||||
.listStyle(InsetGroupedListStyle())
|
||||
.navigationBarTitle("Composing")
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ struct MediaPrefsView: View {
|
|||
List {
|
||||
viewingSection
|
||||
}
|
||||
.insetOrGroupedListStyle()
|
||||
.listStyle(InsetGroupedListStyle())
|
||||
.navigationBarTitle("Media")
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ struct WellnessPrefsView: View {
|
|||
notificationsMode
|
||||
grayscaleImages
|
||||
}
|
||||
.insetOrGroupedListStyle()
|
||||
.listStyle(InsetGroupedListStyle())
|
||||
.navigationBarTitle(Text("Digital Wellness"))
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
|
||||
import UIKit
|
||||
|
||||
@available(iOS 13.4, *)
|
||||
class TrackpadScrollGestureRecognizer: UIPanGestureRecognizer {
|
||||
|
||||
override init(target: Any?, action: Selector?) {
|
||||
|
|
|
@ -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?) {
|
||||
|
|
|
@ -24,18 +24,11 @@ struct AccountDisplayNameLabel<Account: AccountProtocol>: 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)
|
||||
|
|
|
@ -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) {
|
||||
}
|
||||
|
||||
}
|
|
@ -1,59 +0,0 @@
|
|||
//
|
||||
// MaybeLazyStack.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 10/10/20.
|
||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct MaybeLazyVStack<Content: View>: 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<Content: View>: 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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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)
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18121" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17124"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18091"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
|
@ -58,9 +57,6 @@
|
|||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="image" keyPath="image" value="ellipsis" catalog="system"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
<connections>
|
||||
<action selector="morePressed:" destination="iN0-l3-epB" eventType="touchUpInside" id="Td6-rw-Xvr"/>
|
||||
</connections>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="u4P-3i-gEq">
|
||||
<rect key="frame" x="16" y="262" width="398" height="600"/>
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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])
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue