Compare commits
4 Commits
aa2d333f4a
...
130da9d4cc
Author | SHA1 | Date |
---|---|---|
Shadowfacts | 130da9d4cc | |
Shadowfacts | 472b9aa5e2 | |
Shadowfacts | 3413dff8f9 | |
Shadowfacts | 66e8fce488 |
|
@ -17,21 +17,39 @@ class ComposeSceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
return
|
||||
}
|
||||
|
||||
guard LocalData.shared.onboardingComplete else {
|
||||
UIApplication.shared.requestSceneSessionDestruction(session, options: nil, errorHandler: nil)
|
||||
return
|
||||
}
|
||||
|
||||
let account: LocalData.UserAccountInfo
|
||||
let controller: MastodonController
|
||||
let draft: Draft?
|
||||
|
||||
if let activity = connectionOptions.userActivities.first ?? session.stateRestorationActivity,
|
||||
let activityAccount = UserActivityManager.getAccount(from: activity) {
|
||||
account = activityAccount
|
||||
draft = UserActivityManager.getDraft(from: activity)
|
||||
if let activity = connectionOptions.userActivities.first ?? session.stateRestorationActivity {
|
||||
if let activityAccount = UserActivityManager.getAccount(from: activity) {
|
||||
account = activityAccount
|
||||
} else {
|
||||
// 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 {
|
||||
account = LocalData.shared.getMostRecentAccount()!
|
||||
controller = MastodonController.getForAccount(account)
|
||||
draft = nil
|
||||
}
|
||||
|
||||
let controller = MastodonController.getForAccount(account)
|
||||
session.mastodonController = controller
|
||||
|
||||
controller.getOwnAccount()
|
||||
controller.getOwnInstance()
|
||||
|
||||
|
|
|
@ -51,8 +51,14 @@ class GalleryViewController: UIPageViewController, UIPageViewControllerDataSourc
|
|||
}
|
||||
var dismissInteractionController: LargeImageInteractionController?
|
||||
|
||||
var isInteractivelyAnimatingDismissal: Bool = false {
|
||||
didSet {
|
||||
setNeedsStatusBarAppearanceUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
override var prefersStatusBarHidden: Bool {
|
||||
return true
|
||||
return !isInteractivelyAnimatingDismissal
|
||||
}
|
||||
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
|
||||
return .none
|
||||
|
|
|
@ -131,7 +131,31 @@ class ConversationTableViewController: EnhancedTableViewController {
|
|||
let initialImage = showStatusesAutomatically ? ConversationTableViewController.hidePostsImage : ConversationTableViewController.showPostsImage
|
||||
visibilityBarButtonItem = UIBarButtonItem(image: initialImage, style: .plain, target: self, action: #selector(toggleVisibilityButtonPressed))
|
||||
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)
|
||||
|
||||
var snapshot = NSDiffableDataSourceSnapshot<Section, Item>()
|
||||
|
@ -139,12 +163,10 @@ class ConversationTableViewController: EnhancedTableViewController {
|
|||
snapshot.appendItems([mainStatusItem], toSection: .statuses)
|
||||
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
|
||||
mainStatus.incrementReferenceCount()
|
||||
|
||||
// todo: it would be nice to cache these contexts
|
||||
let request = Status.getContext(mainStatusID)
|
||||
mastodonController.run(request) { response in
|
||||
guard case let .success(context, _) = response else { fatalError() }
|
||||
|
|
|
@ -51,8 +51,14 @@ class LargeImageViewController: UIViewController, UIScrollViewDelegate, LargeIma
|
|||
private var prevZoomScale: CGFloat?
|
||||
private var isGrayscale = false
|
||||
|
||||
var isInteractivelyAnimatingDismissal: Bool = false {
|
||||
didSet {
|
||||
setNeedsStatusBarAppearanceUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
override var prefersStatusBarHidden: Bool {
|
||||
return true
|
||||
return !isInteractivelyAnimatingDismissal
|
||||
}
|
||||
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
|
||||
return .none
|
||||
|
|
|
@ -43,8 +43,14 @@ class LoadingLargeImageViewController: UIViewController, LargeImageAnimatableVie
|
|||
var animationGifData: Data? { largeImageVC?.animationGifData }
|
||||
var dismissInteractionController: LargeImageInteractionController?
|
||||
|
||||
var isInteractivelyAnimatingDismissal: Bool = false {
|
||||
didSet {
|
||||
setNeedsStatusBarAppearanceUpdate()
|
||||
}
|
||||
}
|
||||
|
||||
override var prefersStatusBarHidden: Bool {
|
||||
return true
|
||||
return !isInteractivelyAnimatingDismissal
|
||||
}
|
||||
override var preferredStatusBarUpdateAnimation: UIStatusBarAnimation {
|
||||
return .none
|
||||
|
|
|
@ -15,6 +15,7 @@ protocol LargeImageAnimatableViewController: UIViewController {
|
|||
var animationImage: UIImage? { get }
|
||||
var animationGifData: Data? { get }
|
||||
var dismissInteractionController: LargeImageInteractionController? { get }
|
||||
var isInteractivelyAnimatingDismissal: Bool { get set }
|
||||
}
|
||||
|
||||
extension LargeImageAnimatableViewController {
|
||||
|
@ -74,7 +75,7 @@ class LargeImageExpandAnimationController: NSObject, UIViewControllerAnimatedTra
|
|||
toVC.largeImageController?.contentView.isHidden = true
|
||||
toVC.largeImageController?.setControlsVisible(false, animated: false)
|
||||
|
||||
var finalFrameSize = finalVCFrame.inset(by: fromVC.view.safeAreaInsets).size
|
||||
var finalFrameSize = finalVCFrame.inset(by: toVC.view.safeAreaInsets).size
|
||||
let newWidth = finalFrameSize.width / image.size.width
|
||||
let newHeight = finalFrameSize.height / image.size.height
|
||||
if newHeight < newWidth {
|
||||
|
|
|
@ -14,9 +14,9 @@ class LargeImageInteractionController: UIPercentDrivenInteractiveTransition {
|
|||
var direction: CGFloat?
|
||||
|
||||
var shouldCompleteTransition = false
|
||||
private weak var viewController: UIViewController!
|
||||
private weak var viewController: LargeImageAnimatableViewController!
|
||||
|
||||
init(viewController: UIViewController) {
|
||||
init(viewController: LargeImageAnimatableViewController) {
|
||||
super.init()
|
||||
self.viewController = viewController
|
||||
let panRecognizer = UIPanGestureRecognizer(target: self, action: #selector(handleGesture(_:)))
|
||||
|
@ -42,6 +42,7 @@ class LargeImageInteractionController: UIPercentDrivenInteractiveTransition {
|
|||
viewController.dismiss(animated: true)
|
||||
case .changed:
|
||||
shouldCompleteTransition = progress > 0.5 || velocity > 1000
|
||||
viewController.isInteractivelyAnimatingDismissal = progress > 0.1
|
||||
update(progress)
|
||||
case .cancelled:
|
||||
inProgress = false
|
||||
|
@ -59,4 +60,9 @@ class LargeImageInteractionController: UIPercentDrivenInteractiveTransition {
|
|||
}
|
||||
}
|
||||
|
||||
override func cancel() {
|
||||
super.cancel()
|
||||
viewController.isInteractivelyAnimatingDismissal = false
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -353,10 +353,17 @@ fileprivate extension MainSidebarViewController.Item {
|
|||
|
||||
extension MainSplitViewController: TuskerRootViewController {
|
||||
@objc func presentCompose() {
|
||||
let vc = ComposeHostingController(mastodonController: mastodonController)
|
||||
let nav = EnhancedNavigationViewController(rootViewController: vc)
|
||||
nav.presentationController?.delegate = vc
|
||||
present(nav, animated: true)
|
||||
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 nav = EnhancedNavigationViewController(rootViewController: vc)
|
||||
nav.presentationController?.delegate = vc
|
||||
present(nav, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
func select(tab: MainTabBarViewController.Tab) {
|
||||
|
|
|
@ -212,10 +212,17 @@ extension MainTabBarViewController: FastAccountSwitcherViewControllerDelegate {
|
|||
|
||||
extension MainTabBarViewController: TuskerRootViewController {
|
||||
@objc func presentCompose() {
|
||||
let vc = ComposeHostingController(mastodonController: mastodonController)
|
||||
let nav = EnhancedNavigationViewController(rootViewController: vc)
|
||||
nav.presentationController?.delegate = vc
|
||||
present(nav, animated: true)
|
||||
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 nav = EnhancedNavigationViewController(rootViewController: vc)
|
||||
nav.presentationController?.delegate = vc
|
||||
present(nav, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
func select(tab: Tab) {
|
||||
|
|
|
@ -70,6 +70,7 @@ class UserActivityManager {
|
|||
// TODO: check not currently showing compose screen
|
||||
let mentioning = activity.userInfo?["mentioning"] as? String
|
||||
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)
|
||||
present(UINavigationController(rootViewController: composeVC))
|
||||
}
|
||||
|
|
|
@ -89,15 +89,22 @@ extension TuskerNavigationDelegate {
|
|||
}
|
||||
|
||||
func compose(editing draft: Draft) {
|
||||
let compose = ComposeHostingController(draft: draft, mastodonController: apiController)
|
||||
|
||||
let vc = UINavigationController(rootViewController: compose)
|
||||
vc.presentationController?.delegate = compose
|
||||
present(vc, animated: true)
|
||||
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 nav = UINavigationController(rootViewController: compose)
|
||||
nav.presentationController?.delegate = compose
|
||||
present(nav, animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
func compose(inReplyToID: String? = nil, mentioningAcct: String? = nil) {
|
||||
let draft = apiController.createDraft(inReplyToID: inReplyToID, mentioningAcct: mentioningAcct)
|
||||
DraftsManager.shared.add(draft)
|
||||
compose(editing: draft)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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">
|
||||
<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">
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19107.4"/>
|
||||
<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"/>
|
||||
|
@ -38,7 +39,7 @@
|
|||
</constraints>
|
||||
</imageView>
|
||||
<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="169.5"/>
|
||||
<rect key="frame" x="58" y="0.0" width="277" height="173.5"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
|
@ -132,13 +133,19 @@
|
|||
<rect key="frame" x="0.0" y="169.5" width="277" height="0.0"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
||||
</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>
|
||||
</stackView>
|
||||
<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"/>
|
||||
<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">
|
||||
<rect key="frame" x="0.0" y="1" width="25.5" height="21.5"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="25.5" height="21.5"/>
|
||||
<color key="tintColor" systemColor="secondaryLabelColor"/>
|
||||
<accessibility key="accessibilityConfiguration" label="Is a reply"/>
|
||||
<constraints>
|
||||
|
@ -218,7 +225,7 @@
|
|||
<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 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" id="4KL-a3-qyf"/>
|
||||
<constraint firstItem="TUP-Nz-5Yh" firstAttribute="top" secondItem="gIY-Wp-RSk" secondAttribute="bottom" constant="-4" 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="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"/>
|
||||
|
@ -276,7 +283,7 @@
|
|||
<image name="ellipsis" catalog="system" width="128" height="37"/>
|
||||
<image name="globe" catalog="system" width="128" height="121"/>
|
||||
<image name="pin.fill" catalog="system" width="119" height="128"/>
|
||||
<image name="repeat" catalog="system" width="128" height="99"/>
|
||||
<image name="repeat" catalog="system" width="128" height="98"/>
|
||||
<image name="star.fill" catalog="system" width="128" height="116"/>
|
||||
<systemColor name="labelColor">
|
||||
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
|
|
Loading…
Reference in New Issue