Compare commits

...

8 Commits

8 changed files with 70 additions and 19 deletions

View File

@ -1,5 +1,16 @@
# Changelog # Changelog
## 2021.1 (21)
This is a quick follow-up to the previous build with fixes for a couple major crashes. Unfortunately, due to a bug in iOS 14, the Disable Infinite Scrolling preference now requires the iOS 15 beta to use. It may return in a future build if I can find a workaround, but it's disabled in the meantime.
Features/Improvements:
- iPadOS 15: Add Open in New Window context menu action to sidebar items
Bugfixes:
- Fix crash when editing accounts in a list
- Fix crash when refreshing timeline on iOS 14
- Fix(ish) crash when opening collapsed status with Disable Infinite Scrolling active on iOS 15
## 2021.1 (20) ## 2021.1 (20)
This is a big one! In addition to a bunch of fixes for anyone on the iOS 15 beta, there are a couple of big ticket features, including the Open in Tusker action extension and the Disable Infinite Scrolling preference. This is a big one! In addition to a bunch of fixes for anyone on the iOS 15 beta, there are a couple of big ticket features, including the Open in Tusker action extension and the Disable Infinite Scrolling preference.

View File

@ -2577,7 +2577,7 @@
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements; CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20; CURRENT_PROJECT_VERSION = 21;
DEVELOPMENT_TEAM = V4WK9KR9U2; DEVELOPMENT_TEAM = V4WK9KR9U2;
INFOPLIST_FILE = Tusker/Info.plist; INFOPLIST_FILE = Tusker/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.1; IPHONEOS_DEPLOYMENT_TARGET = 14.1;
@ -2610,7 +2610,7 @@
CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements; CODE_SIGN_ENTITLEMENTS = Tusker/Tusker.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 20; CURRENT_PROJECT_VERSION = 21;
DEVELOPMENT_TEAM = V4WK9KR9U2; DEVELOPMENT_TEAM = V4WK9KR9U2;
INFOPLIST_FILE = Tusker/Info.plist; INFOPLIST_FILE = Tusker/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.1; IPHONEOS_DEPLOYMENT_TARGET = 14.1;
@ -2719,7 +2719,7 @@
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements; CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 19; CURRENT_PROJECT_VERSION = 21;
DEVELOPMENT_TEAM = V4WK9KR9U2; DEVELOPMENT_TEAM = V4WK9KR9U2;
INFOPLIST_FILE = OpenInTusker/Info.plist; INFOPLIST_FILE = OpenInTusker/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.1; IPHONEOS_DEPLOYMENT_TARGET = 14.1;
@ -2746,7 +2746,7 @@
CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements; CODE_SIGN_ENTITLEMENTS = OpenInTusker/OpenInTusker.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer"; CODE_SIGN_IDENTITY = "iPhone Developer";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 19; CURRENT_PROJECT_VERSION = 21;
DEVELOPMENT_TEAM = V4WK9KR9U2; DEVELOPMENT_TEAM = V4WK9KR9U2;
INFOPLIST_FILE = OpenInTusker/Info.plist; INFOPLIST_FILE = OpenInTusker/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 14.1; IPHONEOS_DEPLOYMENT_TARGET = 14.1;

View File

