mirror of
https://github.com/pawelorzech/MacTorn.git
synced 2026-03-31 20:25:43 +00:00
Fix safety issues, deprecated APIs, and code quality improvements
- Replace force unwrap developer.tornID! with safe optional binding
- Generate travel notification IDs dynamically from TravelNotificationSetting.defaults
instead of hardcoded strings, preventing cancellation gaps
- Extract duplicated developer ID (2362436) into TornConstants enum
- Change DateFormatter from computed property to static let to avoid
expensive re-creation on every render
- Remove redundant objectWillChange.send() already handled by @Published
- Migrate deprecated onChange(of:) { _ in } to new parameterless closure form
This commit is contained in:
parent
464bfea0a4
commit
22f6e5d8e4
7 changed files with 17 additions and 19 deletions
|
|
@ -14,7 +14,7 @@ struct MacTornApp: App {
|
|||
.onAppear {
|
||||
updateAppearance()
|
||||
}
|
||||
.onChange(of: appearanceModeRaw) { _ in
|
||||
.onChange(of: appearanceModeRaw) {
|
||||
updateAppearance()
|
||||
}
|
||||
} label: {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,11 @@
|
|||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
// MARK: - Constants
|
||||
enum TornConstants {
|
||||
static let developerID = 2362436
|
||||
}
|
||||
|
||||
// MARK: - Root Response
|
||||
struct TornResponse: Codable {
|
||||
let name: String?
|
||||
|
|
|
|||
|
|
@ -103,14 +103,8 @@ class NotificationManager: NSObject, UNUserNotificationCenterDelegate {
|
|||
|
||||
/// Cancel all travel-related notifications
|
||||
func cancelTravelNotifications() {
|
||||
let identifiers = [
|
||||
"travel_2min_alert",
|
||||
"travel_1min_alert",
|
||||
"travel_30sec_alert",
|
||||
"travel_10sec_alert"
|
||||
]
|
||||
let identifiers = TravelNotificationSetting.defaults.map { "\($0.id)_alert" }
|
||||
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: identifiers)
|
||||
print("Cancelled travel notifications")
|
||||
}
|
||||
|
||||
/// Cancel a specific notification by identifier
|
||||
|
|
|
|||
|
|
@ -584,9 +584,7 @@ class AppState: ObservableObject {
|
|||
// Check if feedback prompt should be shown
|
||||
self.checkFeedbackPrompt()
|
||||
|
||||
// Force UI update by triggering objectWillChange
|
||||
self.objectWillChange.send()
|
||||
logger.info("UI update triggered, lastUpdated: \(self.lastUpdated?.description ?? "nil")")
|
||||
logger.info("Data updated, lastUpdated: \(self.lastUpdated?.description ?? "nil")")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ struct ContentView: View {
|
|||
private var headerView: some View {
|
||||
HStack {
|
||||
if let lastUpdated = appState.lastUpdated {
|
||||
Text("Updated: \(lastUpdated, formatter: timeFormatter)")
|
||||
Text("Updated: \(lastUpdated, formatter: Self.timeFormatter)")
|
||||
.font(.caption2)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
|
|
@ -177,9 +177,9 @@ struct ContentView: View {
|
|||
.padding(.bottom, 8)
|
||||
}
|
||||
|
||||
private var timeFormatter: DateFormatter {
|
||||
private static let timeFormatter: DateFormatter = {
|
||||
let formatter = DateFormatter()
|
||||
formatter.timeStyle = .short
|
||||
return formatter
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ struct CreditsView: View {
|
|||
@Binding var showCredits: Bool
|
||||
|
||||
// MARK: - Developer
|
||||
private let developer = TornContributor(name: "bombel", tornID: 2362436)
|
||||
private let developer = TornContributor(name: "bombel", tornID: TornConstants.developerID)
|
||||
|
||||
// MARK: - Special Thanks
|
||||
private let specialThanks: [TornContributor] = [
|
||||
|
|
@ -92,7 +92,9 @@ struct CreditsView: View {
|
|||
}
|
||||
|
||||
Button {
|
||||
openTornProfile(developer.tornID!)
|
||||
if let tornID = developer.tornID {
|
||||
openTornProfile(tornID)
|
||||
}
|
||||
} label: {
|
||||
HStack {
|
||||
Text(developer.name)
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ struct SettingsView: View {
|
|||
@State private var showCredits: Bool = false
|
||||
@State private var availableBrowsers: [PreferredBrowser] = PreferredBrowser.availableBrowsers()
|
||||
|
||||
// Developer ID for tip feature (bombel)
|
||||
private let developerID = 2362436
|
||||
private let developerID = TornConstants.developerID
|
||||
|
||||
var body: some View {
|
||||
if showCredits {
|
||||
|
|
@ -74,7 +73,7 @@ struct SettingsView: View {
|
|||
Text("2m").tag(120)
|
||||
}
|
||||
.pickerStyle(.segmented)
|
||||
.onChange(of: appState.refreshInterval) { _ in
|
||||
.onChange(of: appState.refreshInterval) {
|
||||
Task { @MainActor in
|
||||
appState.startPolling()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue