Compare commits

..

No commits in common. "130da9d4ccca5559cf196014ebab626d832a62f5" and "aa2d333f4a3be23f50d6254c5d3ad5a56d4b371c" have entirely different histories.

12 changed files with 35 additions and 129 deletions

View File

@ -17,39 +17,21 @@ class ComposeSceneDelegate: UIResponder, UIWindowSceneDelegate {
return return
} }
guard LocalData.shared.onboardingComplete else {
UIApplication.shared.requestSceneSessionDestruction(session, options: nil, errorHandler: nil)
return
}
let account: LocalData.UserAccountInfo let account: LocalData.UserAccountInfo
let controller: MastodonController
let draft: Draft? let draft: Draft?
if let activity = connectionOptions.userActivities.first ?? session.stateRestorationActivity { if let activity = connectionOptions.userActivities.first ?? session.stateRestorationActivity,
if let activityAccount = UserActivityManager.getAccount(from: activity) { let activityAccount = UserActivityManager.getAccount(from: activity) {
account = activityAccount account = activityAccount
} else { draft = UserActivityManager.getDraft(from: activity)
// todo: this potentially changes the account for the draft, should show the same warning to user as in the drafts selection screen
account = LocalData.shared.getMostRecentAccount()!
}
controller = MastodonController.getForAccount(account)
if let activityDraft = UserActivityManager.getDraft(from: activity) {
draft = activityDraft
} else if let mentioning = activity.userInfo?["mentioning"] as? String {
draft = controller.createDraft(inReplyToID: nil, mentioningAcct: mentioning)
} else {
draft = nil
}
} else { } else {
account = LocalData.shared.getMostRecentAccount()! account = LocalData.shared.getMostRecentAccount()!
controller = MastodonController.getForAccount(account)
draft = nil draft = nil
} }
let controller = MastodonController.getForAccount(account)
session.mastodonController = controller session.mastodonController = controller
controller.getOwnAccount() controller.getOwnAccount()
controller.getOwnInstance() controller.getOwnInstance()

View File

@ -51,14 +51,8 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
} }
var dismissInteractionController: LargeImageInteractionController? var dismissInteractionController: LargeImageInteractionController?
var isInteractivelyAnimatingDismissal: Bool = false {
didSet {
setNeedsStatusBarAppearanceUpdate()
}
}
override var prefersStatusBarHidden: Bool { override var prefersStatusBarHidden: Bool {
return !isInteractivelyAnimatingDismissal return true
} }
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .none return .none

View File