@ -2,7 +2,7 @@
"object": { "object": {
"pins": [ "pins": [
{ {
"package": "PLCrashReporter", "package": "plcrashreporter",
"repositoryURL": "https://github.com/microsoft/plcrashreporter", "repositoryURL": "https://github.com/microsoft/plcrashreporter",
"state": { "state": {
"branch": null, "branch": null,

View File

@ -80,15 +80,15 @@ class EditListAccountsViewController: EnhancedTableViewController {
self.nextRange = pagination?.older self.nextRange = pagination?.older
self.mastodonController.persistentContainer.addAll(accounts: accounts) self.mastodonController.persistentContainer.addAll(accounts: accounts) {
var snapshot = self.dataSource.snapshot()
var snapshot = self.dataSource.snapshot() snapshot.deleteSections([.accounts])
snapshot.deleteSections([.accounts]) snapshot.appendSections([.accounts])
snapshot.appendSections([.accounts]) snapshot.appendItems(accounts.map { .account(id: $0.id) })
snapshot.appendItems(accounts.map { .account(id: $0.id) })
DispatchQueue.main.async {
DispatchQueue.main.async { self.dataSource.apply(snapshot)
self.dataSource.apply(snapshot) }
} }
} }
} }

View File

@ -462,6 +462,21 @@ extension MainSidebarViewController: UICollectionViewDelegate {
return true return true
} }
} }
func collectionView(_ collectionView: UICollectionView, contextMenuConfigurationForItemAt indexPath: IndexPath, point: CGPoint) -> UIContextMenuConfiguration? {
guard #available(iOS 15.0, *),
let item = dataSource.itemIdentifier(for: indexPath),
let activity = userActivityForItem(item) else {
return nil
}
return UIContextMenuConfiguration(identifier: nil, previewProvider: nil) { (_) in
return UIMenu(children: [
UIWindowScene.ActivationAction({ action in
return UIWindowScene.ActivationConfiguration(userActivity: activity)
}),
])
}
}
} }
extension MainSidebarViewController: UICollectionViewDragDelegate { extension MainSidebarViewController: UICollectionViewDragDelegate {

View File

@ -16,7 +16,9 @@ struct WellnessPrefsView: View {
showFavAndReblogCount showFavAndReblogCount
notificationsMode notificationsMode
grayscaleImages grayscaleImages
disableInfiniteScrolling if #available(iOS 15.0, *) {
disableInfiniteScrolling
}
} }
.listStyle(InsetGroupedListStyle()) .listStyle(InsetGroupedListStyle())
.navigationBarTitle(Text("Digital Wellness")) .navigationBarTitle(Text("Digital Wellness"))

View File

@ -74,6 +74,7 @@ class ProfileViewController: UIPageViewController {
self.composeDirectMentioning() self.composeDirectMentioning()
}) })
]) ])
composeButton.isEnabled = mastodonController.loggedIn
navigationItem.rightBarButtonItem = composeButton navigationItem.rightBarButtonItem = composeButton
headerView = ProfileHeaderView.create() headerView = ProfileHeaderView.create()

View File

@ -123,7 +123,8 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
return return
} }
guard !Preferences.shared.disableInfiniteScrolling || didConfirmLoadMore else { if #available(iOS 15.0, *),
Preferences.shared.disableInfiniteScrolling && !didConfirmLoadMore {
guard !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))
@ -177,11 +178,11 @@ class TimelineTableViewController: DiffableTimelineLikeTableViewController<Timel
self.mastodonController.persistentContainer.addAll(statuses: statuses) { self.mastodonController.persistentContainer.addAll(statuses: statuses) {
var snapshot = currentSnapshot var snapshot = currentSnapshot
let identifiers = statuses.map { Item.status(id: $0.id, state: .unknown) } let newIdentifiers = statuses.map { Item.status(id: $0.id, state: .unknown) }
if let first = snapshot.itemIdentifiers(inSection: .statuses).first { if let first = snapshot.itemIdentifiers(inSection: .statuses).first {
snapshot.insertItems(identifiers, beforeItem: first) snapshot.insertItems(newIdentifiers, beforeItem: first)
} else { } else {
snapshot.appendItems(identifiers, toSection: .statuses) snapshot.appendItems(newIdentifiers, toSection: .statuses)
} }
completion(.success(snapshot)) completion(.success(snapshot))
} }
@ -205,6 +206,27 @@ extension TimelineTableViewController {
enum Item: Hashable { enum Item: Hashable {
case status(id: String, state: StatusState) case status(id: String, state: StatusState)
case confirmLoadMore case confirmLoadMore
static func ==(lhs: Item, rhs: Item) -> Bool {
switch (lhs, rhs) {
case let (.status(id: a, state: _), .status(id: b, state: _)):
return a == b
case (.confirmLoadMore, .confirmLoadMore):
return true
default:
return false
}
}
func hash(into hasher: inout Hasher) {
switch self {
case let .status(id: id, state: _):
hasher.combine(0)
hasher.combine(id)
case .confirmLoadMore:
hasher.combine(1)
}
}
} }
} }