Compare commits
5 Commits
5f9fe505d5
...
bd49683e13
Author | SHA1 | Date |
---|---|---|
Shadowfacts | bd49683e13 | |
Shadowfacts | c22945b1e7 | |
Shadowfacts | 0a16a2e261 | |
Shadowfacts | b95819cada | |
Shadowfacts | dc1ea1bed9 |
|
@ -70,6 +70,7 @@ class AssetCollectionViewController: UICollectionViewController {
|
||||||
|
|
||||||
collectionView.alwaysBounceVertical = true
|
collectionView.alwaysBounceVertical = true
|
||||||
collectionView.allowsMultipleSelection = true
|
collectionView.allowsMultipleSelection = true
|
||||||
|
collectionView.allowsSelection = true
|
||||||
|
|
||||||
collectionView.register(UINib(nibName: "AssetCollectionViewCell", bundle: .main), forCellWithReuseIdentifier: reuseIdentifier)
|
collectionView.register(UINib(nibName: "AssetCollectionViewCell", bundle: .main), forCellWithReuseIdentifier: reuseIdentifier)
|
||||||
collectionView.register(UINib(nibName: "ShowCameraCollectionViewCell", bundle: .main), forCellWithReuseIdentifier: cameraReuseIdentifier)
|
collectionView.register(UINib(nibName: "ShowCameraCollectionViewCell", bundle: .main), forCellWithReuseIdentifier: cameraReuseIdentifier)
|
||||||
|
@ -98,8 +99,6 @@ class AssetCollectionViewController: UICollectionViewController {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
setEditing(true, animated: false)
|
|
||||||
|
|
||||||
updateItemsSelectedCount()
|
updateItemsSelectedCount()
|
||||||
|
|
||||||
if let singleFingerPanGesture = collectionView.gestureRecognizers?.first(where: {
|
if let singleFingerPanGesture = collectionView.gestureRecognizers?.first(where: {
|
||||||
|
|
|
@ -249,9 +249,9 @@ extension ComposeHostingController: ComposeUIStateDelegate {
|
||||||
if #available(iOS 15.0, *) {
|
if #available(iOS 15.0, *) {
|
||||||
let picker = AssetPickerViewController()
|
let picker = AssetPickerViewController()
|
||||||
picker.assetPickerDelegate = self
|
picker.assetPickerDelegate = self
|
||||||
picker.modalPresentationStyle = .popover
|
picker.modalPresentationStyle = .pageSheet
|
||||||
picker.overrideUserInterfaceStyle = .dark
|
picker.overrideUserInterfaceStyle = .dark
|
||||||
let sheet = picker.popoverPresentationController!.adaptiveSheetPresentationController
|
let sheet = picker.sheetPresentationController!
|
||||||
sheet.detents = [.medium(), .large()]
|
sheet.detents = [.medium(), .large()]
|
||||||
sheet.prefersEdgeAttachedInCompactHeight = true
|
sheet.prefersEdgeAttachedInCompactHeight = true
|
||||||
self.present(picker, animated: true)
|
self.present(picker, animated: true)
|
||||||
|
|
|
@ -91,8 +91,8 @@ class ProfileViewController: UIPageViewController {
|
||||||
addKeyCommand(MenuController.nextSubTabCommand)
|
addKeyCommand(MenuController.nextSubTabCommand)
|
||||||
|
|
||||||
accountUpdater = mastodonController.persistentContainer.accountSubject
|
accountUpdater = mastodonController.persistentContainer.accountSubject
|
||||||
.filter { [weak self] in $0 == self?.accountID }
|
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
|
.filter { [weak self] in $0 == self?.accountID }
|
||||||
.sink { [weak self] (_) in self?.updateAccountUI() }
|
.sink { [weak self] (_) in self?.updateAccountUI() }
|
||||||
|
|
||||||
loadAccount()
|
loadAccount()
|
||||||
|
|
|
@ -42,10 +42,12 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
guard let persistentContainer = mastodonController?.persistentContainer else { return }
|
guard let persistentContainer = mastodonController?.persistentContainer,
|
||||||
|
let dataSource = dataSource else { return }
|
||||||
// decrement reference counts of any statuses we still have
|
// decrement reference counts of any statuses we still have
|
||||||
// if the app is currently being quit, this will not affect the persisted data because
|
// if the app is currently being quit, this will not affect the persisted data because
|
||||||
// the persistent container would already have been saved in SceneDelegate.sceneDidEnterBackground(_:)
|
// the persistent container would already have been saved in SceneDelegate.sceneDidEnterBackground(_:)
|
||||||
|
// todo: remove the whole reference count system
|
||||||
for case let .status(id: id, state: _) in dataSource.snapshot().itemIdentifiers {
|
for case let .status(id: id, state: _) in dataSource.snapshot().itemIdentifiers {
|
||||||
persistentContainer.status(for: id)?.decrementReferenceCount()
|
persistentContainer.status(for: id)?.decrementReferenceCount()
|
||||||
}
|
}
|
||||||
|
@ -107,8 +109,8 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
|
||||||
|
|
||||||
self.mastodonController.persistentContainer.addAll(statuses: statuses) {
|
self.mastodonController.persistentContainer.addAll(statuses: statuses) {
|
||||||
var snapshot = Snapshot()
|
var snapshot = Snapshot()
|
||||||
snapshot.appendSections([.statuses])
|
snapshot.appendSections([.statuses, .footer])
|
||||||
snapshot.appendItems(statuses.map { .status(id: $0.id, state: .unknown) })
|
snapshot.appendItems(statuses.map { .status(id: $0.id, state: .unknown) }, toSection: .statuses)
|
||||||
completion(.success(snapshot))
|
completion(.success(snapshot))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,13 +124,12 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
|
||||||
}
|
}
|
||||||
|
|
||||||
guard !Preferences.shared.disableInfiniteScrolling || didConfirmLoadMore else {
|
guard !Preferences.shared.disableInfiniteScrolling || didConfirmLoadMore else {
|
||||||
guard !currentSnapshot.sectionIdentifiers.contains(.footer) || !currentSnapshot.itemIdentifiers(inSection: .footer).contains(.confirmLoadMore) else {
|
guard !currentSnapshot.itemIdentifiers(inSection: .footer).contains(.confirmLoadMore) else {
|
||||||
// todo: need something more accurate than "success"/"failure"
|
// todo: need something more accurate than "success"/"failure"
|
||||||
completion(.success(currentSnapshot))
|
completion(.success(currentSnapshot))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var snapshot = currentSnapshot
|
var snapshot = currentSnapshot
|
||||||
snapshot.appendSections([.footer])
|
|
||||||
snapshot.appendItems([.confirmLoadMore], toSection: .footer)
|
snapshot.appendItems([.confirmLoadMore], toSection: .footer)
|
||||||
self.dataSource.apply(snapshot)
|
self.dataSource.apply(snapshot)
|
||||||
completion(.success(snapshot))
|
completion(.success(snapshot))
|
||||||
|
@ -148,7 +149,7 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
|
||||||
self.mastodonController.persistentContainer.addAll(statuses: statuses) {
|
self.mastodonController.persistentContainer.addAll(statuses: statuses) {
|
||||||
var snapshot = currentSnapshot
|
var snapshot = currentSnapshot
|
||||||
snapshot.appendItems(statuses.map { .status(id: $0.id, state: .unknown) }, toSection: .statuses)
|
snapshot.appendItems(statuses.map { .status(id: $0.id, state: .unknown) }, toSection: .statuses)
|
||||||
snapshot.deleteSections([.footer])
|
snapshot.deleteItems([.confirmLoadMore])
|
||||||
completion(.success(snapshot))
|
completion(.success(snapshot))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,7 +156,8 @@ class DiffableTimelineLikeTableViewController<Section: Hashable & CaseIterable,
|
||||||
// this assumes that indexPathsForVisibleRows is always in order
|
// this assumes that indexPathsForVisibleRows is always in order
|
||||||
lastLastVisibleRow = tableView.indexPathsForVisibleRows?.last
|
lastLastVisibleRow = tableView.indexPathsForVisibleRows?.last
|
||||||
|
|
||||||
if indexPath.section == tableView.numberOfSections - 1,
|
let orderedContentSections = dataSource.snapshot().sectionIdentifiers.filter { timelineContentSections().contains($0) }
|
||||||
|
if indexPath.section == orderedContentSections.count - 1,
|
||||||
indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 {
|
indexPath.row == tableView.numberOfRows(inSection: indexPath.section) - 1 {
|
||||||
|
|
||||||
loadOlder()
|
loadOlder()
|
||||||
|
|
|
@ -164,7 +164,9 @@ class AttachmentView: UIImageView, GIFAnimatable {
|
||||||
let attachmentURL = attachment.url
|
let attachmentURL = attachment.url
|
||||||
attachmentRequest = ImageCache.attachments.get(attachmentURL) { [weak self] (data, _) in
|
attachmentRequest = ImageCache.attachments.get(attachmentURL) { [weak self] (data, _) in
|
||||||
guard let self = self, let data = data else { return }
|
guard let self = self, let data = data else { return }
|
||||||
|
DispatchQueue.main.async {
|
||||||
self.attachmentRequest = nil
|
self.attachmentRequest = nil
|
||||||
|
}
|
||||||
if self.attachment.url.pathExtension == "gif" {
|
if self.attachment.url.pathExtension == "gif" {
|
||||||
self.source = .gifData(attachmentURL, data)
|
self.source = .gifData(attachmentURL, data)
|
||||||
if self.autoplayGifs {
|
if self.autoplayGifs {
|
||||||
|
|
|
@ -80,14 +80,14 @@ class ProfileHeaderView: UIView {
|
||||||
cancellables = []
|
cancellables = []
|
||||||
|
|
||||||
mastodonController.persistentContainer.accountSubject
|
mastodonController.persistentContainer.accountSubject
|
||||||
.filter { [weak self] in $0 == self?.accountID }
|
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
|
.filter { [weak self] in $0 == self?.accountID }
|
||||||
.sink { [weak self] in self?.updateUI(for: $0) }
|
.sink { [weak self] in self?.updateUI(for: $0) }
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
|
|
||||||
mastodonController.persistentContainer.relationshipSubject
|
mastodonController.persistentContainer.relationshipSubject
|
||||||
.filter { [weak self] in $0 == self?.accountID }
|
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
|
.filter { [weak self] in $0 == self?.accountID }
|
||||||
.sink { [weak self] (_) in self?.updateRelationship() }
|
.sink { [weak self] (_) in self?.updateRelationship() }
|
||||||
.store(in: &cancellables)
|
.store(in: &cancellables)
|
||||||
}
|
}
|
||||||
|
@ -203,11 +203,14 @@ class ProfileHeaderView: UIView {
|
||||||
let image = image,
|
let image = image,
|
||||||
self.accountID == accountID,
|
self.accountID == accountID,
|
||||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: avatarURL, image: image) else {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self?.avatarRequest = nil
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.avatarRequest = nil
|
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
self.avatarRequest = nil
|
||||||
self.avatarImageView.image = transformedImage
|
self.avatarImageView.image = transformedImage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,11 +220,14 @@ class ProfileHeaderView: UIView {
|
||||||
let image = image,
|
let image = image,
|
||||||
self.accountID == accountID,
|
self.accountID == accountID,
|
||||||
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: header, image: image) else {
|
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: header, image: image) else {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self?.headerRequest = nil
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.headerRequest = nil
|
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
|
self.headerRequest = nil
|
||||||
self.headerImageView.image = transformedImage
|
self.headerImageView.image = transformedImage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,8 +106,8 @@ class BaseStatusTableViewCell: UITableViewCell, MenuPreviewProvider {
|
||||||
open func createObserversIfNecessary() {
|
open func createObserversIfNecessary() {
|
||||||
if statusUpdater == nil {
|
if statusUpdater == nil {
|
||||||
statusUpdater = mastodonController.persistentContainer.statusSubject
|
statusUpdater = mastodonController.persistentContainer.statusSubject
|
||||||
.filter { [unowned self] in $0 == self.statusID }
|
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
|
.filter { [unowned self] in $0 == self.statusID }
|
||||||
.sink { [unowned self] in
|
.sink { [unowned self] in
|
||||||
if let mastodonController = mastodonController,
|
if let mastodonController = mastodonController,
|
||||||
let status = mastodonController.persistentContainer.status(for: $0) {
|
let status = mastodonController.persistentContainer.status(for: $0) {
|
||||||
|
@ -118,8 +118,8 @@ class BaseStatusTableViewCell: UITableViewCell, MenuPreviewProvider {
|
||||||
|
|
||||||
if accountUpdater == nil {
|
if accountUpdater == nil {
|
||||||
accountUpdater = mastodonController.persistentContainer.accountSubject
|
accountUpdater = mastodonController.persistentContainer.accountSubject
|
||||||
.filter { [unowned self] in $0 == self.accountID }
|
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
|
.filter { [unowned self] in $0 == self.accountID }
|
||||||
.sink { [unowned self] in
|
.sink { [unowned self] in
|
||||||
if let mastodonController = mastodonController,
|
if let mastodonController = mastodonController,
|
||||||
let account = mastodonController.persistentContainer.account(for: $0) {
|
let account = mastodonController.persistentContainer.account(for: $0) {
|
||||||
|
|
|
@ -59,8 +59,8 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
|
||||||
|
|
||||||
if rebloggerAccountUpdater == nil {
|
if rebloggerAccountUpdater == nil {
|
||||||
rebloggerAccountUpdater = mastodonController.persistentContainer.accountSubject
|
rebloggerAccountUpdater = mastodonController.persistentContainer.accountSubject
|
||||||
.filter { [unowned self] in $0 == self.rebloggerID }
|
|
||||||
.receive(on: DispatchQueue.main)
|
.receive(on: DispatchQueue.main)
|
||||||
|
.filter { [unowned self] in $0 == self.rebloggerID }
|
||||||
.sink { [unowned self] in
|
.sink { [unowned self] in
|
||||||
if let mastodonController = self.mastodonController,
|
if let mastodonController = self.mastodonController,
|
||||||
let reblogger = mastodonController.persistentContainer.account(for: $0) {
|
let reblogger = mastodonController.persistentContainer.account(for: $0) {
|
||||||
|
|
Loading…
Reference in New Issue