diff options
| -rw-r--r-- | Hotline.xcodeproj/project.pbxproj | 4 | ||||
| -rw-r--r-- | Hotline/Application-macOS.swift | 19 | ||||
| -rw-r--r-- | Hotline/Hotline.entitlements | 16 | ||||
| -rw-r--r-- | Hotline/Models/Bookmark.swift | 16 | ||||
| -rw-r--r-- | Hotline/Models/BookmarksOld.swift | 126 | ||||
| -rw-r--r-- | Hotline/Sounds/Application-iOS.swift | 4 | ||||
| -rw-r--r-- | Hotline/macOS/ServerView.swift | 5 |
7 files changed, 29 insertions, 161 deletions
diff --git a/Hotline.xcodeproj/project.pbxproj b/Hotline.xcodeproj/project.pbxproj index 9237db3..858cc6c 100644 --- a/Hotline.xcodeproj/project.pbxproj +++ b/Hotline.xcodeproj/project.pbxproj @@ -65,7 +65,6 @@ DABE8C002B55E69800884D28 /* server-message.aiff in Resources */ = {isa = PBXBuildFile; fileRef = DABE8BFF2B55E69800884D28 /* server-message.aiff */; }; DABE8C022B55E69D00884D28 /* new-news.aiff in Resources */ = {isa = PBXBuildFile; fileRef = DABE8C012B55E69D00884D28 /* new-news.aiff */; }; DABE8C042B57940B00884D28 /* DAKeychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABE8C032B57940A00884D28 /* DAKeychain.swift */; }; - DABE8C062B57A06100884D28 /* BookmarksOld.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABE8C052B57A06100884D28 /* BookmarksOld.swift */; }; DABFCC292B1530DC009F40D2 /* FoundationExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABFCC282B1530DC009F40D2 /* FoundationExtensions.swift */; }; DAC002192B21630900A6C290 /* SwiftUIExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC002182B21630900A6C290 /* SwiftUIExtensions.swift */; }; DAC3D97E2BC0F1ED00A727C9 /* Application-iOS.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC3D97D2BC0F1ED00A727C9 /* Application-iOS.swift */; platformFilter = ios; }; @@ -144,7 +143,6 @@ DABE8BFF2B55E69800884D28 /* server-message.aiff */ = {isa = PBXFileReference; lastKnownFileType = audio.aiff; path = "server-message.aiff"; sourceTree = "<group>"; }; DABE8C012B55E69D00884D28 /* new-news.aiff */ = {isa = PBXFileReference; lastKnownFileType = audio.aiff; path = "new-news.aiff"; sourceTree = "<group>"; }; DABE8C032B57940A00884D28 /* DAKeychain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DAKeychain.swift; sourceTree = "<group>"; }; - DABE8C052B57A06100884D28 /* BookmarksOld.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookmarksOld.swift; sourceTree = "<group>"; }; DABFCC282B1530DC009F40D2 /* FoundationExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FoundationExtensions.swift; sourceTree = "<group>"; }; DAC002182B21630900A6C290 /* SwiftUIExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIExtensions.swift; sourceTree = "<group>"; }; DAC3D97D2BC0F1ED00A727C9 /* Application-iOS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Application-iOS.swift"; path = "Sounds/Application-iOS.swift"; sourceTree = "<group>"; }; @@ -296,7 +294,6 @@ DADDB28E2B238D850024040D /* Hotline.swift */, DADDB28A2B22B31F0024040D /* Tracker.swift */, DAC3D9822BC33FD000A727C9 /* ApplicationState.swift */, - DABE8C052B57A06100884D28 /* BookmarksOld.swift */, DA2863D92B37BF6E00A7D050 /* Preferences.swift */, DADDB28C2B22B5920024040D /* Server.swift */, DA32CD482B2931640053B98B /* User.swift */, @@ -451,7 +448,6 @@ DA55AC732BE42AF000034857 /* AsyncLinkPreview.swift in Sources */, DA65499E2BEC438A00EDB697 /* NSWindowBridge.swift in Sources */, DAE735032B30C0BB000C56F6 /* MessageView.swift in Sources */, - DABE8C062B57A06100884D28 /* BookmarksOld.swift in Sources */, DA32CD4B2B29318E0053B98B /* FileInfo.swift in Sources */, DA20BBE12BF5237600B94E7C /* Bookmark.swift in Sources */, DA9CAFCB2B126E3300CDA197 /* HotlineTrackerClient.swift in Sources */, diff --git a/Hotline/Application-macOS.swift b/Hotline/Application-macOS.swift index f6b5bc5..6b02024 100644 --- a/Hotline/Application-macOS.swift +++ b/Hotline/Application-macOS.swift @@ -33,7 +33,6 @@ struct Application: App { @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate - @State private var bookmarks = BookmarksOld() @State private var hotlinePanel: HotlinePanel? = nil @FocusedValue(\.activeHotlineModel) private var activeHotline: Hotline? @@ -44,9 +43,8 @@ struct Application: App { Window("Servers", id: "servers") { TrackerView() .frame(minWidth: 250, minHeight: 250) - .environment(bookmarks) } - .modelContainer(for: Bookmark.self, isAutosaveEnabled: true, isUndoEnabled: true) + .modelContainer(for: [Bookmark.self]) .defaultSize(width: 700, height: 550) .defaultPosition(.center) .keyboardShortcut(.init("R"), modifiers: .command) @@ -80,10 +78,10 @@ struct Application: App { WindowGroup(id: "server", for: Server.self) { server in ServerView(server: server) .frame(minWidth: 430, minHeight: 300) - .environment(bookmarks) } defaultValue: { Server(name: nil, description: nil, address: "") } + .modelContainer(for: [Bookmark.self]) .defaultSize(width: 750, height: 700) .defaultPosition(.center) .onChange(of: activeServerState) { @@ -179,18 +177,7 @@ struct Application: App { Settings { SettingsView() } - - - // MARK: News Editor Window -// WindowGroup(id: "news-editor", for: NewsArticle.self) { $article in -// NewsEditorView(article: $article) -// } -// .windowResizability(.contentSize) -// .windowStyle(.titleBar) -// .windowToolbarStyle(.unifiedCompact(showsTitle: true)) -// .defaultSize(width: 450, height: 550) -// .defaultPosition(.center) - + // MARK: Image Preview Window WindowGroup(id: "preview-image", for: PreviewFileInfo.self) { $info in FilePreviewImageView(info: $info) diff --git a/Hotline/Hotline.entitlements b/Hotline/Hotline.entitlements index 3c00456..e15d27d 100644 --- a/Hotline/Hotline.entitlements +++ b/Hotline/Hotline.entitlements @@ -2,14 +2,26 @@ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> - <key>com.apple.security.files.user-selected.read-write</key> - <true/> + <key>aps-environment</key> + <string>development</string> + <key>com.apple.developer.aps-environment</key> + <string>development</string> + <key>com.apple.developer.icloud-container-identifiers</key> + <array> + <string>iCloud.co.goodmake.hotline</string> + </array> + <key>com.apple.developer.icloud-services</key> + <array> + <string>CloudKit</string> + </array> <key>com.apple.security.app-sandbox</key> <true/> <key>com.apple.security.files.downloads.read-write</key> <true/> <key>com.apple.security.files.user-selected.read-only</key> <true/> + <key>com.apple.security.files.user-selected.read-write</key> + <true/> <key>com.apple.security.network.client</key> <true/> </dict> diff --git a/Hotline/Models/Bookmark.swift b/Hotline/Models/Bookmark.swift index 160de30..3530b19 100644 --- a/Hotline/Models/Bookmark.swift +++ b/Hotline/Models/Bookmark.swift @@ -1,20 +1,20 @@ import Foundation import SwiftData -enum BookmarkType: Codable { - case tracker - case server - case temporary +enum BookmarkType: String, Codable { + case tracker = "tracker" + case server = "server" + case temporary = "temporary" } @Model final class Bookmark { - var type: BookmarkType + var type: BookmarkType = BookmarkType.server var order: Int = 0 - var name: String - var address: String - var port: Int + var name: String = "" + var address: String = "" + var port: Int = HotlinePorts.DefaultServerPort @Attribute(.allowsCloudEncryption) var login: String? diff --git a/Hotline/Models/BookmarksOld.swift b/Hotline/Models/BookmarksOld.swift deleted file mode 100644 index 0a7bb16..0000000 --- a/Hotline/Models/BookmarksOld.swift +++ /dev/null @@ -1,126 +0,0 @@ -import SwiftUI - -extension NSNotification { - static let BookmarkAdded = Notification.Name("BookmarkAdded") - static let BookmarkRemoved = Notification.Name("BookmarkRemoved") -} - -enum BookmarkOldType: String, Codable { - case tracker = "tracker" - case server = "server" -} - -struct BookmarkOld: Codable, Equatable { - let type: BookmarkOldType - let name: String - let address: String - let port: Int - let login: String? - let password: String? - - init(type: BookmarkOldType, name: String, address: String, port: Int = HotlinePorts.DefaultServerPort, login: String? = nil, password: String? = nil) { - self.type = type - self.name = name - self.address = address - self.port = port - self.login = login - self.password = password - } -} - -@Observable final class BookmarksOld { - var bookmarks: [BookmarkOld]? = nil - - static let DefaultBookmarks: [BookmarkOld] = [ - BookmarkOld(type: .server, name: "System 7 Today", address: "hotline.system7today.com"), - BookmarkOld(type: .server, name: "The Mobius Strip", address: "67.174.208.111"), - BookmarkOld(type: .tracker, name: "Featured Servers", address: "hltracker.com"), - ] - - init() { - self.load() - } - - func apply(_ newBookmarks: [BookmarkOld], save shouldSave: Bool = true) { - self.bookmarks = newBookmarks - if shouldSave { - self.save() - } - } - - func load() { - let jsonString: String? = DAKeychain.shared["Hotline Bookmarks"] - let jsonData: Data? = jsonString?.data(using: .utf8, allowLossyConversion: false) - - let decoder = JSONDecoder() - var decodedBookmarks = try? decoder.decode([BookmarkOld].self, from: jsonData ?? Data()) - if decodedBookmarks == nil || decodedBookmarks?.isEmpty == true { - print("Bookmarks: using default bookmarks") - decodedBookmarks = BookmarksOld.DefaultBookmarks - } - else { - print("Bookmarks: using saved bookmarks") - } - - self.bookmarks = [BookmarkOld](decodedBookmarks!) - } - - func save() { - var bookmarksToSave = self.bookmarks - if bookmarksToSave == BookmarksOld.DefaultBookmarks { - print("Bookmarks: skipping saving default bookmarks") - bookmarksToSave = [] - } - - let encoder = JSONEncoder() - encoder.outputFormatting = .prettyPrinted - if let jsonData = try? encoder.encode(bookmarksToSave) { - if let jsonString = String(data: jsonData, encoding: .utf8) { - DAKeychain.shared["Hotline Bookmarks"] = jsonString - } - } - } - - // MARK: - - - func add(_ bookmark: BookmarkOld, save shouldSave: Bool = true) { - self.bookmarks?.insert(bookmark, at: 0) - - if shouldSave { - self.save() - } - - DispatchQueue.main.async { - NotificationCenter.default.post(name: NSNotification.BookmarkAdded, object: nil, userInfo: ["index": 0]) - } - } - - func delete(_ bookmark: BookmarkOld, save shouldSave: Bool = true) -> Bool { - if let i = self.bookmarks?.firstIndex(where: { b in b.address.lowercased() == bookmark.address.lowercased() && b.port == bookmark.port }) { - self.bookmarks?.remove(at: i) - - if shouldSave { - self.save() - } - - DispatchQueue.main.async { - NotificationCenter.default.post(name: NSNotification.BookmarkRemoved, object: nil, userInfo: ["index": i]) - } - return true - } - - return false - } - - func update(_ bookmark: BookmarkOld, save shouldSave: Bool = true) -> Bool { - if let i = self.bookmarks?.firstIndex(where: { b in b.address.lowercased() == bookmark.address.lowercased() && b.port == bookmark.port }) { - self.bookmarks?[i] = bookmark - if shouldSave { - self.save() - } - return true - } - - return false - } -} diff --git a/Hotline/Sounds/Application-iOS.swift b/Hotline/Sounds/Application-iOS.swift index dc3a9d0..2fb6ad2 100644 --- a/Hotline/Sounds/Application-iOS.swift +++ b/Hotline/Sounds/Application-iOS.swift @@ -5,9 +5,7 @@ import UniformTypeIdentifiers @main struct Application: App { private var model = Hotline(trackerClient: HotlineTrackerClient(), client: HotlineClient()) - - @State private var bookmarks = Bookmarks() - + @FocusedValue(\.activeHotlineModel) private var activeHotline: Hotline? @FocusedValue(\.activeServerState) private var activeServerState: ServerState? diff --git a/Hotline/macOS/ServerView.swift b/Hotline/macOS/ServerView.swift index 64c3fbd..e3f0596 100644 --- a/Hotline/macOS/ServerView.swift +++ b/Hotline/macOS/ServerView.swift @@ -127,11 +127,11 @@ enum ServerNavigationType: Identifiable, Hashable, Equatable { } struct ServerView: View { - @Environment(BookmarksOld.self) private var bookmarks: BookmarksOld @Environment(\.dismiss) var dismiss @Environment(\.colorScheme) private var colorScheme @Environment(\.controlActiveState) private var controlActiveState @Environment(\.scenePhase) private var scenePhase + @Environment(\.modelContext) private var modelContext @State private var model: Hotline = Hotline(trackerClient: HotlineTrackerClient(), client: HotlineClient()) @State private var state: ServerState = ServerState(selection: .chat) @@ -334,7 +334,8 @@ struct ServerView: View { let password: String? = connectPassword.isEmpty ? nil : connectPassword if !host.isEmpty { - let _ = bookmarks.add(BookmarkOld(type: .server, name: name, address: host, port: port, login: login, password: password)) + let newBookmark = Bookmark(type: .server, name: name, address: host, port: port, login: login, password: password) + Bookmark.add(newBookmark, context: modelContext) } } } |