Compare commits

...

5 Commits

9 changed files with 37 additions and 20 deletions

View File

@ -1,5 +1,20 @@
# Changelog # Changelog
## 2024.2 (121)
This build introduces a new multi-column navigation mode on iPad. You can revert to the old mode under Preferences -> Appearance.
Features/Improvements:
- iPadOS: Enable multi-column navigation
- Add post preview to Appearance preferences
- Consolidate Media preferences section with Appearance
- Add icons to Preferences sections
Bugfixes:
- Fix push notifications not working on Pleroma/Akkoma and older Mastodon versions
- Fix push notifications not working with certain accounts
- Fix links on About screen not being aligned
- macOS: Remove non-functional in-app Safari preferences
## 2024.2 (120) ## 2024.2 (120)
This build adds push notifications, which can be enabled in Preferences -> Notifications. This build adds push notifications, which can be enabled in Preferences -> Notifications.

View File

@ -71,7 +71,7 @@ class PushManagerImpl: _PushManager {
private func endpointURL(deviceToken: Data, accountID: String) -> URL { private func endpointURL(deviceToken: Data, accountID: String) -> URL {
var endpoint = URLComponents(url: endpoint, resolvingAgainstBaseURL: false)! var endpoint = URLComponents(url: endpoint, resolvingAgainstBaseURL: false)!
let accountID = accountID.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)! let accountID = accountID.addingPercentEncoding(withAllowedCharacters: .alphanumerics)!
endpoint.path = "/push/v1/\(apnsEnvironment)/\(deviceToken.hexEncodedString())/\(accountID)" endpoint.path = "/push/v1/\(apnsEnvironment)/\(deviceToken.hexEncodedString())/\(accountID)"
return endpoint.url! return endpoint.url!
} }

View File

@ -8,12 +8,12 @@
import Foundation import Foundation
import UIKit import UIKit
struct ThemeKey: MigratablePreferenceKey { public struct ThemeKey: MigratablePreferenceKey {
static var defaultValue: Theme { .unspecified } public static var defaultValue: Theme { .unspecified }
} }
struct AccentColorKey: MigratablePreferenceKey { public struct AccentColorKey: MigratablePreferenceKey {
static var defaultValue: AccentColor { .default } public static var defaultValue: AccentColor { .default }
} }
struct AvatarStyleKey: MigratablePreferenceKey { struct AvatarStyleKey: MigratablePreferenceKey {
@ -28,10 +28,10 @@ struct TrailingSwipeActionsKey: MigratablePreferenceKey {
static var defaultValue: [StatusSwipeAction] { [.reply, .share] } static var defaultValue: [StatusSwipeAction] { [.reply, .share] }
} }
struct WidescreenNavigationModeKey: MigratablePreferenceKey { public struct WidescreenNavigationModeKey: MigratablePreferenceKey {
static var defaultValue: WidescreenNavigationMode { .multiColumn } public static var defaultValue: WidescreenNavigationMode { .multiColumn }
static func shouldMigrate(oldValue: WidescreenNavigationMode) -> Bool { public static func shouldMigrate(oldValue: WidescreenNavigationMode) -> Bool {
oldValue != .splitScreen oldValue != .splitScreen
} }
} }

View File

@ -7,10 +7,10 @@
import Foundation import Foundation
struct TrueKey: MigratablePreferenceKey { public struct TrueKey: MigratablePreferenceKey {
static var defaultValue: Bool { true } public static var defaultValue: Bool { true }
} }
struct FalseKey: MigratablePreferenceKey { public struct FalseKey: MigratablePreferenceKey {
static var defaultValue: Bool { false } public static var defaultValue: Bool { false }
} }

View File

@ -89,13 +89,13 @@ final class Preference<Key: PreferenceKey>: Codable {
} }
} }
struct PreferencePublisher<Key: PreferenceKey>: Publisher { public struct PreferencePublisher<Key: PreferenceKey>: Publisher {
typealias Output = Key.Value public typealias Output = Key.Value
typealias Failure = Never public typealias Failure = Never
let preference: Preference<Key> let preference: Preference<Key>
func receive<S>(subscriber: S) where S : Subscriber, Never == S.Failure, Key.Value == S.Input { public func receive<S>(subscriber: S) where S : Subscriber, Never == S.Failure, Key.Value == S.Input {
preference.$storedValue.map { $0 ?? Key.defaultValue }.receive(subscriber: subscriber) preference.$storedValue.map { $0 ?? Key.defaultValue }.receive(subscriber: subscriber)
} }
} }

View File

@ -16,7 +16,7 @@ public protocol PreferenceKey {
} }
extension PreferenceKey { extension PreferenceKey {
static func didSet(in store: PreferenceStore, newValue: Value) {} public static func didSet(in store: PreferenceStore, newValue: Value) {}
} }
protocol MigratablePreferenceKey: PreferenceKey where Value: Equatable { protocol MigratablePreferenceKey: PreferenceKey where Value: Equatable {

View File

@ -291,6 +291,7 @@
D6C3F5192991F5D60009FCFF /* TimelineJumpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C3F5182991F5D60009FCFF /* TimelineJumpButton.swift */; }; D6C3F5192991F5D60009FCFF /* TimelineJumpButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C3F5182991F5D60009FCFF /* TimelineJumpButton.swift */; };
D6C4532D2BCB86AC00E26A0E /* AppearancePrefsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C4532C2BCB86AC00E26A0E /* AppearancePrefsView.swift */; }; D6C4532D2BCB86AC00E26A0E /* AppearancePrefsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C4532C2BCB86AC00E26A0E /* AppearancePrefsView.swift */; };
D6C4532F2BCB873400E26A0E /* MockStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C4532E2BCB873400E26A0E /* MockStatusView.swift */; }; D6C4532F2BCB873400E26A0E /* MockStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C4532E2BCB873400E26A0E /* MockStatusView.swift */; };
D6C453372BCE1CEF00E26A0E /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = D6C4532A2BCAD7F900E26A0E /* PrivacyInfo.xcprivacy */; };
D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */; }; D6C693EF216192C2007D6A6D /* TuskerNavigationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693EE216192C2007D6A6D /* TuskerNavigationDelegate.swift */; };
D6C693FC2162FE6F007D6A6D /* LoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */; }; D6C693FC2162FE6F007D6A6D /* LoadingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */; };
D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */; }; D6C693FE2162FEEA007D6A6D /* UIViewController+Children.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */; };
@ -1954,6 +1955,7 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
D6C453372BCE1CEF00E26A0E /* PrivacyInfo.xcprivacy in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@ -10,7 +10,7 @@ import UIKit
class StatusCollapseButton: UIButton { class StatusCollapseButton: UIButton {
private var interactionBounds: CGRect! private var interactionBounds: CGRect?
override func layoutSubviews() { override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
@ -19,7 +19,7 @@ class StatusCollapseButton: UIButton {
} }
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return interactionBounds.contains(point) return interactionBounds?.contains(point) ?? false
} }
} }

View File

@ -10,7 +10,7 @@
// https://help.apple.com/xcode/#/dev745c5c974 // https://help.apple.com/xcode/#/dev745c5c974
MARKETING_VERSION = 2024.2 MARKETING_VERSION = 2024.2
CURRENT_PROJECT_VERSION = 120 CURRENT_PROJECT_VERSION = 121
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