Skip to content

Commit

Permalink
Fix about box layout on open. Remove about box from window menu, add …
Browse files Browse the repository at this point in the history
…expand button to server agreement, add email address highlighting, style server messages, unread badge on admins are red now, play server message sound, some code cleanup.
  • Loading branch information
mierau committed May 9, 2024
1 parent 01d3291 commit 75b40db
Show file tree
Hide file tree
Showing 12 changed files with 310 additions and 55 deletions.
12 changes: 12 additions & 0 deletions Hotline.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@
DA5753682B33E88A00FAC277 /* HotlineFileClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA5753672B33E88A00FAC277 /* HotlineFileClient.swift */; };
DA57536C2B36BA1D00FAC277 /* TextDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA57536B2B36BA1D00FAC277 /* TextDocument.swift */; };
DA6300972B24036B0034CBFD /* HotlineClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA6300962B24036B0034CBFD /* HotlineClient.swift */; };
DA65499A2BEC280E00EDB697 /* ServerMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA6549992BEC280E00EDB697 /* ServerMessageView.swift */; };
DA65499C2BEC3FBD00EDB697 /* ServerAgreementView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA65499B2BEC3FBD00EDB697 /* ServerAgreementView.swift */; };
DA65499E2BEC438A00EDB697 /* NSWindowBridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA65499D2BEC438A00EDB697 /* NSWindowBridge.swift */; };
DA72A0DD2B4CD0BF00A0F48A /* NewsEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA72A0DC2B4CD0BF00A0F48A /* NewsEditorView.swift */; };
DA72A0E02B4DA8CA00A0F48A /* SplitView in Frameworks */ = {isa = PBXBuildFile; productRef = DA72A0DF2B4DA8CA00A0F48A /* SplitView */; };
DA72A0E22B4DAA4000A0F48A /* NewsArticle.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA72A0E12B4DAA4000A0F48A /* NewsArticle.swift */; };
Expand Down Expand Up @@ -105,6 +108,9 @@
DA5753672B33E88A00FAC277 /* HotlineFileClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HotlineFileClient.swift; sourceTree = "<group>"; };
DA57536B2B36BA1D00FAC277 /* TextDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextDocument.swift; sourceTree = "<group>"; };
DA6300962B24036B0034CBFD /* HotlineClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HotlineClient.swift; sourceTree = "<group>"; };
DA6549992BEC280E00EDB697 /* ServerMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerMessageView.swift; sourceTree = "<group>"; };
DA65499B2BEC3FBD00EDB697 /* ServerAgreementView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerAgreementView.swift; sourceTree = "<group>"; };
DA65499D2BEC438A00EDB697 /* NSWindowBridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSWindowBridge.swift; sourceTree = "<group>"; };
DA72A0DC2B4CD0BF00A0F48A /* NewsEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsEditorView.swift; sourceTree = "<group>"; };
DA72A0E12B4DAA4000A0F48A /* NewsArticle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsArticle.swift; sourceTree = "<group>"; };
DA77253E2B21176D006C5ABB /* NewsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewsView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -275,6 +281,7 @@
DA57536B2B36BA1D00FAC277 /* TextDocument.swift */,
DABE8C032B57940A00884D28 /* DAKeychain.swift */,
DA55AC782BE6A1AD00034857 /* RegularExpressions.swift */,
DA65499D2BEC438A00EDB697 /* NSWindowBridge.swift */,
);
path = Utility;
sourceTree = "<group>";
Expand Down Expand Up @@ -319,6 +326,8 @@
DA2863D72B37AD1C00A7D050 /* SettingsView.swift */,
DAE136B92B9D1147007D8307 /* HotlinePanelView.swift */,
DA55AC762BE589F700034857 /* AboutView.swift */,
DA65499B2BEC3FBD00EDB697 /* ServerAgreementView.swift */,
DA6549992BEC280E00EDB697 /* ServerMessageView.swift */,
);
path = macOS;
sourceTree = "<group>";
Expand Down Expand Up @@ -414,6 +423,7 @@
DA43205E2B1D615600FC8843 /* ServerView.swift in Sources */,
DA0D69912B1E894800C71DF5 /* FilesView.swift in Sources */,
DAC3D9832BC33FD000A727C9 /* ApplicationState.swift in Sources */,
DA65499C2BEC3FBD00EDB697 /* ServerAgreementView.swift in Sources */,
DAB4D8802B4C8E9A0048A05C /* URLAdditions.swift in Sources */,
DA2863DD2B3E8B7000A7D050 /* FilePreview.swift in Sources */,
DA2863D82B37AD1C00A7D050 /* SettingsView.swift in Sources */,
Expand All @@ -433,6 +443,7 @@
DA9CAFBD2B126D5700CDA197 /* TrackerView.swift in Sources */,
DAB4D87B2B4B78310048A05C /* FileImageView.swift in Sources */,
DA55AC732BE42AF000034857 /* AsyncLinkPreview.swift in Sources */,
DA65499E2BEC438A00EDB697 /* NSWindowBridge.swift in Sources */,
DAE735032B30C0BB000C56F6 /* MessageView.swift in Sources */,
DABE8C062B57A06100884D28 /* Bookmarks.swift in Sources */,
DA32CD4B2B29318E0053B98B /* FileInfo.swift in Sources */,
Expand All @@ -455,6 +466,7 @@
DA4F2BF82B16A17200D8ADDC /* HotlineProtocol.swift in Sources */,
DA5753682B33E88A00FAC277 /* HotlineFileClient.swift in Sources */,
DAB4D8822B4C8FED0048A05C /* FileIconView.swift in Sources */,
DA65499A2BEC280E00EDB697 /* ServerMessageView.swift in Sources */,
DAAEE66F2B47625600A5BA07 /* FilePreviewImageView.swift in Sources */,
DA872B152BDDEE1A008B1012 /* VisualEffectView.swift in Sources */,
DAAEE66D2B475F1400A5BA07 /* PreviewFileInfo.swift in Sources */,
Expand Down
11 changes: 5 additions & 6 deletions Hotline/Application-macOS.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@ struct Application: App {
.frame(minWidth: 250, minHeight: 250)
.environment(bookmarks)
}
.keyboardShortcut(.init(.init("R"), modifiers: .command))
.defaultSize(width: 700, height: 550)
.defaultPosition(.center)
.keyboardShortcut(.init("R"), modifiers: .command)
.onChange(of: AppLaunchState.shared.launchState) {
if AppLaunchState.shared.launchState == .launched {
if Prefs.shared.showBannerToolbar {
Expand All @@ -60,21 +60,20 @@ struct Application: App {
}
}

// MARK: About Box
Window("About", id: "about") {
AboutView()
.ignoresSafeArea()
.background(Color.hotlineRed)
}
.windowResizability(.contentSize)
// .windowStyle(.hiddenTitleBar)
.windowStyle(HiddenTitleBarWindowStyle())
.windowStyle(.hiddenTitleBar)
.defaultPosition(.center)
.commandsRemoved() // Remove About that was automatically added to Window menu.
.commands {
CommandGroup(replacing: CommandGroupPlacement.appInfo) {
Button(action: {
Button("About Hotline") {
openWindow(id: "about")
}) {
Text("About Hotline")
}
}
}
Expand Down
7 changes: 6 additions & 1 deletion Hotline/Models/Hotline.swift
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,12 @@ class Hotline: Equatable, HotlineClientDelegate, HotlineFileClientDelegate {
print("Hotline: received private message from \(user.name): \(message)")

if Prefs.shared.playPrivateMessageSound && Prefs.shared.playPrivateMessageSound {
SoundEffectPlayer.shared.playSoundEffect(.chatMessage)
if self.unreadInstantMessages[userID] == nil {
SoundEffectPlayer.shared.playSoundEffect(.serverMessage)
}
else {
SoundEffectPlayer.shared.playSoundEffect(.chatMessage)
}
}

let instantMessage = InstantMessage(direction: .incoming, text: message.convertingLinksToMarkdown(), type: .message, date: Date())
Expand Down
12 changes: 11 additions & 1 deletion Hotline/Utility/FoundationExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,22 @@ extension String {
let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: self)
let matches = self.ranges(of: RegularExpressions.relaxedLink)
for match in matches {
attributedString.addAttribute(.link, value: self[match], range: NSRange(match, in: self))
let matchString = String(self[match])
if matchString.isEmailAddress() {
attributedString.addAttribute(.link, value: "mailto:\(matchString)", range: NSRange(match, in: self))
}
else {
attributedString.addAttribute(.link, value: matchString, range: NSRange(match, in: self))
}
// attributedString.addAttribute(.underlineStyle, value: 1, range: NSRange(match, in: self))
}
return AttributedString(attributedString)
}

func isEmailAddress() -> Bool {
self.wholeMatch(of: RegularExpressions.emailAddress) != nil
}

func isWebURL() -> Bool {
guard let url = URL(string: self) else {
return false
Expand Down
25 changes: 25 additions & 0 deletions Hotline/Utility/NSWindowBridge.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import SwiftUI

fileprivate class NSWindowAccessorView: NSView {
let executeBlock: (_ window: NSWindow? ) -> ()

init(_ inConfigFunction: @escaping (_ window: NSWindow? ) -> () ) {
executeBlock = inConfigFunction
super.init( frame: NSRect() )
}

required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }

public override func viewDidMoveToWindow() {
super.viewDidMoveToWindow()
executeBlock( self.window ) // We pass it through even if it is nil.
}
}

public struct NSWindowAccessor: NSViewRepresentable {
var configCode: (_ window: NSWindow? ) -> ()

public init(_ configCode: @escaping (_: NSWindow?) -> Void) { self.configCode = configCode }
public func makeNSView(context: Context) -> NSView { return NSWindowAccessorView( configCode ) }
public func updateNSView(_ nsView: NSView, context: Context) {}
}
96 changes: 95 additions & 1 deletion Hotline/Utility/RegularExpressions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ struct RegularExpressions {
// domain name
OneOrMore {
CharacterClass(
.anyOf(".-"),
.anyOf(".-@"),
("a"..."z"),
("0"..."9")
)
Expand Down Expand Up @@ -138,4 +138,98 @@ struct RegularExpressions {
}
.anchorsMatchLineEndings()
.ignoresCase()

static let emailAddress = Regex {
ChoiceOf {
Anchor.startOfLine
Anchor.wordBoundary
}
Capture {
// username
OneOrMore {
CharacterClass(
.anyOf(".-_"),
("a"..."z"),
("0"..."9")
)
}
"@"
// domain name
OneOrMore {
CharacterClass(
.anyOf(".-"),
("a"..."z"),
("0"..."9")
)
}
// top-level domain name
"."
ChoiceOf {
"com"
"net"
"org"
"edu"
"gov"
"mil"
"aero"
"asia"
"biz"
"cat"
"coop"
"info"
"int"
"jobs"
"mobi"
"museum"
"name"
"pizza"
"post"
"pro"
"red"
"tel"
"today"
"travel"
"garden"
"online"
"ai"
"be"
"by"
"ca"
"co"
"de"
"er"
"es"
"fr"
"gs"
"ie"
"im"
"in"
"io"
"is"
"it"
"jp"
"la"
"ly"
"ma"
"md"
"me"
"my"
"nl"
"ps"
"pt"
"ja"
"st"
"to"
"tv"
"uk"
"ws"
}
}
ChoiceOf {
Anchor.endOfLine
Anchor.wordBoundary
}
}
.anchorsMatchLineEndings()
.ignoresCase()
}
52 changes: 36 additions & 16 deletions Hotline/macOS/AboutView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ struct AboutView: View {
}
}
.frame(height: 40)
// .padding(.top, 4)

Spacer()
}
.frame(width: 270)
.frame(width: 250)

Spacer()

ScrollView(.vertical) {
VStack(alignment: .leading, spacing: 16) {
Expand Down Expand Up @@ -118,17 +119,38 @@ struct AboutView: View {
Link(destination: contributor.webURL) {
HStack {
if let pictureURL = contributor.pictureURL {
AsyncImage(url: pictureURL) { img in
img
.interpolation(.high)
.resizable()
.scaledToFit()
.background(.white)
} placeholder: {
Color.white.opacity(0.2)
AsyncImage(url: pictureURL) { phase in
if let image = phase.image {
image
.interpolation(.high)
.resizable()
.scaledToFit()
.background(.white)
.frame(width: 32, height: 32)
} else if phase.error != nil {
Color.clear
.frame(width: 32, height: 32)
} else {
Color.white
.opacity(0.2)
.frame(width: 32, height: 32)
}
}
.frame(width: 32, height: 32)
.clipShape(Circle())

// AsyncImage(url: pictureURL) { img in
// img
// .interpolation(.high)
// .resizable()
// .scaledToFit()
// .background(.white)
// } placeholder: {
// Color.white.opacity(0.2)
// .frame(width: 32, height: 32)
// }
// .frame(width: 32, height: 32)
// .clipShape(Circle())
}

VStack(alignment: .leading, spacing: 2) {
Expand All @@ -143,16 +165,12 @@ struct AboutView: View {
.font(.system(size: 11))
.foregroundStyle(.white.opacity(0.4))
}

Spacer()
}
}
}
}
}
.ignoresSafeArea()
.scrollClipDisabled()
.padding(.leading, 24)
}
.frame(width: 570, height: 330)
.background(
Expand All @@ -162,7 +180,7 @@ struct AboutView: View {
Spacer()
}
.frame(height: 330 + 100)
.offset(x: 270)
.offset(x: 250)
}
)
.background(Color.hotlineRed)
Expand Down Expand Up @@ -191,7 +209,9 @@ struct AboutView: View {
}
}

contributors = newContributors
withAnimation {
contributors = newContributors
}
}

func checkForUpdate() async {
Expand Down
Loading

0 comments on commit 75b40db

Please sign in to comment.