Add multi-window drag and drop to all the things
This commit is contained in:
parent
522c9b2b03
commit
30297c2390
|
@ -82,6 +82,7 @@
|
|||
D62275A624F1C81800B82A16 /* ComposeReplyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62275A524F1C81800B82A16 /* ComposeReplyView.swift */; };
|
||||
D62275A824F1CA2800B82A16 /* ComposeReplyContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62275A724F1CA2800B82A16 /* ComposeReplyContentView.swift */; };
|
||||
D62275AA24F1E01C00B82A16 /* ComposeTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D62275A924F1E01C00B82A16 /* ComposeTextView.swift */; };
|
||||
D625E4822588262A0074BB2B /* DraggableTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D625E4812588262A0074BB2B /* DraggableTableViewCell.swift */; };
|
||||
D626493323BD751600612E6E /* ShowCameraCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D626493123BD751600612E6E /* ShowCameraCollectionViewCell.xib */; };
|
||||
D626493523BD94CE00612E6E /* CompositionAttachmentData.swift in Sources */ = {isa = PBXBuildFile; fileRef = D626493423BD94CE00612E6E /* CompositionAttachmentData.swift */; };
|
||||
D626493823C0FD0000612E6E /* AllPhotosTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D626493623C0FD0000612E6E /* AllPhotosTableViewCell.swift */; };
|
||||
|
@ -437,6 +438,7 @@
|
|||
D62275A524F1C81800B82A16 /* ComposeReplyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeReplyView.swift; sourceTree = "<group>"; };
|
||||
D62275A724F1CA2800B82A16 /* ComposeReplyContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeReplyContentView.swift; sourceTree = "<group>"; };
|
||||
D62275A924F1E01C00B82A16 /* ComposeTextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeTextView.swift; sourceTree = "<group>"; };
|
||||
D625E4812588262A0074BB2B /* DraggableTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggableTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D626493123BD751600612E6E /* ShowCameraCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ShowCameraCollectionViewCell.xib; sourceTree = "<group>"; };
|
||||
D626493423BD94CE00612E6E /* CompositionAttachmentData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CompositionAttachmentData.swift; sourceTree = "<group>"; };
|
||||
D626493623C0FD0000612E6E /* AllPhotosTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllPhotosTableViewCell.swift; sourceTree = "<group>"; };
|
||||
|
@ -1382,6 +1384,7 @@
|
|||
D65C6BF425478A9C00A6E89C /* BackgroundableViewController.swift */,
|
||||
D6B81F3B2560365300F6E31D /* RefreshableViewController.swift */,
|
||||
D65234C8256189D0001AF9CF /* TimelineLikeTableViewController.swift */,
|
||||
D625E4812588262A0074BB2B /* DraggableTableViewCell.swift */,
|
||||
);
|
||||
path = Utilities;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1895,6 +1898,7 @@
|
|||
D6A3BC802321B7E600FD64D5 /* FollowNotificationGroupTableViewCell.swift in Sources */,
|
||||
D627944D23A9A03D00D38C68 /* ListTimelineViewController.swift in Sources */,
|
||||
D6945C3823AC739F005C403C /* InstanceTimelineViewController.swift in Sources */,
|
||||
D625E4822588262A0074BB2B /* DraggableTableViewCell.swift in Sources */,
|
||||
D68E525B24A3D77E0054355A /* TuskerRootViewController.swift in Sources */,
|
||||
D62D2422217AA7E1005076CC /* UserActivityManager.swift in Sources */,
|
||||
D6CA6A92249FAD8900AD45C1 /* AudioSessionHelper.swift in Sources */,
|
||||
|
|
|
@ -27,6 +27,8 @@ class BookmarksTableViewController: EnhancedTableViewController {
|
|||
|
||||
super.init(style: .plain)
|
||||
|
||||
dragEnabled = true
|
||||
|
||||
title = NSLocalizedString("Bookmarks", comment: "bookmarks screen title")
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,8 @@ class ConversationTableViewController: EnhancedTableViewController {
|
|||
self.mastodonController = mastodonController
|
||||
|
||||
super.init(style: .plain)
|
||||
|
||||
dragEnabled = true
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
|
|
|
@ -45,6 +45,8 @@ class DraftsTableViewController: UITableViewController {
|
|||
|
||||
tableView.register(UINib(nibName: "DraftTableViewCell", bundle: nil), forCellReuseIdentifier: "draftCell")
|
||||
|
||||
tableView.dragDelegate = self
|
||||
|
||||
drafts = DraftsManager.shared.sorted.filter { (draft) in
|
||||
draft.accountID == account.id && draft != excludedDraft
|
||||
}
|
||||
|
@ -116,3 +118,12 @@ class DraftsTableViewController: UITableViewController {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
extension DraftsTableViewController: UITableViewDragDelegate {
|
||||
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
|
||||
let draft = self.draft(for: indexPath)
|
||||
let activity = UserActivityManager.editDraftActivity(id: draft.id, accountID: account.id)
|
||||
let provider = NSItemProvider(object: activity)
|
||||
return [UIDragItem(itemProvider: provider)]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ class ExploreViewController: EnhancedTableViewController {
|
|||
|
||||
super.init(style: .insetGrouped)
|
||||
|
||||
dragEnabled = true
|
||||
|
||||
title = NSLocalizedString("Explore", comment: "explore tab title")
|
||||
tabBarItem.image = UIImage(systemName: "magnifyingglass")
|
||||
}
|
||||
|
@ -401,3 +403,35 @@ extension ExploreViewController: InstanceTimelineViewControllerDelegate {
|
|||
dismiss(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
extension ExploreViewController {
|
||||
override func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
|
||||
guard let item = dataSource.itemIdentifier(for: indexPath),
|
||||
let accountID = mastodonController.accountInfo?.id else {
|
||||
return []
|
||||
}
|
||||
let provider: NSItemProvider
|
||||
switch item {
|
||||
case .bookmarks:
|
||||
provider = NSItemProvider(object: UserActivityManager.bookmarksActivity())
|
||||
case let .list(list):
|
||||
guard let activity = UserActivityManager.showTimelineActivity(timeline: .list(id: list.id), accountID: accountID) else { return [] }
|
||||
provider = NSItemProvider(object: activity)
|
||||
case let .savedHashtag(hashtag):
|
||||
provider = NSItemProvider(object: hashtag.url as NSURL)
|
||||
if let activity = UserActivityManager.showTimelineActivity(timeline: .tag(hashtag: hashtag.name), accountID: accountID) {
|
||||
provider.registerObject(activity, visibility: .all)
|
||||
}
|
||||
case let .savedInstance(url):
|
||||
provider = NSItemProvider(object: url as NSURL)
|
||||
// todo: should dragging public timelines into new windows be supported?
|
||||
case .addList:
|
||||
return []
|
||||
case .addSavedHashtag:
|
||||
return []
|
||||
case .findInstance:
|
||||
return []
|
||||
}
|
||||
return [UIDragItem(itemProvider: provider)]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,8 @@ class NotificationsTableViewController: TimelineLikeTableViewController<Notifica
|
|||
self.mastodonController = mastodonController
|
||||
|
||||
super.init()
|
||||
|
||||
dragEnabled = true
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
|
|
|
@ -28,6 +28,8 @@ class ProfileStatusesViewController: TimelineLikeTableViewController<TimelineEnt
|
|||
self.mastodonController = mastodonController
|
||||
|
||||
super.init()
|
||||
|
||||
dragEnabled = true
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
|
|
|
@ -49,6 +49,8 @@ class SearchResultsViewController: EnhancedTableViewController {
|
|||
|
||||
super.init(style: .grouped)
|
||||
|
||||
dragEnabled = true
|
||||
|
||||
title = NSLocalizedString("Search", comment: "search screen title")
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,8 @@ class StatusActionAccountListTableViewController: EnhancedTableViewController {
|
|||
|
||||
super.init(style: .grouped)
|
||||
|
||||
dragEnabled = true
|
||||
|
||||
switch actionType {
|
||||
case .favorite:
|
||||
title = NSLocalizedString("Favorited By", comment: "status favorited by accounts list title")
|
||||
|
|
|
@ -25,6 +25,8 @@ class TimelineTableViewController: TimelineLikeTableViewController<TimelineEntry
|
|||
|
||||
super.init()
|
||||
|
||||
dragEnabled = true
|
||||
|
||||
title = timeline.title
|
||||
tabBarItem.image = timeline.tabBarImage
|
||||
|
||||
|
@ -53,8 +55,6 @@ class TimelineTableViewController: TimelineLikeTableViewController<TimelineEntry
|
|||
super.viewDidLoad()
|
||||
|
||||
tableView.register(UINib(nibName: "TimelineStatusTableViewCell", bundle: .main), forCellReuseIdentifier: "statusCell")
|
||||
|
||||
tableView.dragDelegate = self
|
||||
}
|
||||
|
||||
override class func refreshCommandTitle() -> String {
|
||||
|
@ -175,18 +175,3 @@ extension TimelineTableViewController: UITableViewDataSourcePrefetching {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension TimelineTableViewController: UITableViewDragDelegate {
|
||||
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
|
||||
let id = item(for: indexPath).id
|
||||
guard let status = mastodonController.persistentContainer.status(for: id),
|
||||
let accountId = mastodonController.accountInfo?.id else {
|
||||
return []
|
||||
}
|
||||
let activity = UserActivityManager.showConversationActivity(mainStatusID: id, accountID: accountId)
|
||||
let itemProvider = NSItemProvider(object: status.url! as NSURL)
|
||||
itemProvider.registerObject(activity, visibility: .all)
|
||||
let dragItem = UIDragItem(itemProvider: itemProvider)
|
||||
return [dragItem]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// DraggableTableViewCell.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 12/14/20.
|
||||
// Copyright © 2020 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
protocol DraggableTableViewCell: UITableViewCell {
|
||||
func dragItemsForBeginning(session: UIDragSession) -> [UIDragItem]
|
||||
}
|
|
@ -16,6 +16,16 @@ class EnhancedTableViewController: UITableViewController {
|
|||
private var prevScrollViewContentOffset: CGPoint?
|
||||
private(set) var scrollViewDirection: CGFloat = 0
|
||||
|
||||
var dragEnabled = false
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
if dragEnabled {
|
||||
tableView.dragDelegate = self
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Scroll View Delegate
|
||||
|
||||
override func scrollViewShouldScrollToTop(_ scrollView: UIScrollView) -> Bool {
|
||||
|
@ -96,6 +106,15 @@ extension EnhancedTableViewController {
|
|||
|
||||
}
|
||||
|
||||
extension EnhancedTableViewController: UITableViewDragDelegate {
|
||||
func tableView(_ tableView: UITableView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] {
|
||||
guard let cell = tableView.cellForRow(at: indexPath) as? DraggableTableViewCell else {
|
||||
return []
|
||||
}
|
||||
return cell.dragItemsForBeginning(session: session)
|
||||
}
|
||||
}
|
||||
|
||||
extension EnhancedTableViewController: TabBarScrollableViewController {
|
||||
func tabBarScrollToTop() {
|
||||
if scrollViewShouldScrollToTop(tableView) {
|
||||
|
|
|
@ -24,11 +24,6 @@ class TimelineLikeTableViewController<Item>: EnhancedTableViewController, Refres
|
|||
init() {
|
||||
super.init(style: .plain)
|
||||
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
self.refreshControl = UIRefreshControl()
|
||||
self.refreshControl!.addTarget(self, action: #selector(refresh), for: .valueChanged)
|
||||
#endif
|
||||
|
||||
addKeyCommand(MenuController.refreshCommand(discoverabilityTitle: Self.refreshCommandTitle()))
|
||||
}
|
||||
|
||||
|
@ -46,6 +41,11 @@ class TimelineLikeTableViewController<Item>: EnhancedTableViewController, Refres
|
|||
tableView.rowHeight = UITableView.automaticDimension
|
||||
tableView.estimatedRowHeight = 140
|
||||
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
self.refreshControl = UIRefreshControl()
|
||||
self.refreshControl!.addTarget(self, action: #selector(refresh), for: .valueChanged)
|
||||
#endif
|
||||
|
||||
if let prefetchSource = self as? UITableViewDataSourcePrefetching {
|
||||
tableView.prefetchDataSource = prefetchSource
|
||||
}
|
||||
|
|
|
@ -109,3 +109,16 @@ extension AccountTableViewCell: MenuPreviewProvider {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension AccountTableViewCell: DraggableTableViewCell {
|
||||
func dragItemsForBeginning(session: UIDragSession) -> [UIDragItem] {
|
||||
guard let account = mastodonController.persistentContainer.account(for: accountID),
|
||||
let currentAccountID = mastodonController.accountInfo?.id else {
|
||||
return []
|
||||
}
|
||||
let provider = NSItemProvider(object: account.url as NSURL)
|
||||
let activity = UserActivityManager.showProfileActivity(id: account.id, accountID: currentAccountID)
|
||||
provider.registerObject(activity, visibility: .all)
|
||||
return [UIDragItem(itemProvider: provider)]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,3 +219,16 @@ extension FollowNotificationGroupTableViewCell: MenuPreviewProvider {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
extension FollowNotificationGroupTableViewCell: DraggableTableViewCell {
|
||||
func dragItemsForBeginning(session: UIDragSession) -> [UIDragItem] {
|
||||
guard group.notifications.count == 1 else {
|
||||
return []
|
||||
}
|
||||
let notification = group.notifications[0]
|
||||
let provider = NSItemProvider(object: notification.account.url as NSURL)
|
||||
let activity = UserActivityManager.showProfileActivity(id: notification.account.id, accountID: mastodonController.accountInfo!.id)
|
||||
provider.registerObject(activity, visibility: .all)
|
||||
return [UIDragItem(itemProvider: provider)]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -181,3 +181,12 @@ extension FollowRequestNotificationTableViewCell: MenuPreviewProvider {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
extension FollowRequestNotificationTableViewCell: DraggableTableViewCell {
|
||||
func dragItemsForBeginning(session: UIDragSession) -> [UIDragItem] {
|
||||
let provider = NSItemProvider(object: account.url as NSURL)
|
||||
let activity = UserActivityManager.showProfileActivity(id: account.id, accountID: mastodonController.accountInfo!.id)
|
||||
provider.registerObject(activity, visibility: .all)
|
||||
return [UIDragItem(itemProvider: provider)]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -483,10 +483,13 @@ extension BaseStatusTableViewCell: MenuPreviewProvider {
|
|||
|
||||
extension BaseStatusTableViewCell: UIDragInteractionDelegate {
|
||||
func dragInteraction(_ interaction: UIDragInteraction, itemsForBeginning session: UIDragSession) -> [UIDragItem] {
|
||||
guard let currentAccountID = mastodonController.accountInfo?.id else {
|
||||
guard let currentAccountID = mastodonController.accountInfo?.id,
|
||||
let account = mastodonController.persistentContainer.account(for: accountID) else {
|
||||
return []
|
||||
}
|
||||
let provider = NSItemProvider(object: UserActivityManager.showProfileActivity(id: accountID, accountID: currentAccountID))
|
||||
let provider = NSItemProvider(object: account.url as NSURL)
|
||||
let activity = UserActivityManager.showProfileActivity(id: accountID, accountID: currentAccountID)
|
||||
provider.registerObject(activity, visibility: .all)
|
||||
return [UIDragItem(itemProvider: provider)]
|
||||
}
|
||||
}
|
||||
|
|
|
@ -296,3 +296,16 @@ extension TimelineStatusTableViewCell: TableViewSwipeActionProvider {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
extension TimelineStatusTableViewCell: DraggableTableViewCell {
|
||||
func dragItemsForBeginning(session: UIDragSession) -> [UIDragItem] {
|
||||
guard let status = mastodonController.persistentContainer.status(for: statusID),
|
||||
let accountID = mastodonController.accountInfo?.id else {
|
||||
return []
|
||||
}
|
||||
let provider = NSItemProvider(object: status.url! as NSURL)
|
||||
let activity = UserActivityManager.showConversationActivity(mainStatusID: status.id, accountID: accountID)
|
||||
provider.registerObject(activity, visibility: .all)
|
||||
return [UIDragItem(itemProvider: provider)]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue