Skip to content

Commit

Permalink
New Preferences window on macOS with support for changing some basic …
Browse files Browse the repository at this point in the history
…moderation settings, plus username (finally) and user icon.
  • Loading branch information
mierau committed Dec 24, 2023
1 parent e2eccde commit a4cbaea
Show file tree
Hide file tree
Showing 7 changed files with 282 additions and 29 deletions.
18 changes: 16 additions & 2 deletions Hotline.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
DA0D698D2B1E7CF700C71DF5 /* UsersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA0D698C2B1E7CF700C71DF5 /* UsersView.swift */; platformFilter = ios; };
DA0D698F2B1E841600C71DF5 /* MessageBoardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA0D698E2B1E841600C71DF5 /* MessageBoardView.swift */; platformFilter = ios; };
DA0D69912B1E894800C71DF5 /* FilesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA0D69902B1E894800C71DF5 /* FilesView.swift */; platformFilter = ios; };
DA2863D82B37AD1C00A7D050 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2863D72B37AD1C00A7D050 /* SettingsView.swift */; };
DA2863DA2B37BF6E00A7D050 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA2863D92B37BF6E00A7D050 /* Preferences.swift */; };
DA32CD492B2931640053B98B /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32CD482B2931640053B98B /* User.swift */; };
DA32CD4B2B29318E0053B98B /* FileInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32CD4A2B29318E0053B98B /* FileInfo.swift */; };
DA32CD4D2B2931B50053B98B /* ChatMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA32CD4C2B2931B50053B98B /* ChatMessage.swift */; };
Expand Down Expand Up @@ -48,6 +50,9 @@
DA0D698C2B1E7CF700C71DF5 /* UsersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UsersView.swift; sourceTree = "<group>"; };
DA0D698E2B1E841600C71DF5 /* MessageBoardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageBoardView.swift; sourceTree = "<group>"; };
DA0D69902B1E894800C71DF5 /* FilesView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilesView.swift; sourceTree = "<group>"; };
DA2863D72B37AD1C00A7D050 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = "<group>"; };
DA2863D92B37BF6E00A7D050 /* Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
DA2863DB2B37DBE000A7D050 /* Hotline.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Hotline.entitlements; sourceTree = "<group>"; };
DA32CD472B28EE640053B98B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
DA32CD482B2931640053B98B /* User.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = "<group>"; };
DA32CD4A2B29318E0053B98B /* FileInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileInfo.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -136,6 +141,7 @@
DABFCC272B1530BE009F40D2 /* Utility */,
DA9CAFC02B126D5800CDA197 /* Assets.xcassets */,
DA32CD472B28EE640053B98B /* Info.plist */,
DA2863DB2B37DBE000A7D050 /* Hotline.entitlements */,
DA9CAFC22B126D5800CDA197 /* Preview Content */,
);
path = Hotline;
Expand Down Expand Up @@ -177,6 +183,7 @@
isa = PBXGroup;
children = (
DADDB28A2B22B31F0024040D /* Tracker.swift */,
DA2863D92B37BF6E00A7D050 /* Preferences.swift */,
DADDB28E2B238D850024040D /* Hotline.swift */,
DADDB28C2B22B5920024040D /* Server.swift */,
DA32CD482B2931640053B98B /* User.swift */,
Expand All @@ -198,6 +205,7 @@
DAE734FC2B2E65E9000C56F6 /* MessageBoardView.swift */,
DAE735002B2E71F2000C56F6 /* FilesView.swift */,
DA5753692B34A60D00FAC277 /* FileImageView.swift */,
DA2863D72B37AD1C00A7D050 /* SettingsView.swift */,
);
path = macOS;
sourceTree = "<group>";
Expand Down Expand Up @@ -277,6 +285,7 @@
DA43205E2B1D615600FC8843 /* ServerView.swift in Sources */,
DA0D69912B1E894800C71DF5 /* FilesView.swift in Sources */,
DAE735092B329810000C56F6 /* VisualEffectView.swift in Sources */,
DA2863D82B37AD1C00A7D050 /* SettingsView.swift in Sources */,
DA7725412B21435B006C5ABB /* ObservableScrollView.swift in Sources */,
DAE734FF2B2E6750000C56F6 /* ChatView.swift in Sources */,
DAC002192B21630900A6C290 /* SwiftUIExtensions.swift in Sources */,
Expand All @@ -288,6 +297,7 @@
DAE735032B30C0BB000C56F6 /* MessageView.swift in Sources */,
DA32CD4B2B29318E0053B98B /* FileInfo.swift in Sources */,
DA9CAFCB2B126E3300CDA197 /* HotlineTrackerClient.swift in Sources */,
DA2863DA2B37BF6E00A7D050 /* Preferences.swift in Sources */,
DA32CD4F2B2931CC0053B98B /* NewsInfo.swift in Sources */,
DA9CAFBB2B126D5700CDA197 /* Application.swift in Sources */,
DA0D698F2B1E841600C71DF5 /* MessageBoardView.swift in Sources */,
Expand Down Expand Up @@ -435,11 +445,13 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Hotline/Hotline.entitlements;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_ASSET_PATHS = "\"Hotline/Preview Content\"";
DEVELOPMENT_TEAM = 5AEEV7QB2U;
"ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Hotline/Info.plist;
Expand Down Expand Up @@ -469,11 +481,13 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Hotline/Hotline.entitlements;
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
CURRENT_PROJECT_VERSION = 2;
DEVELOPMENT_ASSET_PATHS = "\"Hotline/Preview Content\"";
DEVELOPMENT_TEAM = 5AEEV7QB2U;
"ENABLE_HARDENED_RUNTIME[sdk=macosx*]" = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = Hotline/Info.plist;
Expand Down
10 changes: 10 additions & 0 deletions Hotline/Application.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ struct Application: App {
private var model = Hotline(trackerClient: HotlineTrackerClient(), client: HotlineClient())
#endif

private var preferences = Prefs()

var body: some Scene {
#if os(iOS)
WindowGroup {
Expand Down Expand Up @@ -36,6 +38,7 @@ struct Application: App {
ServerView(server: s)
.frame(minWidth: 400, minHeight: 300)
.environment(Hotline(trackerClient: HotlineTrackerClient(), client: HotlineClient()))
.environment(preferences)
.toolbar {
ToolbarItem(placement: .navigation) {
Image(systemName: "globe.americas.fill")
Expand All @@ -52,6 +55,13 @@ struct Application: App {
}
.defaultSize(width: 700, height: 800)
.defaultPosition(.center)

#if os(macOS)
Settings {
SettingsView()
.environment(preferences)
}
#endif

#endif
}
Expand Down
14 changes: 14 additions & 0 deletions Hotline/Hotline.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!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.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.network.client</key>
<true/>
</dict>
</plist>
14 changes: 10 additions & 4 deletions Hotline/Models/Hotline.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,12 @@ import SwiftUI
2561: "🇸🇪",
]

// @AppStorage("username") private var username: String = "guest"
// @AppStorage("refuse private messages") private var refusePrivateMessages = false
// @AppStorage("refuse private chat") private var refusePrivateChat = false
// @AppStorage("enable automatic response") private var enableAutomaticResponse = false
// @AppStorage("automatic response") private var automaticResponse = ""

var status: HotlineClientStatus = .disconnected

var server: Server? {
Expand All @@ -89,8 +95,8 @@ import SwiftUI
}
}
var serverTitle: String = "Server"
var username: String = "bolt"
var iconID: UInt = 414
var username: String = "guest"
var iconID: Int = 414
var access: HotlineUserAccessOptions?
var agreed: Bool = false

Expand Down Expand Up @@ -141,7 +147,7 @@ import SwiftUI
self.trackerClient.disconnect()
}

@MainActor func login(server: Server, login: String, password: String, username: String, iconID: UInt, callback: ((Bool) -> Void)? = nil) {
@MainActor func login(server: Server, login: String, password: String, username: String, iconID: Int, callback: ((Bool) -> Void)? = nil) {
self.server = server
self.serverName = server.name
self.username = username
Expand All @@ -157,7 +163,7 @@ import SwiftUI
}
}

@MainActor func sendUserInfo(username: String, iconID: UInt, options: HotlineUserOptions = [], autoresponse: String? = nil, callback: ((Bool) -> Void)? = nil) {
@MainActor func sendUserInfo(username: String, iconID: Int, options: HotlineUserOptions = [], autoresponse: String? = nil, callback: ((Bool) -> Void)? = nil) {
self.username = username
self.iconID = iconID

Expand Down
107 changes: 107 additions & 0 deletions Hotline/Models/Preferences.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import SwiftUI

enum PrefsKeys: String {
case username = "username"
case userIconID = "user icon id"
case refusePrivateMessages = "refuse private messages"
case refusePrivateChat = "refuse private chat"
case enableAutomaticMessage = "enable automatic message"
case automaticMessage = "automatic message"
}

@Observable
class Prefs {
init() {
UserDefaults.standard.register(defaults:[
PrefsKeys.username.rawValue: "guest",
PrefsKeys.userIconID.rawValue: 137,
PrefsKeys.refusePrivateMessages.rawValue: false,
PrefsKeys.refusePrivateChat.rawValue: false,
PrefsKeys.enableAutomaticMessage.rawValue: false,
PrefsKeys.automaticMessage.rawValue: "",
])

self.username = UserDefaults.standard.string(forKey: PrefsKeys.username.rawValue)!
self.userIconID = UserDefaults.standard.integer(forKey: PrefsKeys.userIconID.rawValue)
self.refusePrivateMessages = UserDefaults.standard.bool(forKey: PrefsKeys.refusePrivateMessages.rawValue)
self.refusePrivateChat = UserDefaults.standard.bool(forKey: PrefsKeys.refusePrivateChat.rawValue)
self.enableAutomaticMessage = UserDefaults.standard.bool(forKey: PrefsKeys.enableAutomaticMessage.rawValue)
self.automaticMessage = UserDefaults.standard.string(forKey: PrefsKeys.automaticMessage.rawValue)!
}

var username: String {
didSet { UserDefaults.standard.set(self.username, forKey: PrefsKeys.username.rawValue) }
}

var userIconID: Int {
didSet { UserDefaults.standard.set(self.userIconID, forKey: PrefsKeys.userIconID.rawValue) }
}

var refusePrivateMessages: Bool {
didSet { UserDefaults.standard.set(self.refusePrivateMessages, forKey: PrefsKeys.refusePrivateMessages.rawValue) }
}

var refusePrivateChat: Bool {
didSet { UserDefaults.standard.set(self.refusePrivateChat, forKey: PrefsKeys.refusePrivateChat.rawValue) }
}

var enableAutomaticMessage: Bool {
didSet { UserDefaults.standard.set(self.enableAutomaticMessage, forKey: PrefsKeys.enableAutomaticMessage.rawValue) }
}

var automaticMessage: String {
didSet { UserDefaults.standard.set(self.automaticMessage, forKey: PrefsKeys.automaticMessage.rawValue) }
}
}

//@Observable
//final class Preferences {
//
// var username: String {
// get {
// access(keyPath: \.username)
// return UserDefaults.standard.object(forKey: "username") as? String ?? "guest"
// }
// set {
// withMutation(keyPath: \.username) {
// UserDefaults.standard.set(newValue, forKey: "username")
// }
// }
// }
//
// var refusePrivateMessages: Bool {
// get { return UserDefaults.standard.object(forKey: "refuse private messages") as? Bool ?? false }
// set { UserDefaults.standard.set(newValue, forKey: "refuse private messages") }
// }
//
// var refusePrivateChat: Bool {
// get { return UserDefaults.standard.object(forKey: "refuse private chat") as? Bool ?? false }
// set { UserDefaults.standard.set(newValue, forKey: "refuse private chat") }
// }
//
// var automaticResponseEnabled: Bool {
// get { return UserDefaults.standard.object(forKey: "enable automatic response") as? Bool ?? false }
// set { UserDefaults.standard.set(newValue, forKey: "enable automatic response") }
// }
//
// var automaticResponse: String {
// get { return UserDefaults.standard.object(forKey: "automatic response") as? String ?? "" }
// set { UserDefaults.standard.set(newValue, forKey: "automatic response") }
// }
//
// var userIconID: Int {
// get { return UserDefaults.standard.object(forKey: "user icon") as? Int ?? 404 }
// set { UserDefaults.standard.set(newValue, forKey: "user icon") }
// }
//
//// @AppStorage("username") public var username: String = "guest"
//// @AppStorage("refuse private messages") public var refusePrivateMessages: Bool = false
//// @AppStorage("refuse private chat") public var refusePrivateChat: Bool = false
//// @AppStorage("enable automatic response") public var enableAutomaticResponse: Bool = false
//// @AppStorage("automatic response") public var automaticResponse: String = ""
////
//// // Icon
//// @AppStorage("user icon id") public var iconID: Int = 404
//
// public static let shared = Preferences()
//}
54 changes: 31 additions & 23 deletions Hotline/macOS/ServerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ private func connectionStatusToProgress(status: HotlineClientStatus) -> Double {

struct ServerView: View {
@Environment(Hotline.self) private var model: Hotline
@Environment(Prefs.self) private var preferences: Prefs
@Environment(\.dismiss) var dismiss
@Environment(\.controlActiveState) private var controlActiveState

@State private var agreementShown: Bool = false
@State private var selection: MenuItem? = ServerView.menuItems.first


let server: Server

static var menuItems = [
Expand All @@ -129,6 +129,28 @@ struct ServerView: View {
// MenuItem(name: "Tasks", image: "arrow.up.circle", type: .tasks),
]

@MainActor func sendPreferences() {
if self.model.status == .loggedIn {
var options: HotlineUserOptions = HotlineUserOptions()

if preferences.refusePrivateMessages {
options.update(with: .refusePrivateMessages)
}

if preferences.refusePrivateChat {
options.update(with: .refusePrivateChat)
}

if preferences.enableAutomaticMessage {
options.update(with: .automaticResponse)
}

print("Updating preferences with server")

self.model.sendUserInfo(username: preferences.username, iconID: preferences.userIconID, options: options, autoresponse: preferences.automaticMessage)
}
}

var body: some View {
NavigationSplitView {
List(selection: $selection) {
Expand Down Expand Up @@ -238,13 +260,13 @@ struct ServerView: View {
.navigationTitle("")
.onAppear {
print(" YAYY")
self.model.login(server: self.server, login: "", password: "", username: "bolt", iconID: 128) { success in
self.model.login(server: self.server, login: "", password: "", username: preferences.username, iconID: preferences.userIconID) { success in
if !success {
print("FAILED LOGIN??")
}
else {
print("GETTING USER LIST????!")
self.model.sendUserInfo(username: "bolt", iconID: 128)
self.sendPreferences()
self.model.getUserList()
}
}
Expand All @@ -257,26 +279,12 @@ struct ServerView: View {
dismiss()
}
}
// .onChange(of: model.agreement) {
// if model.agreement != nil {
// agreementShown = true
// }
// }
// .sheet(isPresented: $agreementShown, onDismiss: {
// if model.status == .disconnected {
// dismiss()
// }
// }, content: {
// if let text = model.agreement {
// AgreementView(text: text, disagree: {
// self.model.disconnect()
// print("DISAGREE")
// }, agree: {
// print("AGREE?")
// })
//// .frame(minWidth: 300, maxWidth: 500, minHeight: 300)
// }
// })
.onChange(of: preferences.userIconID) { self.sendPreferences() }
.onChange(of: preferences.username) { self.sendPreferences() }
.onChange(of: preferences.refusePrivateMessages) { self.sendPreferences() }
.onChange(of: preferences.refusePrivateChat) { self.sendPreferences() }
.onChange(of: preferences.enableAutomaticMessage) { self.sendPreferences() }
.onChange(of: preferences.automaticMessage) { self.sendPreferences() }
}
}

Expand Down
Loading

0 comments on commit a4cbaea

Please sign in to comment.