Compare commits
No commits in common. "18f6445a7cba08c501d1b1c62c348c154cc1441a" and "2e2279ba8c319ea8cf2d075a32d78dce3456061c" have entirely different histories.
18f6445a7c
...
2e2279ba8c
|
@ -1,34 +1,3 @@
|
||||||
## 2024.3
|
|
||||||
This update includes a number of bugfixes and performance improvements. See below for a list of fixes.
|
|
||||||
|
|
||||||
Bugfixes:
|
|
||||||
- Fix an issue displaying rich text in certain cases
|
|
||||||
- Fix crash when video attachment finishes playing
|
|
||||||
- Fix video attachment thumbnails being flipped on Compose screen
|
|
||||||
- Fix profile header images being blurry
|
|
||||||
- Fix crash when opening push notifications in certain circumstances
|
|
||||||
- Fix certain links in profile fields not being tappable
|
|
||||||
- Fix gifv playback pausing audio from other apps
|
|
||||||
- Fix gifv playback being paused when returning from background
|
|
||||||
- Fix badges on gifv attachments not appearing
|
|
||||||
- Fix excessive network traffic when opening profile pages
|
|
||||||
- Fix controls visibility not matching across attachment gallery pages
|
|
||||||
- Fix add hashtag/instance pinned timeline sheet in Customize Timelines dismissing instantly
|
|
||||||
- Fix Dynamic Type not applying to status content
|
|
||||||
- Fix mention/status push notifications not showing CW
|
|
||||||
- Fix sensitive attachment thumbnails being shown in push notifications
|
|
||||||
- Fix profile moved overlay visual and VoiceOver issues
|
|
||||||
- Fix opening Mastodon remote status links
|
|
||||||
- Fix reply author avatar on Compose screen not being pinned to top when scrolling while typing
|
|
||||||
- Pleroma/Akkoma: Fix editing attachment descriptions not working
|
|
||||||
- Pixelfed/Firefish: Fix error loading certain accounts
|
|
||||||
- Pixelfed: Fix error loading relationships and follow/block/etc. actions
|
|
||||||
- iPadOS: Fix pointer interactions throughout the app
|
|
||||||
- iPadOS: Fix multiple close buttons being added in multi-column interface
|
|
||||||
- iPadOS: Fix Cmd+1/etc. removing columns when returning to previous tab
|
|
||||||
- iPadOS: Fix multi-column interface not animating for some actions
|
|
||||||
- iPadOS: Fix selecting search results always adding new column
|
|
||||||
|
|
||||||
## 2024.2
|
## 2024.2
|
||||||
This release introduces push notifications as well as an enhanced multi-column interface on iPadOS!
|
This release introduces push notifications as well as an enhanced multi-column interface on iPadOS!
|
||||||
|
|
||||||
|
|
11
CHANGELOG.md
11
CHANGELOG.md
|
@ -1,16 +1,5 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
## 2024.3 (131)
|
|
||||||
Bugfixes:
|
|
||||||
- Fix Cmd+3 not correctly switching to Explore tab
|
|
||||||
|
|
||||||
## 2024.3 (130)
|
|
||||||
Bugfixes:
|
|
||||||
- Fix reply author avatar on Compose screen not being pinned to top when scrolling while typing
|
|
||||||
- Fix crash when dragging between buttons in reblog confirmation alert
|
|
||||||
- Fix potential crash when displaying search results
|
|
||||||
- Mac: Fix Post button not displaying on Compose screen
|
|
||||||
|
|
||||||
## 2024.3 (129)
|
## 2024.3 (129)
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
- Fix excessive network traffic on profile pages
|
- Fix excessive network traffic on profile pages
|
||||||
|
|
|
@ -333,12 +333,7 @@ public final class ComposeController: ViewController {
|
||||||
}
|
}
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .cancellationAction) { cancelButton }
|
ToolbarItem(placement: .cancellationAction) { cancelButton }
|
||||||
#if targetEnvironment(macCatalyst)
|
|
||||||
ToolbarItem(placement: .topBarTrailing) { draftsButton }
|
|
||||||
ToolbarItem(placement: .confirmationAction) { postButton }
|
ToolbarItem(placement: .confirmationAction) { postButton }
|
||||||
#else
|
|
||||||
ToolbarItem(placement: .confirmationAction) { postOrDraftsButton }
|
|
||||||
#endif
|
|
||||||
#if os(visionOS)
|
#if os(visionOS)
|
||||||
ToolbarItem(placement: .bottomOrnament) {
|
ToolbarItem(placement: .bottomOrnament) {
|
||||||
ControllerView(controller: { controller.toolbarController })
|
ControllerView(controller: { controller.toolbarController })
|
||||||
|
@ -466,26 +461,18 @@ public final class ComposeController: ViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var postOrDraftsButton: some View {
|
|
||||||
if draft.hasContent || draft.editedStatusID != nil || !controller.config.allowSwitchingDrafts {
|
|
||||||
postButton
|
|
||||||
} else {
|
|
||||||
draftsButton
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var draftsButton: some View {
|
|
||||||
Button(action: controller.showDrafts) {
|
|
||||||
Text("Drafts")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private var postButton: some View {
|
private var postButton: some View {
|
||||||
|
if draft.hasContent || draft.editedStatusID != nil || !controller.config.allowSwitchingDrafts {
|
||||||
Button(action: controller.postStatus) {
|
Button(action: controller.postStatus) {
|
||||||
Text(draft.editedStatusID == nil ? "Post" : "Edit")
|
Text(draft.editedStatusID == nil ? "Post" : "Edit")
|
||||||
}
|
}
|
||||||
.keyboardShortcut(.return, modifiers: .command)
|
.keyboardShortcut(.return, modifiers: .command)
|
||||||
.disabled(!controller.postButtonEnabled)
|
.disabled(!controller.postButtonEnabled)
|
||||||
|
} else {
|
||||||
|
Button(action: controller.showDrafts) {
|
||||||
|
Text("Drafts")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
|
|
|
@ -16,8 +16,6 @@ public class DraftsPersistentContainer: NSPersistentContainer {
|
||||||
|
|
||||||
public static let shared = DraftsPersistentContainer()
|
public static let shared = DraftsPersistentContainer()
|
||||||
|
|
||||||
public static var captureError: ((any Error) -> Void)?
|
|
||||||
|
|
||||||
private static let managedObjectModel: NSManagedObjectModel = {
|
private static let managedObjectModel: NSManagedObjectModel = {
|
||||||
let url = Bundle.module.url(forResource: "Drafts", withExtension: "momd")!
|
let url = Bundle.module.url(forResource: "Drafts", withExtension: "momd")!
|
||||||
return NSManagedObjectModel(contentsOf: url)!
|
return NSManagedObjectModel(contentsOf: url)!
|
||||||
|
@ -41,7 +39,6 @@ public class DraftsPersistentContainer: NSPersistentContainer {
|
||||||
|
|
||||||
loadPersistentStores { _, error in
|
loadPersistentStores { _, error in
|
||||||
if let error {
|
if let error {
|
||||||
DraftsPersistentContainer.captureError?(error)
|
|
||||||
fatalError("Loading persistent store: \(error)")
|
fatalError("Loading persistent store: \(error)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ extension TextViewCaretScrolling {
|
||||||
|
|
||||||
let animator = UIViewPropertyAnimator(duration: 0.2, curve: .easeInOut) {
|
let animator = UIViewPropertyAnimator(duration: 0.2, curve: .easeInOut) {
|
||||||
scrollView.scrollRectToVisible(rectToMakeVisible, animated: false)
|
scrollView.scrollRectToVisible(rectToMakeVisible, animated: false)
|
||||||
scrollView.layoutIfNeeded()
|
|
||||||
}
|
}
|
||||||
self.caretScrollPositionAnimator = animator
|
self.caretScrollPositionAnimator = animator
|
||||||
animator.startAnimation()
|
animator.startAnimation()
|
||||||
|
|
|
@ -76,15 +76,13 @@ struct ReplyStatusView: View {
|
||||||
// once you scroll past the in-reply-to-content, the bottom of the avatar should be pinned to the bottom of the content
|
// once you scroll past the in-reply-to-content, the bottom of the avatar should be pinned to the bottom of the content
|
||||||
offset = min(offset, maxOffset)
|
offset = min(offset, maxOffset)
|
||||||
|
|
||||||
return AvatarContainerRepresentable(offset: offset) {
|
return AvatarImageView(
|
||||||
AvatarImageView(
|
|
||||||
url: status.account.avatar,
|
url: status.account.avatar,
|
||||||
size: 50,
|
size: 50,
|
||||||
style: controller.config.avatarStyle,
|
style: controller.config.avatarStyle,
|
||||||
fetchAvatar: controller.fetchAvatar
|
fetchAvatar: controller.fetchAvatar
|
||||||
)
|
)
|
||||||
}
|
.offset(x: 0, y: offset)
|
||||||
.frame(width: 50, height: 50)
|
|
||||||
.accessibilityHidden(true)
|
.accessibilityHidden(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,39 +94,3 @@ private struct DisplayNameHeightPrefKey: PreferenceKey {
|
||||||
value = nextValue()
|
value = nextValue()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This whole dance is necessary so that the offset can be animatable from
|
|
||||||
// UIKit animations, like TextViewCaretScrolling.
|
|
||||||
private struct AvatarContainerRepresentable<Content: View>: UIViewControllerRepresentable {
|
|
||||||
let offset: CGFloat
|
|
||||||
@ViewBuilder let content: Content
|
|
||||||
|
|
||||||
func makeUIViewController(context: Context) -> Controller {
|
|
||||||
Controller(host: UIHostingController(rootView: content))
|
|
||||||
}
|
|
||||||
|
|
||||||
func updateUIViewController(_ uiViewController: Controller, context: Context) {
|
|
||||||
uiViewController.host.rootView = content
|
|
||||||
uiViewController.host.view.transform = CGAffineTransform(translationX: 0, y: offset)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This extra layer is necessary because applying a transform to the
|
|
||||||
// representable's VC's view doesn't seem to have an effect.
|
|
||||||
class Controller: UIViewController {
|
|
||||||
let host: UIHostingController<Content>
|
|
||||||
|
|
||||||
init(host: UIHostingController<Content>) {
|
|
||||||
self.host = host
|
|
||||||
super.init(nibName: nil, bundle: nil)
|
|
||||||
addChild(host)
|
|
||||||
host.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
|
|
||||||
view.addSubview(host.view)
|
|
||||||
host.view.frame = view.bounds
|
|
||||||
host.didMove(toParent: self)
|
|
||||||
}
|
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
|
||||||
fatalError("init(coder:) has not been implemented")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -56,9 +56,6 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||||
|
|
||||||
// make sure the persistent container is initialized on the main thread
|
// make sure the persistent container is initialized on the main thread
|
||||||
// otherwise initializing it on the background thread can deadlock with accessing it on the main thread elsewhere
|
// otherwise initializing it on the background thread can deadlock with accessing it on the main thread elsewhere
|
||||||
#if canImport(Sentry)
|
|
||||||
DraftsPersistentContainer.captureError = { SentrySDK.capture(error: $0) }
|
|
||||||
#endif
|
|
||||||
_ = DraftsPersistentContainer.shared
|
_ = DraftsPersistentContainer.shared
|
||||||
|
|
||||||
DispatchQueue.global(qos: .userInitiated).async {
|
DispatchQueue.global(qos: .userInitiated).async {
|
||||||
|
|
|
@ -32,7 +32,7 @@ struct MenuController {
|
||||||
static let sidebarItemKeyCommands: [UIKeyCommand] = [
|
static let sidebarItemKeyCommands: [UIKeyCommand] = [
|
||||||
sidebarCommand(item: .tab(.timelines), command: "1", action: #selector(MainSplitViewController.handleSidebarCommandTimelines)),
|
sidebarCommand(item: .tab(.timelines), command: "1", action: #selector(MainSplitViewController.handleSidebarCommandTimelines)),
|
||||||
sidebarCommand(item: .tab(.notifications), command: "2", action: #selector(MainSplitViewController.handleSidebarCommandNotifications)),
|
sidebarCommand(item: .tab(.notifications), command: "2", action: #selector(MainSplitViewController.handleSidebarCommandNotifications)),
|
||||||
sidebarCommand(item: .tab(.explore), command: "3", action: #selector(MainSplitViewController.handleSidebarCommandExplore)),
|
sidebarCommand(item: .explore, command: "3", action: #selector(MainSplitViewController.handleSidebarCommandExplore)),
|
||||||
sidebarCommand(item: .bookmarks, command: "4", action: #selector(MainSplitViewController.handleSidebarCommandBookmarks)),
|
sidebarCommand(item: .bookmarks, command: "4", action: #selector(MainSplitViewController.handleSidebarCommandBookmarks)),
|
||||||
sidebarCommand(item: .tab(.myProfile), command: "5", action: #selector(MainSplitViewController.handleSidebarCommandMyProfile)),
|
sidebarCommand(item: .tab(.myProfile), command: "5", action: #selector(MainSplitViewController.handleSidebarCommandMyProfile)),
|
||||||
]
|
]
|
||||||
|
|
|
@ -43,7 +43,7 @@ class MainSidebarViewController: UIViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
var exploreTabItems: [Item] {
|
var exploreTabItems: [Item] {
|
||||||
var items: [Item] = [.tab(.explore), .bookmarks, .favorites]
|
var items: [Item] = [.explore, .bookmarks, .favorites]
|
||||||
let snapshot = dataSource.snapshot()
|
let snapshot = dataSource.snapshot()
|
||||||
for case let .list(list) in snapshot.itemIdentifiers(inSection: .lists) {
|
for case let .list(list) in snapshot.itemIdentifiers(inSection: .lists) {
|
||||||
items.append(.list(list))
|
items.append(.list(list))
|
||||||
|
@ -170,7 +170,7 @@ class MainSidebarViewController: UIViewController {
|
||||||
snapshot.appendItems([
|
snapshot.appendItems([
|
||||||
.tab(.timelines),
|
.tab(.timelines),
|
||||||
.tab(.notifications),
|
.tab(.notifications),
|
||||||
.tab(.explore),
|
.explore,
|
||||||
.bookmarks,
|
.bookmarks,
|
||||||
.favorites,
|
.favorites,
|
||||||
.tab(.myProfile)
|
.tab(.myProfile)
|
||||||
|
@ -302,7 +302,7 @@ class MainSidebarViewController: UIViewController {
|
||||||
return UserActivityManager.checkNotificationsActivity(mode: Preferences.shared.defaultNotificationsMode, accountID: id)
|
return UserActivityManager.checkNotificationsActivity(mode: Preferences.shared.defaultNotificationsMode, accountID: id)
|
||||||
case .tab(.compose):
|
case .tab(.compose):
|
||||||
return UserActivityManager.newPostActivity(accountID: id)
|
return UserActivityManager.newPostActivity(accountID: id)
|
||||||
case .tab(.explore):
|
case .explore:
|
||||||
return UserActivityManager.searchActivity(query: nil, accountID: id)
|
return UserActivityManager.searchActivity(query: nil, accountID: id)
|
||||||
case .bookmarks:
|
case .bookmarks:
|
||||||
return UserActivityManager.bookmarksActivity(accountID: id)
|
return UserActivityManager.bookmarksActivity(accountID: id)
|
||||||
|
@ -340,7 +340,7 @@ extension MainSidebarViewController {
|
||||||
}
|
}
|
||||||
enum Item: Hashable {
|
enum Item: Hashable {
|
||||||
case tab(MainTabBarViewController.Tab)
|
case tab(MainTabBarViewController.Tab)
|
||||||
case bookmarks, favorites
|
case explore, bookmarks, favorites
|
||||||
case listsHeader, list(List), addList
|
case listsHeader, list(List), addList
|
||||||
case savedHashtagsHeader, savedHashtag(String), addSavedHashtag
|
case savedHashtagsHeader, savedHashtag(String), addSavedHashtag
|
||||||
case savedInstancesHeader, savedInstance(URL), addSavedInstance
|
case savedInstancesHeader, savedInstance(URL), addSavedInstance
|
||||||
|
@ -349,6 +349,8 @@ extension MainSidebarViewController {
|
||||||
switch self {
|
switch self {
|
||||||
case let .tab(tab):
|
case let .tab(tab):
|
||||||
return tab.title
|
return tab.title
|
||||||
|
case .explore:
|
||||||
|
return "Explore"
|
||||||
case .bookmarks:
|
case .bookmarks:
|
||||||
return "Bookmarks"
|
return "Bookmarks"
|
||||||
case .favorites:
|
case .favorites:
|
||||||
|
@ -378,6 +380,8 @@ extension MainSidebarViewController {
|
||||||
switch self {
|
switch self {
|
||||||
case let .tab(tab):
|
case let .tab(tab):
|
||||||
return tab.imageName
|
return tab.imageName
|
||||||
|
case .explore:
|
||||||
|
return "magnifyingglass"
|
||||||
case .bookmarks:
|
case .bookmarks:
|
||||||
return "bookmark"
|
return "bookmark"
|
||||||
case .favorites:
|
case .favorites:
|
||||||
|
|
|
@ -279,7 +279,7 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
$0.1 > $1.1
|
$0.1 > $1.1
|
||||||
}
|
}
|
||||||
if let mostRecentExploreItem = mostRecentExploreItem?.0,
|
if let mostRecentExploreItem = mostRecentExploreItem?.0,
|
||||||
mostRecentExploreItem != .tab(.explore) {
|
mostRecentExploreItem != .explore {
|
||||||
let exploreNav = tabBarViewController.viewController(for: .explore) as! UINavigationController
|
let exploreNav = tabBarViewController.viewController(for: .explore) as! UINavigationController
|
||||||
// Pop back to root, so we're appending to the Explore VC instead of some other VC
|
// Pop back to root, so we're appending to the Explore VC instead of some other VC
|
||||||
exploreNav.popToRootViewController(animated: false)
|
exploreNav.popToRootViewController(animated: false)
|
||||||
|
@ -292,7 +292,11 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
case nil:
|
case nil:
|
||||||
break
|
break
|
||||||
|
|
||||||
case .tab(.explore):
|
case let .tab(tab):
|
||||||
|
// sidebar items that map 1 <-> 1 can be transferred directly
|
||||||
|
tabBarViewController.select(tab: tab, dismissPresented: false)
|
||||||
|
|
||||||
|
case .explore:
|
||||||
// Search sidebar item maps to the Explore tab with the search controller/results visible
|
// Search sidebar item maps to the Explore tab with the search controller/results visible
|
||||||
// The nav stack can't be copied directly, since the split VC uses a different SearchViewController
|
// The nav stack can't be copied directly, since the split VC uses a different SearchViewController
|
||||||
// so that explore items aren't shown multiple times.
|
// so that explore items aren't shown multiple times.
|
||||||
|
@ -331,14 +335,10 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transfer the navigation stack, dropping the search VC, to keep anything the user has opened
|
// Transfer the navigation stack, dropping the search VC, to keep anything the user has opened
|
||||||
transferNavigationStack(from: .tab(.explore), to: exploreNav, dropFirst: true, append: true)
|
transferNavigationStack(from: .explore, to: exploreNav, dropFirst: true, append: true)
|
||||||
|
|
||||||
tabBarViewController.select(tab: .explore, dismissPresented: false)
|
tabBarViewController.select(tab: .explore, dismissPresented: false)
|
||||||
|
|
||||||
case let .tab(tab):
|
|
||||||
// sidebar items that map 1 <-> 1 can be transferred directly
|
|
||||||
tabBarViewController.select(tab: tab, dismissPresented: false)
|
|
||||||
|
|
||||||
case .bookmarks, .favorites, .list(_), .savedHashtag(_), .savedInstance(_):
|
case .bookmarks, .favorites, .list(_), .savedHashtag(_), .savedInstance(_):
|
||||||
tabBarViewController.select(tab: .explore, dismissPresented: false)
|
tabBarViewController.select(tab: .explore, dismissPresented: false)
|
||||||
// Make sure the Explore VC doesn't show its search bar when it appears, in case the user was previously
|
// Make sure the Explore VC doesn't show its search bar when it appears, in case the user was previously
|
||||||
|
@ -396,9 +396,9 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
// For other items, the 2nd VC in the nav stack determines which sidebar item they map to.
|
// For other items, the 2nd VC in the nav stack determines which sidebar item they map to.
|
||||||
// Search screen has special considerations, all others can be transferred directly.
|
// Search screen has special considerations, all others can be transferred directly.
|
||||||
if tabNavigationStack.count == 1 || ((tabNavigationStack.first as? ExploreViewController)?.searchController?.isActive ?? false) {
|
if tabNavigationStack.count == 1 || ((tabNavigationStack.first as? ExploreViewController)?.searchController?.isActive ?? false) {
|
||||||
exploreItem = .tab(.explore)
|
exploreItem = .explore
|
||||||
// reuse the existing VC, if there is one
|
// reuse the existing VC, if there is one
|
||||||
let searchVC = getOrCreateNavigationStack(item: .tab(.explore)).first! as! InlineTrendsViewController
|
let searchVC = getOrCreateNavigationStack(item: .explore).first! as! InlineTrendsViewController
|
||||||
// load the view so that the search controller is accessible
|
// load the view so that the search controller is accessible
|
||||||
searchVC.loadViewIfNeeded()
|
searchVC.loadViewIfNeeded()
|
||||||
let explore = tabNavigationStack.first as! ExploreViewController
|
let explore = tabNavigationStack.first as! ExploreViewController
|
||||||
|
@ -426,16 +426,16 @@ extension MainSplitViewController: UISplitViewControllerDelegate {
|
||||||
case let instanceVC as InstanceTimelineViewController:
|
case let instanceVC as InstanceTimelineViewController:
|
||||||
exploreItem = .savedInstance(instanceVC.instanceURL)
|
exploreItem = .savedInstance(instanceVC.instanceURL)
|
||||||
case is TrendsViewController:
|
case is TrendsViewController:
|
||||||
exploreItem = .tab(.explore)
|
exploreItem = .explore
|
||||||
// skip transferring the ExploreViewController and TrendsViewController
|
// skip transferring the ExploreViewController and TrendsViewController
|
||||||
skipFirst = 2
|
skipFirst = 2
|
||||||
// prepend the InlineTrendsViewController
|
// prepend the InlineTrendsViewController
|
||||||
toPrepend = getOrCreateNavigationStack(item: .tab(.explore)).first!
|
toPrepend = getOrCreateNavigationStack(item: .explore).first!
|
||||||
default:
|
default:
|
||||||
// transfer the navigation stack prepending, the existing explore VC
|
// transfer the navigation stack prepending, the existing explore VC
|
||||||
// if there was other stuff on the explore stack, it will get discarded
|
// if there was other stuff on the explore stack, it will get discarded
|
||||||
toPrepend = getOrCreateNavigationStack(item: .tab(.explore)).first!
|
toPrepend = getOrCreateNavigationStack(item: .explore).first!
|
||||||
exploreItem = .tab(.explore)
|
exploreItem = .explore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
transferNavigationStack(from: tabNavController, to: exploreItem!, skipFirst: skipFirst, prepend: toPrepend)
|
transferNavigationStack(from: tabNavController, to: exploreItem!, skipFirst: skipFirst, prepend: toPrepend)
|
||||||
|
@ -502,10 +502,10 @@ fileprivate extension MainSidebarViewController.Item {
|
||||||
@MainActor
|
@MainActor
|
||||||
func createRootViewController(_ mastodonController: MastodonController) -> UIViewController? {
|
func createRootViewController(_ mastodonController: MastodonController) -> UIViewController? {
|
||||||
switch self {
|
switch self {
|
||||||
case .tab(.explore):
|
|
||||||
return InlineTrendsViewController(mastodonController: mastodonController)
|
|
||||||
case let .tab(tab):
|
case let .tab(tab):
|
||||||
return tab.createViewController(mastodonController)
|
return tab.createViewController(mastodonController)
|
||||||
|
case .explore:
|
||||||
|
return InlineTrendsViewController(mastodonController: mastodonController)
|
||||||
case .bookmarks:
|
case .bookmarks:
|
||||||
return BookmarksViewController(mastodonController: mastodonController)
|
return BookmarksViewController(mastodonController: mastodonController)
|
||||||
case .favorites:
|
case .favorites:
|
||||||
|
@ -562,7 +562,7 @@ extension MainSplitViewController: TuskerRootViewController {
|
||||||
case .myProfile:
|
case .myProfile:
|
||||||
item = .tab(.myProfile)
|
item = .tab(.myProfile)
|
||||||
case .explore:
|
case .explore:
|
||||||
item = .tab(.explore)
|
item = .explore
|
||||||
case .bookmarks:
|
case .bookmarks:
|
||||||
item = .bookmarks
|
item = .bookmarks
|
||||||
case .list(id: let id):
|
case .list(id: let id):
|
||||||
|
@ -616,8 +616,8 @@ extension MainSplitViewController: TuskerRootViewController {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if sidebar.selectedItem != .tab(.explore) {
|
if sidebar.selectedItem != .explore {
|
||||||
select(newItem: .tab(.explore), oldItem: sidebar.selectedItem)
|
select(newItem: .explore, oldItem: sidebar.selectedItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let searchViewController = secondaryNavController.viewControllers.first as? InlineTrendsViewController else {
|
guard let searchViewController = secondaryNavController.viewControllers.first as? InlineTrendsViewController else {
|
||||||
|
|
|
@ -95,7 +95,7 @@ class NotificationLoadingViewController: UIViewController {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard let navigationController else {
|
guard let navigationController else {
|
||||||
fatalError("Don't know how to show notification VC outside of navigation controller: parent is \(parent?.description ?? "<nil>")")
|
fatalError("Don't know how to show notification VC outside of navigation controller")
|
||||||
}
|
}
|
||||||
navigationController.viewControllers[navigationController.viewControllers.count - 1] = vc
|
navigationController.viewControllers[navigationController.viewControllers.count - 1] = vc
|
||||||
}
|
}
|
||||||
|
|
|
@ -414,7 +414,7 @@ extension SearchResultsViewController {
|
||||||
hasher.combine(id)
|
hasher.combine(id)
|
||||||
case let .hashtag(hashtag):
|
case let .hashtag(hashtag):
|
||||||
hasher.combine("hashtag")
|
hasher.combine("hashtag")
|
||||||
hasher.combine(hashtag.name)
|
hasher.combine(hashtag.url)
|
||||||
case let .status(id, _):
|
case let .status(id, _):
|
||||||
hasher.combine("status")
|
hasher.combine("status")
|
||||||
hasher.combine(id)
|
hasher.combine(id)
|
||||||
|
|
|
@ -320,13 +320,13 @@ class CustomAlertActionsView: UIControl {
|
||||||
actionButtons[currentSelectedActionIndex].backgroundColor = nil
|
actionButtons[currentSelectedActionIndex].backgroundColor = nil
|
||||||
}
|
}
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
if selectedButton != nil {
|
|
||||||
if #available(iOS 17.5, *) {
|
if #available(iOS 17.5, *) {
|
||||||
generator.selectionChanged(at: recognizer.location(in: generator.view))
|
let view = selectedButton!.element
|
||||||
|
let location = convert(CGPoint(x: view.bounds.midX, y: view.bounds.midY), from: view)
|
||||||
|
generator.selectionChanged(at: location)
|
||||||
} else {
|
} else {
|
||||||
generator.selectionChanged()
|
generator.selectionChanged()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if let showPressedMenuWorkItem {
|
if let showPressedMenuWorkItem {
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
// https://help.apple.com/xcode/#/dev745c5c974
|
// https://help.apple.com/xcode/#/dev745c5c974
|
||||||
|
|
||||||
MARKETING_VERSION = 2024.3
|
MARKETING_VERSION = 2024.3
|
||||||
CURRENT_PROJECT_VERSION = 131
|
CURRENT_PROJECT_VERSION = 129
|
||||||
CURRENT_PROJECT_VERSION = $(inherited)$(CURRENT_PROJECT_VERSION_BUILD_SUFFIX_$(CONFIGURATION))
|
CURRENT_PROJECT_VERSION = $(inherited)$(CURRENT_PROJECT_VERSION_BUILD_SUFFIX_$(CONFIGURATION))
|
||||||
|
|
||||||
CURRENT_PROJECT_VERSION_BUILD_SUFFIX_Debug=-dev
|
CURRENT_PROJECT_VERSION_BUILD_SUFFIX_Debug=-dev
|
||||||
|
|
Loading…
Reference in New Issue