@ -132,30 +132,6 @@ class ConversationTableViewController: EnhancedTableViewController {
visibilityBarButtonItem = UIBarButtonItem(image: initialImage, style: .plain, target: self, action: #selector(toggleVisibilityButtonPressed)) visibilityBarButtonItem = UIBarButtonItem(image: initialImage, style: .plain, target: self, action: #selector(toggleVisibilityButtonPressed))
navigationItem.rightBarButtonItem = visibilityBarButtonItem navigationItem.rightBarButtonItem = visibilityBarButtonItem
loadMainStatus()
}
private func loadMainStatus() {
if let mainStatus = mastodonController.persistentContainer.status(for: mainStatusID) {
self.mainStatusLoaded(mainStatus)
} else {
let request = Client.getStatus(id: mainStatusID)
mastodonController.run(request) { (response) in
switch response {
case let .success(status, _):
let viewContext = self.mastodonController.persistentContainer.viewContext
self.mastodonController.persistentContainer.addOrUpdate(status: status, incrementReferenceCount: false, context: viewContext) { (statusMO) in
self.mainStatusLoaded(statusMO)
}
case .failure(_):
fatalError()
}
}
}
}
private func mainStatusLoaded(_ mainStatus: StatusMO) {
let mainStatusItem = Item.status(id: mainStatusID, state: mainStatusState) let mainStatusItem = Item.status(id: mainStatusID, state: mainStatusState)
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>() var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
@ -163,10 +139,12 @@ class ConversationTableViewController: EnhancedTableViewController {
snapshot.appendItems([mainStatusItem], toSection: .statuses) snapshot.appendItems([mainStatusItem], toSection: .statuses)
dataSource.apply(snapshot, animatingDifferences: false) dataSource.apply(snapshot, animatingDifferences: false)
guard let mainStatus = self.mastodonController.persistentContainer.status(for: self.mainStatusID) else {
fatalError("Missing cached status \(self.mainStatusID)")
}
let mainStatusInReplyToID = mainStatus.inReplyToID let mainStatusInReplyToID = mainStatus.inReplyToID
mainStatus.incrementReferenceCount() mainStatus.incrementReferenceCount()
// todo: it would be nice to cache these contexts
let request = Status.getContext(mainStatusID) let request = Status.getContext(mainStatusID)
mastodonController.run(request) { response in mastodonController.run(request) { response in
guard case let .success(context, _) = response else { fatalError() } guard case let .success(context, _) = response else { fatalError() }

View File

@ -51,14 +51,8 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma
private var prevZoomScale: CGFloat? private var prevZoomScale: CGFloat?
private var isGrayscale = false private var isGrayscale = false
var isInteractivelyAnimatingDismissal: Bool = false {
didSet {
setNeedsStatusBarAppearanceUpdate()
}
}
override var prefersStatusBarHidden: Bool { override var prefersStatusBarHidden: Bool {
return !isInteractivelyAnimatingDismissal return true
} }
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .none return .none

View File

@ -43,14 +43,8 @@ class LoadingLargeImageViewController: UIViewController, LargeImageAnimatableVie
var animationGifData: Data? { largeImageVC?.animationGifData } var animationGifData: Data? { largeImageVC?.animationGifData }
var dismissInteractionController: LargeImageInteractionController? var dismissInteractionController: LargeImageInteractionController?
var isInteractivelyAnimatingDismissal: Bool = false {
didSet {
setNeedsStatusBarAppearanceUpdate()
}
}
override var prefersStatusBarHidden: Bool { override var prefersStatusBarHidden: Bool {
return !isInteractivelyAnimatingDismissal return true
} }
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation { override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
return .none return .none

View File

@ -15,7 +15,6 @@ protocol LargeImageAnimatableViewController: UIViewController {
var animationImage: UIImage? { get } var animationImage: UIImage? { get }
var animationGifData: Data? { get } var animationGifData: Data? { get }
var dismissInteractionController: LargeImageInteractionController? { get } var dismissInteractionController: LargeImageInteractionController? { get }
var isInteractivelyAnimatingDismissal: Bool { get set }
} }
extension LargeImageAnimatableViewController { extension LargeImageAnimatableViewController {
@ -75,7 +74,7 @@ class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTra
toVC.largeImageController?.contentView.isHidden = true toVC.largeImageController?.contentView.isHidden = true
toVC.largeImageController?.setControlsVisible(false, animated: false) toVC.largeImageController?.setControlsVisible(false, animated: false)
var finalFrameSize = finalVCFrame.inset(by: toVC.view.safeAreaInsets).size var finalFrameSize = finalVCFrame.inset(by: fromVC.view.safeAreaInsets).size
let newWidth = finalFrameSize.width / image.size.width let newWidth = finalFrameSize.width / image.size.width
let newHeight = finalFrameSize.height / image.size.height let newHeight = finalFrameSize.height / image.size.height
if newHeight < newWidth { if newHeight < newWidth {

View File

@ -14,9 +14,9 @@ class LargeImageInteractionController: UIPercentDrivenInteractiveTransition {
var direction: CGFloat? var direction: CGFloat?
var shouldCompleteTransition = false var shouldCompleteTransition = false
private weak var viewController: LargeImageAnimatableViewController! private weak var viewController: UIViewController!
init(viewController: LargeImageAnimatableViewController) { init(viewController: UIViewController) {
super.init() super.init()
self.viewController = viewController self.viewController = viewController
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handleGesture(_:))) let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handleGesture(_:)))
@ -42,7 +42,6 @@ class LargeImageInteractionController: UIPercentDrivenInteractiveTransition {
viewController.dismiss(animated: true) viewController.dismiss(animated: true)
case .changed: case .changed:
shouldCompleteTransition = progress > 0.5 || velocity > 1000 shouldCompleteTransition = progress > 0.5 || velocity > 1000
viewController.isInteractivelyAnimatingDismissal = progress > 0.1
update(progress) update(progress)
case .cancelled: case .cancelled:
inProgress = false inProgress = false
@ -60,9 +59,4 @@ class LargeImageInteractionController: UIPercentDrivenInteractiveTransition {
} }
} }
override func cancel() {
super.cancel()
viewController.isInteractivelyAnimatingDismissal = false
}
} }

View File

@ -353,18 +353,11 @@ fileprivate extension MainSidebarViewController.Item {
extension MainSplitViewController: TuskerRootViewController { extension MainSplitViewController: TuskerRootViewController {
@objc func presentCompose() { @objc func presentCompose() {
if #available(iOS 15.0, *), 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
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: compose, options: options, errorHandler: nil)
} else {
let vc = ComposeHostingController(mastodonController: mastodonController) let vc = ComposeHostingController(mastodonController: mastodonController)
let nav = EnhancedNavigationViewController(rootViewController: vc) let nav = EnhancedNavigationViewController(rootViewController: vc)
nav.presentationController?.delegate = vc nav.presentationController?.delegate = vc
present(nav, animated: true) present(nav, animated: true)
} }
}
func select(tab: MainTabBarViewController.Tab) { func select(tab: MainTabBarViewController.Tab) {
if traitCollection.horizontalSizeClass == .compact { if traitCollection.horizontalSizeClass == .compact {

View File

@ -212,18 +212,11 @@ extension MainTabBarViewController: FastAccountSwitcherViewControllerDelegate {
extension MainTabBarViewController: TuskerRootViewController { extension MainTabBarViewController: TuskerRootViewController {
@objc func presentCompose() { @objc func presentCompose() {
if #available(iOS 15.0, *), 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
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: compose, options: options, errorHandler: nil)
} else {
let vc = ComposeHostingController(mastodonController: mastodonController) let vc = ComposeHostingController(mastodonController: mastodonController)
let nav = EnhancedNavigationViewController(rootViewController: vc) let nav = EnhancedNavigationViewController(rootViewController: vc)
nav.presentationController?.delegate = vc nav.presentationController?.delegate = vc
present(nav, animated: true) present(nav, animated: true)
} }
}
func select(tab: Tab) { func select(tab: Tab) {
if tab == .compose { if tab == .compose {

View File

@ -70,7 +70,6 @@ class UserActivityManager {
// TODO: check not currently showing compose screen // TODO: check not currently showing compose screen
let mentioning = activity.userInfo?["mentioning"] as? String let mentioning = activity.userInfo?["mentioning"] as? String
let draft = mastodonController.createDraft(mentioningAcct: mentioning) let draft = mastodonController.createDraft(mentioningAcct: mentioning)
// todo: this shouldn't use self.mastodonController, it should get the right one based on the userInfo accountID
let composeVC = ComposeHostingController(draft: draft, mastodonController: mastodonController) let composeVC = ComposeHostingController(draft: draft, mastodonController: mastodonController)
present(UINavigationController(rootViewController: composeVC)) present(UINavigationController(rootViewController: composeVC))
} }

View File

@ -89,22 +89,15 @@ extension TuskerNavigationDelegate {
} }
func compose(editing draft: Draft) { func compose(editing draft: Draft) {
if #available(iOS 15.0, *), 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
UIApplication.shared.requestSceneSessionActivation(nil, userActivity: compose, options: options, errorHandler: nil)
} else {
let compose = ComposeHostingController(draft: draft, mastodonController: apiController) let compose = ComposeHostingController(draft: draft, mastodonController: apiController)
let nav = UINavigationController(rootViewController: compose)
nav.presentationController?.delegate = compose let vc = UINavigationController(rootViewController: compose)
present(nav, animated: true) vc.presentationController?.delegate = compose
} present(vc, animated: true)
} }
func compose(inReplyToID: String? = nil, mentioningAcct: String? = nil) { func compose(inReplyToID: String? = nil, mentioningAcct: String? = nil) {
let draft = apiController.createDraft(inReplyToID: inReplyToID, mentioningAcct: mentioningAcct) let draft = apiController.createDraft(inReplyToID: inReplyToID, mentioningAcct: mentioningAcct)
DraftsManager.shared.add(draft)
compose(editing: draft) compose(editing: draft)
} }

View File

@ -1,9 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19115.2" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/> <device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19107.4"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
@ -39,7 +38,7 @@
</constraints> </constraints>
</imageView> </imageView>
<stackView opaque="NO" contentMode="scaleToFill" verticalCompressionResistancePriority="751" axis="vertical" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="gIY-Wp-RSk"> <stackView opaque="NO" contentMode="scaleToFill" verticalCompressionResistancePriority="751" axis="vertical" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="gIY-Wp-RSk">
<rect key="frame" x="58" y="0.0" width="277" height="173.5"/> <rect key="frame" x="58" y="0.0" width="277" height="169.5"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="3Sm-P0-ySf"> <stackView opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="3Sm-P0-ySf">
<rect key="frame" x="0.0" y="0.0" width="277" height="20.5"/> <rect key="frame" x="0.0" y="0.0" width="277" height="20.5"/>
@ -133,19 +132,13 @@
<rect key="frame" x="0.0" y="169.5" width="277" height="0.0"/> <rect key="frame" x="0.0" y="169.5" width="277" height="0.0"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/> <color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view> </view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="1" verticalCompressionResistancePriority="1" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oFl-rC-EEN">
<rect key="frame" x="0.0" y="173.5" width="277" height="0.0"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews> </subviews>
</stackView> </stackView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="oie-wK-IpU"> <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="oie-wK-IpU">
<rect key="frame" x="0.0" y="54" width="50" height="22"/> <rect key="frame" x="0.0" y="54" width="50" height="22"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="bubble.left.and.bubble.right" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="KdQ-Zn-IhD"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="bubble.left.and.bubble.right" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="KdQ-Zn-IhD">
<rect key="frame" x="0.0" y="0.0" width="25.5" height="21.5"/> <rect key="frame" x="0.0" y="1" width="25.5" height="21.5"/>
<color key="tintColor" systemColor="secondaryLabelColor"/> <color key="tintColor" systemColor="secondaryLabelColor"/>
<accessibility key="accessibilityConfiguration" label="Is a reply"/> <accessibility key="accessibilityConfiguration" label="Is a reply"/>
<constraints> <constraints>
@ -225,7 +218,7 @@
<constraint firstItem="gIY-Wp-RSk" firstAttribute="leading" secondItem="QMP-j2-HLn" secondAttribute="trailing" constant="8" id="0Tm-v7-Ts4"/> <constraint firstItem="gIY-Wp-RSk" firstAttribute="leading" secondItem="QMP-j2-HLn" secondAttribute="trailing" constant="8" id="0Tm-v7-Ts4"/>
<constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="QMP-j2-HLn" secondAttribute="bottom" constant="8" id="2Ao-Gj-fY3"/> <constraint firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="QMP-j2-HLn" secondAttribute="bottom" constant="8" id="2Ao-Gj-fY3"/>
<constraint firstItem="TUP-Nz-5Yh" firstAttribute="trailing" secondItem="ve3-Y1-NQH" secondAttribute="trailingMargin" id="3l0-tE-Ak1"/> <constraint firstItem="TUP-Nz-5Yh" firstAttribute="trailing" secondItem="ve3-Y1-NQH" secondAttribute="trailingMargin" id="3l0-tE-Ak1"/>
<constraint firstItem="TUP-Nz-5Yh" firstAttribute="top" secondItem="gIY-Wp-RSk" secondAttribute="bottom" constant="-4" id="4KL-a3-qyf"/> <constraint firstItem="TUP-Nz-5Yh" firstAttribute="top" secondItem="gIY-Wp-RSk" secondAttribute="bottom" id="4KL-a3-qyf"/>
<constraint firstItem="oie-wK-IpU" firstAttribute="top" secondItem="QMP-j2-HLn" secondAttribute="bottom" constant="4" id="7Mp-WS-FhY"/> <constraint firstItem="oie-wK-IpU" firstAttribute="top" secondItem="QMP-j2-HLn" secondAttribute="bottom" constant="4" id="7Mp-WS-FhY"/>
<constraint firstItem="TUP-Nz-5Yh" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="oie-wK-IpU" secondAttribute="bottom" id="7Xp-Sa-Rfk"/> <constraint firstItem="TUP-Nz-5Yh" firstAttribute="bottom" relation="greaterThanOrEqual" secondItem="oie-wK-IpU" secondAttribute="bottom" id="7Xp-Sa-Rfk"/>
<constraint firstItem="QMP-j2-HLn" firstAttribute="top" secondItem="ve3-Y1-NQH" secondAttribute="top" id="PC4-Bi-QXm"/> <constraint firstItem="QMP-j2-HLn" firstAttribute="top" secondItem="ve3-Y1-NQH" secondAttribute="top" id="PC4-Bi-QXm"/>
@ -283,7 +276,7 @@
<image name="ellipsis" catalog="system" width="128" height="37"/> <image name="ellipsis" catalog="system" width="128" height="37"/>
<image name="globe" catalog="system" width="128" height="121"/> <image name="globe" catalog="system" width="128" height="121"/>
<image name="pin.fill" catalog="system" width="119" height="128"/> <image name="pin.fill" catalog="system" width="119" height="128"/>
<image name="repeat" catalog="system" width="128" height="98"/> <image name="repeat" catalog="system" width="128" height="99"/>
<image name="star.fill" catalog="system" width="128" height="116"/> <image name="star.fill" catalog="system" width="128" height="116"/>
<systemColor name="labelColor"> <systemColor name="labelColor">
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>