aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Hotline.xcodeproj/project.pbxproj16
-rw-r--r--Hotline/Hotline/HotlineClient.swift27
-rw-r--r--Hotline/Hotline/HotlineProtocol.swift5
-rw-r--r--Hotline/MacApp.swift6
-rw-r--r--Hotline/State/HotlineState.swift49
-rw-r--r--Hotline/macOS/BroadcastMessageSheet.swift (renamed from Hotline/macOS/BroadcastMessageView.swift)2
-rw-r--r--Hotline/macOS/Files/FileDetailsSheet.swift43
-rw-r--r--Hotline/macOS/Files/FilesView.swift38
-rw-r--r--Hotline/macOS/MessageView.swift36
-rw-r--r--Hotline/macOS/ServerView.swift23
-rw-r--r--Hotline/macOS/UserClientInfoSheet.swift (renamed from Hotline/macOS/UserInfo.swift)2
11 files changed, 175 insertions, 72 deletions
diff --git a/Hotline.xcodeproj/project.pbxproj b/Hotline.xcodeproj/project.pbxproj
index 2b3c8e9..6ff1f66 100644
--- a/Hotline.xcodeproj/project.pbxproj
+++ b/Hotline.xcodeproj/project.pbxproj
@@ -89,7 +89,7 @@
DAB4D8842B4CABEF0048A05C /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAB4D8832B4CABEF0048A05C /* Extensions.swift */; };
DAB4D8872B4CB3610048A05C /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = DAB4D8862B4CB3610048A05C /* MarkdownUI */; };
DABAFBEA2EC58C170015E889 /* AccountDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABAFBE92EC58C170015E889 /* AccountDetailsView.swift */; };
- DABAFBEC2EC599700015E889 /* BroadcastMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABAFBEB2EC5996B0015E889 /* BroadcastMessageView.swift */; };
+ DABAFBEC2EC599700015E889 /* BroadcastMessageSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = DABAFBEB2EC5996B0015E889 /* BroadcastMessageSheet.swift */; };
DABE8BF42B55DC0A00884D28 /* transfer-complete.aiff in Resources */ = {isa = PBXBuildFile; fileRef = DABE8BF32B55DC0A00884D28 /* transfer-complete.aiff */; };
DABE8BF62B55DC2E00884D28 /* chat-message.aiff in Resources */ = {isa = PBXBuildFile; fileRef = DABE8BF52B55DC2E00884D28 /* chat-message.aiff */; };
DABE8BF82B55DC6100884D28 /* logged-in.aiff in Resources */ = {isa = PBXBuildFile; fileRef = DABE8BF72B55DC6100884D28 /* logged-in.aiff */; };
@@ -99,7 +99,7 @@
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 */; };
- DAC0E4232EC78E1100E999DB /* UserInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC0E4222EC78E1100E999DB /* UserInfo.swift */; };
+ DAC0E4232EC78E1100E999DB /* UserClientInfoSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC0E4222EC78E1100E999DB /* UserClientInfoSheet.swift */; };
DAC3D9832BC33FD000A727C9 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC3D9822BC33FD000A727C9 /* AppState.swift */; };
DAC6B2E02EAC6236004E2CBA /* ChatStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC6B2DE2EAC6236004E2CBA /* ChatStore.swift */; };
DAC6B2E22EAEE9FE004E2CBA /* NetSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = DAC6B2E12EAEE9EF004E2CBA /* NetSocket.swift */; };
@@ -205,7 +205,7 @@
DAB4D8812B4C8FED0048A05C /* FileIconView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileIconView.swift; sourceTree = "<group>"; };
DAB4D8832B4CABEF0048A05C /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = "<group>"; };
DABAFBE92EC58C170015E889 /* AccountDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDetailsView.swift; sourceTree = "<group>"; };
- DABAFBEB2EC5996B0015E889 /* BroadcastMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BroadcastMessageView.swift; sourceTree = "<group>"; };
+ DABAFBEB2EC5996B0015E889 /* BroadcastMessageSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BroadcastMessageSheet.swift; sourceTree = "<group>"; };
DABE8BF32B55DC0A00884D28 /* transfer-complete.aiff */ = {isa = PBXFileReference; lastKnownFileType = audio.aiff; path = "transfer-complete.aiff"; sourceTree = "<group>"; };
DABE8BF52B55DC2E00884D28 /* chat-message.aiff */ = {isa = PBXFileReference; lastKnownFileType = audio.aiff; path = "chat-message.aiff"; sourceTree = "<group>"; };
DABE8BF72B55DC6100884D28 /* logged-in.aiff */ = {isa = PBXFileReference; lastKnownFileType = audio.aiff; path = "logged-in.aiff"; sourceTree = "<group>"; };
@@ -215,7 +215,7 @@
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>"; };
- DAC0E4222EC78E1100E999DB /* UserInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInfo.swift; sourceTree = "<group>"; };
+ DAC0E4222EC78E1100E999DB /* UserClientInfoSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserClientInfoSheet.swift; sourceTree = "<group>"; };
DAC3D9822BC33FD000A727C9 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
DAC6B2DE2EAC6236004E2CBA /* ChatStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatStore.swift; sourceTree = "<group>"; };
DAC6B2E12EAEE9EF004E2CBA /* NetSocket.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetSocket.swift; sourceTree = "<group>"; };
@@ -534,15 +534,15 @@
DAE734F72B2E4126000C56F6 /* macOS */ = {
isa = PBXGroup;
children = (
- DAC0E4222EC78E1100E999DB /* UserInfo.swift */,
DA55AC762BE589F700034857 /* AboutView.swift */,
DACCE5E22EABE86A008CDD92 /* AppUpdateView.swift */,
DAE136B92B9D1147007D8307 /* HotlinePanelView.swift */,
DAE734F82B2E4185000C56F6 /* ServerView.swift */,
DAF5BC6B2EC2727100551E4D /* ConnectView.swift */,
DAE735022B30C0BB000C56F6 /* MessageView.swift */,
+ DAC0E4222EC78E1100E999DB /* UserClientInfoSheet.swift */,
DA5268B42EB6840A00DCB941 /* TransfersView.swift */,
- DABAFBEB2EC5996B0015E889 /* BroadcastMessageView.swift */,
+ DABAFBEB2EC5996B0015E889 /* BroadcastMessageSheet.swift */,
DA501BE52EBE9520001714F8 /* Trackers */,
DA5268A82EB081AF00DCB941 /* Chat */,
DA5268A62EB0762300DCB941 /* Board */,
@@ -736,12 +736,12 @@
DA501BE72EBE9542001714F8 /* TrackerBookmarkSheet.swift in Sources */,
DAB4D87E2B4C8BCA0048A05C /* FilePreviewTextView.swift in Sources */,
DA3429B72EBAB1750010784E /* QuickLookPreviewView.swift in Sources */,
- DABAFBEC2EC599700015E889 /* BroadcastMessageView.swift in Sources */,
+ DABAFBEC2EC599700015E889 /* BroadcastMessageSheet.swift in Sources */,
DA4F2C012B1A558E00D8ADDC /* ChatView.swift in Sources */,
DA5268B32EB6806E00DCB941 /* HotlineFileDownloadClient.swift in Sources */,
DACCE5E32EABE86A008CDD92 /* AppUpdateView.swift in Sources */,
DAC6B2E02EAC6236004E2CBA /* ChatStore.swift in Sources */,
- DAC0E4232EC78E1100E999DB /* UserInfo.swift in Sources */,
+ DAC0E4232EC78E1100E999DB /* UserClientInfoSheet.swift in Sources */,
DA32CD492B2931640053B98B /* User.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/Hotline/Hotline/HotlineClient.swift b/Hotline/Hotline/HotlineClient.swift
index 1440b71..29b7827 100644
--- a/Hotline/Hotline/HotlineClient.swift
+++ b/Hotline/Hotline/HotlineClient.swift
@@ -181,7 +181,16 @@ public actor HotlineClient {
// Connect socket
print("HotlineClient.connect(): Connecting socket...")
- let socket = try await NetSocket.connect(host: host, port: port)
+ let socket: NetSocket
+ do {
+ socket = try await NetSocket.connect(host: host, port: port)
+ }
+ catch let socketError as NetSocketError {
+ if case .failed(_) = socketError {
+ throw HotlineClientError.connectionFailed(socketError)
+ }
+ throw socketError
+ }
print("HotlineClient.connect(): Socket connected")
// Perform handshake
@@ -590,6 +599,22 @@ public actor HotlineClient {
try await socket.send(transaction, endian: .big)
}
+
+ /// Force a user to disconnect from the server
+ ///
+ /// - Parameters:
+ /// - userID: Target user ID
+ /// - options: If specified, temporarily or permanently ban the user
+ public func disconnectUser(userID: UInt16, options: HotlineUserDisconnectOptions? = nil) async throws {
+ var transaction = HotlineTransaction(id: self.generateTransactionID(), type: .disconnectUser)
+
+ transaction.setFieldUInt16(type: .userID, val: userID)
+ if let options {
+ transaction.setFieldUInt16(type: .options, val: options.rawValue)
+ }
+
+ try await self.sendTransaction(transaction)
+ }
// MARK: - Agreement
diff --git a/Hotline/Hotline/HotlineProtocol.swift b/Hotline/Hotline/HotlineProtocol.swift
index 92fdfd2..a1a0f31 100644
--- a/Hotline/Hotline/HotlineProtocol.swift
+++ b/Hotline/Hotline/HotlineProtocol.swift
@@ -10,6 +10,11 @@ struct HotlinePorts {
static let DefaultTrackerPort: Int = 5498
}
+public enum HotlineUserDisconnectOptions: UInt16 {
+ case temporarilyBan = 1
+ case permanentlyBan = 2
+}
+
public struct HotlineUserOptions: OptionSet, Sendable {
public let rawValue: UInt16
diff --git a/Hotline/MacApp.swift b/Hotline/MacApp.swift
index 7997a87..4f6c2af 100644
--- a/Hotline/MacApp.swift
+++ b/Hotline/MacApp.swift
@@ -185,13 +185,13 @@ struct Application: App {
Server(name: nil, description: nil, address: "")
}
.modelContainer(self.modelContainer)
- .defaultSize(width: 690, height: 760)
+ .defaultSize(width: 780, height: 640)
.defaultPosition(.center)
.onChange(of: activeServerState) {
- AppState.shared.activeServerState = activeServerState
+ AppState.shared.activeServerState = self.activeServerState
}
.onChange(of: activeHotline) {
- AppState.shared.activeHotline = activeHotline
+ AppState.shared.activeHotline = self.activeHotline
}
.commands {
CommandGroup(replacing: .newItem) {
diff --git a/Hotline/State/HotlineState.swift b/Hotline/State/HotlineState.swift
index e78a780..7baa477 100644
--- a/Hotline/State/HotlineState.swift
+++ b/Hotline/State/HotlineState.swift
@@ -174,7 +174,7 @@ class HotlineState: Equatable {
self.updateServerTitle()
}
}
- var serverTitle: String = "Server"
+ var serverTitle: String = ""
var username: String = "guest"
var iconID: Int = 414
var access: HotlineUserAccessOptions?
@@ -361,18 +361,41 @@ class HotlineState: Equatable {
self.downloadBanner()
}
- } catch {
+ }
+ catch let clientError as HotlineClientError {
+ switch clientError {
+ case .connectionFailed(_):
+ self.displayError(clientError, message: "This server appears to be offline.")
+ case .loginFailed(let msg):
+ self.displayError(clientError, message: msg)
+ case .serverError(_, let msg):
+ self.displayError(clientError, message: msg)
+ default:
+ self.displayError(clientError)
+ }
+ if let client = self.client {
+ await client.disconnect()
+ self.client = nil
+ }
+ self.status = .disconnected
+ throw clientError
+ }
+ catch {
print("HotlineState.login(): Login failed with error: \(error)")
if let client = self.client {
await client.disconnect()
self.client = nil
}
- self.status = .disconnected // .failed(error.localizedDescription)
- self.errorDisplayed = true
- self.errorMessage = error.localizedDescription
+ self.status = .disconnected
+ self.displayError(error)
throw error
}
}
+
+ private func displayError(_ error: Error, message: String? = nil) {
+ self.errorDisplayed = true
+ self.errorMessage = message ?? error.localizedDescription
+ }
/// Disconnect from the server (user-initiated)
@MainActor
@@ -813,6 +836,20 @@ class HotlineState: Equatable {
return nil
}
+
+ func disconnectUser(id userID: UInt16, options: HotlineUserDisconnectOptions?) async throws {
+ guard let client = self.client else {
+ throw HotlineClientError.notConnected
+ }
+
+ do {
+ try await client.disconnectUser(userID: userID, options: options)
+ }
+ catch let error as HotlineClientError {
+ self.errorMessage = error.userMessage
+ self.errorDisplayed = true
+ }
+ }
// MARK: - Files
@@ -1948,7 +1985,7 @@ class HotlineState: Equatable {
// MARK: - Utilities
func updateServerTitle() {
- self.serverTitle = self.serverName ?? self.server?.name ?? self.server?.address ?? "Server"
+ self.serverTitle = self.serverName ?? self.server?.name ?? self.server?.address ?? "Hotline"
}
// News helpers
diff --git a/Hotline/macOS/BroadcastMessageView.swift b/Hotline/macOS/BroadcastMessageSheet.swift
index a5f6fd2..b3bd7ea 100644
--- a/Hotline/macOS/BroadcastMessageView.swift
+++ b/Hotline/macOS/BroadcastMessageSheet.swift
@@ -2,7 +2,7 @@ import SwiftUI
fileprivate let CHARACTER_LIMIT: Int = 255
-struct BroadcastMessageView: View {
+struct BroadcastMessageSheet: View {
@Environment(HotlineState.self) private var model: HotlineState
@Environment(\.dismiss) private var dismiss
diff --git a/Hotline/macOS/Files/FileDetailsSheet.swift b/Hotline/macOS/Files/FileDetailsSheet.swift
index e86bf28..1bfacb2 100644
--- a/Hotline/macOS/Files/FileDetailsSheet.swift
+++ b/Hotline/macOS/Files/FileDetailsSheet.swift
@@ -14,7 +14,7 @@ struct FileDetailsSheet: View {
var body: some View {
VStack(alignment: .leading, spacing: 16) {
HStack(alignment: .center, spacing: 16){
- if self.details.type == "Folder" {
+ if self.isFolder {
FolderIconView()
.frame(width: 32, height: 32)
}
@@ -22,6 +22,7 @@ struct FileDetailsSheet: View {
FileIconView(filename: self.details.name, fileType: nil)
.frame(width: 32, height: 32)
}
+
TextField("File Name", text: $filename)
.disabled(!self.canRename)
}
@@ -114,6 +115,28 @@ struct FileDetailsSheet: View {
}
}
+ private var isFolder: Bool {
+ self.details.type == "Folder" || self.details.type == "fldr"
+ }
+
+ private func isEdited() -> Bool {
+ return self.filename != self.details.name || self.comment != self.details.comment
+ }
+
+ private var canRename: Bool {
+ if self.isFolder {
+ return self.model.access?.contains(.canRenameFolders) == true
+ }
+ return self.model.access?.contains(.canRenameFiles) == true
+ }
+
+ private var canSetComment: Bool {
+ if self.isFolder {
+ return self.model.access?.contains(.canSetFolderComment) == true
+ }
+ return self.model.access?.contains(.canSetFileComment) == true
+ }
+
static var dateFormatter: DateFormatter = {
var dateFormatter = DateFormatter()
dateFormatter.dateStyle = .long
@@ -142,24 +165,6 @@ struct FileDetailsSheet: View {
let formattedByteCount = Self.byteCountSizeFormatter.string(from: NSNumber(value:byteCount)) ?? "0"
return "\(FileItemView.byteFormatter.string(fromByteCount: Int64(byteCount))) (\(formattedByteCount) bytes)"
}
-
- private func isEdited() -> Bool {
- return self.filename != self.details.name || self.comment != self.details.comment
- }
-
- private var canRename: Bool {
- if self.details.type == "fldr" || self.details.type == "Folder" {
- return self.model.access?.contains(.canRenameFolders) == true
- }
- return self.model.access?.contains(.canRenameFiles) == true
- }
-
- private var canSetComment: Bool {
- if self.details.type == "fldr" || self.details.type == "Folder" {
- return self.model.access?.contains(.canSetFolderComment) == true
- }
- return self.model.access?.contains(.canSetFileComment) == true
- }
}
//#Preview {
diff --git a/Hotline/macOS/Files/FilesView.swift b/Hotline/macOS/Files/FilesView.swift
index 1ae99d9..c9c4c24 100644
--- a/Hotline/macOS/Files/FilesView.swift
+++ b/Hotline/macOS/Files/FilesView.swift
@@ -198,28 +198,32 @@ struct FilesView: View {
ToolbarSpacer()
}
- ToolbarItem {
- Button {
- self.newFolderShown = true
- } label: {
- Label("New Folder", systemImage: "folder.badge.plus")
- }
- .help("New Folder")
- .popover(isPresented: self.$newFolderShown, arrowEdge: .bottom) {
- NewFolderPopover { folderName in
- self.newFolder(name: folderName, parent: self.selection)
+ if self.model.access?.contains(.canCreateFolders) == true {
+ ToolbarItem {
+ Button {
+ self.newFolderShown = true
+ } label: {
+ Label("New Folder", systemImage: "folder.badge.plus")
+ }
+ .help("New Folder")
+ .popover(isPresented: self.$newFolderShown, arrowEdge: .bottom) {
+ NewFolderPopover { folderName in
+ self.newFolder(name: folderName, parent: self.selection)
+ }
}
}
}
- ToolbarItem {
- Button {
- self.confirmDeleteShown = true
- } label: {
- Label("Delete", systemImage: "trash")
+ if self.model.access?.contains(.canDeleteFiles) == true || self.model.access?.contains(.canDeleteFolders) == true {
+ ToolbarItem {
+ Button {
+ self.confirmDeleteShown = true
+ } label: {
+ Label("Delete", systemImage: "trash")
+ }
+ .disabled(self.selection == nil)
+ .help("Delete")
}
- .disabled(self.selection == nil)
- .help("Delete")
}
}
}
diff --git a/Hotline/macOS/MessageView.swift b/Hotline/macOS/MessageView.swift
index 6690a88..6208d54 100644
--- a/Hotline/macOS/MessageView.swift
+++ b/Hotline/macOS/MessageView.swift
@@ -8,6 +8,8 @@ struct MessageView: View {
@State private var scrollPos: Int?
@State private var contentHeight: CGFloat = 0
@State private var userInfo: HotlineUserClientInfo?
+ @State private var disconnectConfirmShown: Bool = false
+ @State private var username: String?
@Namespace private var bottomID
@FocusState private var focusedField: FocusedField?
@@ -27,6 +29,10 @@ struct MessageView: View {
self.inputBar
}
.background(Color(nsColor: .textBackgroundColor))
+ .onAppear {
+ let user = self.model.users.first(where: { $0.id == userID })
+ self.username = user?.name
+ }
.toolbar {
if self.model.access?.contains(.canGetClientInfo) == true {
ToolbarItem {
@@ -35,11 +41,30 @@ struct MessageView: View {
} label: {
Image(systemName: "info.circle")
}
+ .help("View \(self.username ?? "user")'s information")
+ }
+ }
+
+ if self.model.access?.contains(.canDisconnectUsers) == true {
+ ToolbarItem {
+ Button {
+ self.disconnectConfirmShown = true
+ } label: {
+ Image(systemName: "nosign")
+ }
+ .help("Disconnect \(self.username ?? "this user")")
}
}
}
.sheet(item: self.$userInfo) { info in
- UserInfoView(info: info)
+ UserClientInfoSheet(info: info)
+ }
+ .alert("Are you sure you want to disconnect \(self.username ?? "this user")?", isPresented: self.$disconnectConfirmShown) {
+ Button("Disconnect", role: .destructive) {
+ self.disconnectUser()
+ }
+ } message: {
+ Text("They will be disconnected from the server, but may reconnect.")
}
}
@@ -51,10 +76,15 @@ struct MessageView: View {
}
}
+ private func disconnectUser() {
+ Task {
+ try await self.model.disconnectUser(id: self.userID, options: nil)
+ }
+ }
+
private var inputBar: some View {
HStack(alignment: .lastTextBaseline, spacing: 0) {
- let user = self.model.users.first(where: { $0.id == userID })
- TextField("Message \(user?.name ?? "")", text: $input, axis: .vertical)
+ TextField("Message \(self.username ?? "")", text: $input, axis: .vertical)
.focused($focusedField, equals: .chatInput)
.textFieldStyle(.plain)
.lineLimit(1...5)
diff --git a/Hotline/macOS/ServerView.swift b/Hotline/macOS/ServerView.swift
index 3794018..ff92acc 100644
--- a/Hotline/macOS/ServerView.swift
+++ b/Hotline/macOS/ServerView.swift
@@ -111,7 +111,7 @@ struct ServerView: View {
self.connectForm
Spacer()
}
- .navigationTitle("New Connection")
+ .navigationTitle(self.model.serverTitle.isBlank ? "Hotline" : self.model.serverTitle)
}
else if self.model.status.isLoggingIn {
HStack {
@@ -131,7 +131,7 @@ struct ServerView: View {
}
.frame(maxWidth: 300)
.padding()
- .navigationTitle("New Connection")
+ .navigationTitle(self.model.serverTitle.isBlank ? "Hotline" : self.model.serverTitle)
}
else if self.model.status == .loggedIn {
self.serverView
@@ -155,7 +155,7 @@ struct ServerView: View {
Task { try? await self.model.sendUserPreferences() }
}
.sheet(isPresented: self.$state.broadcastShown) {
- BroadcastMessageView()
+ BroadcastMessageSheet()
.environment(self.model)
.presentationSizing(.fitted)
}
@@ -336,8 +336,8 @@ struct ServerView: View {
var serverView: some View {
NavigationSplitView {
self.navigationList
- .frame(maxWidth: .infinity)
- .navigationSplitViewColumnWidth(min: 200, ideal: 250, max: 500)
+ .navigationSplitViewColumnWidth(200)
+// .navigationSplitViewColumnWidth(min: 150, ideal: 200, max: 400)
.toolbar(removing: .sidebarToggle)
// .toolbar {
// if self.model.access?.contains(.canOpenUsers) == true {
@@ -357,22 +357,22 @@ struct ServerView: View {
ChatView()
.navigationTitle(model.serverTitle)
// .navigationSubtitle("Public Chat")
- .navigationSplitViewColumnWidth(min: 250, ideal: 500)
+// .navigationSplitViewColumnWidth(min: 250, ideal: 500)
case .news:
NewsView()
.navigationTitle(model.serverTitle)
// .navigationSubtitle("Newsgroups")
- .navigationSplitViewColumnWidth(min: 250, ideal: 500)
+// .navigationSplitViewColumnWidth(min: 250, ideal: 500)
case .board:
MessageBoardView()
.navigationTitle(model.serverTitle)
// .navigationSubtitle("Message Board")
- .navigationSplitViewColumnWidth(min: 250, ideal: 500)
+// .navigationSplitViewColumnWidth(min: 250, ideal: 500)
case .files:
FilesView()
.navigationTitle(model.serverTitle)
// .navigationSubtitle("Shared Files")
- .navigationSplitViewColumnWidth(min: 250, ideal: 500)
+// .navigationSplitViewColumnWidth(min: 250, ideal: 500)
// case .accounts:
// AccountManagerView()
// .navigationTitle(model.serverTitle)
@@ -383,15 +383,12 @@ struct ServerView: View {
MessageView(userID: userID)
.navigationTitle(model.serverTitle)
// .navigationSubtitle(user?.name ?? "Private Message")
- .navigationSplitViewColumnWidth(min: 250, ideal: 500)
+// .navigationSplitViewColumnWidth(min: 250, ideal: 500)
.onAppear {
model.markInstantMessagesAsRead(userID: userID)
}
}
}
- .background {
- Color.red
- }
}
// MARK: -
diff --git a/Hotline/macOS/UserInfo.swift b/Hotline/macOS/UserClientInfoSheet.swift
index 328fc02..8fa4db8 100644
--- a/Hotline/macOS/UserInfo.swift
+++ b/Hotline/macOS/UserClientInfoSheet.swift
@@ -1,6 +1,6 @@
import SwiftUI
-struct UserInfoView: View {
+struct UserClientInfoSheet: View {
@Environment(\.dismiss) private var dismiss
let info: HotlineUserClientInfo