diff options
| author | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-02-05 22:27:17 +0100 |
|---|---|---|
| committer | Ruben Beltran del Rio <git@r.bdr.sh> | 2025-02-05 22:27:17 +0100 |
| commit | 45829daa856b376b1ab04d415917110b71b1dec5 (patch) | |
| tree | 8e52daed6897b6f489d455736fe256cb9bd90fef /Hotline/Utility | |
| parent | 5c3ea897d062a47bc8cd6255fb8c36bad2f0733f (diff) | |
Apply formatting
Diffstat (limited to 'Hotline/Utility')
| -rw-r--r-- | Hotline/Utility/BookmarkDocument.swift | 14 | ||||
| -rw-r--r-- | Hotline/Utility/DAKeychain.swift | 23 | ||||
| -rw-r--r-- | Hotline/Utility/FoundationExtensions.swift | 28 | ||||
| -rw-r--r-- | Hotline/Utility/NSWindowBridge.swift | 22 | ||||
| -rw-r--r-- | Hotline/Utility/ObservableScrollView.swift | 28 | ||||
| -rw-r--r-- | Hotline/Utility/RegularExpressions.swift | 6 | ||||
| -rw-r--r-- | Hotline/Utility/SoundEffects.swift | 22 | ||||
| -rw-r--r-- | Hotline/Utility/SwiftUIExtensions.swift | 4 | ||||
| -rw-r--r-- | Hotline/Utility/TextDocument.swift | 12 |
9 files changed, 83 insertions, 76 deletions
diff --git a/Hotline/Utility/BookmarkDocument.swift b/Hotline/Utility/BookmarkDocument.swift index 47fa442..43f251c 100644 --- a/Hotline/Utility/BookmarkDocument.swift +++ b/Hotline/Utility/BookmarkDocument.swift @@ -1,5 +1,5 @@ -import SwiftUI import Foundation +import SwiftUI import UniformTypeIdentifiers struct BookmarkDocument: FileDocument { @@ -7,22 +7,22 @@ struct BookmarkDocument: FileDocument { static var writableContentTypes: [UTType] { [.data, UTType(filenameExtension: "hlbm")!] } var bookmark: Bookmark - + init(bookmark: Bookmark) { self.bookmark = bookmark } - + init(configuration: ReadConfiguration) throws { guard configuration.file.isRegularFile, - let data = configuration.file.regularFileContents, - let fileName = configuration.file.preferredFilename, - let bookmark = Bookmark(fileData: data, name: (fileName as NSString).deletingPathExtension) + let data = configuration.file.regularFileContents, + let fileName = configuration.file.preferredFilename, + let bookmark = Bookmark(fileData: data, name: (fileName as NSString).deletingPathExtension) else { throw CocoaError(.fileReadCorruptFile) } self.bookmark = bookmark } - + func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { let wrapper = FileWrapper(regularFileWithContents: self.bookmark.bookmarkFileData()!) wrapper.fileAttributes[FileAttributeKey.hfsCreatorCode.rawValue] = "HTLC".fourCharCode() diff --git a/Hotline/Utility/DAKeychain.swift b/Hotline/Utility/DAKeychain.swift index 8031886..aa71508 100644 --- a/Hotline/Utility/DAKeychain.swift +++ b/Hotline/Utility/DAKeychain.swift @@ -9,26 +9,27 @@ import Foundation open class DAKeychain { - + open var loggingEnabled = false - + private init() {} public static let shared = DAKeychain() - + open subscript(key: String) -> String? { get { return load(withKey: key) - } set { + } + set { DispatchQueue.global().sync(flags: .barrier) { self.save(newValue, forKey: key) } } } - + private func save(_ string: String?, forKey key: String) { let query = keychainQuery(withKey: key) let objectData: Data? = string?.data(using: .utf8, allowLossyConversion: false) - + if SecItemCopyMatching(query, nil) == noErr { if let dictData = objectData { let status = SecItemUpdate(query, NSDictionary(dictionary: [kSecValueData: dictData])) @@ -45,15 +46,15 @@ open class DAKeychain { } } } - + private func load(withKey key: String) -> String? { let query = keychainQuery(withKey: key) query.setValue(kCFBooleanTrue, forKey: kSecReturnData as String) query.setValue(kCFBooleanTrue, forKey: kSecReturnAttributes as String) - + var result: CFTypeRef? let status = SecItemCopyMatching(query, &result) - + guard let resultsDict = result as? NSDictionary, let resultsData = resultsDict.value(forKey: kSecValueData as String) as? Data, @@ -64,7 +65,7 @@ open class DAKeychain { } return String(data: resultsData, encoding: .utf8) } - + private func keychainQuery(withKey key: String) -> NSMutableDictionary { let result = NSMutableDictionary() result.setValue(kSecClassGenericPassword, forKey: kSecClass as String) @@ -72,7 +73,7 @@ open class DAKeychain { result.setValue(kSecAttrAccessibleWhenUnlocked, forKey: kSecAttrAccessible as String) return result } - + private func logPrint(_ items: Any...) { if loggingEnabled { print(items) diff --git a/Hotline/Utility/FoundationExtensions.swift b/Hotline/Utility/FoundationExtensions.swift index 9fc9ae7..b1cd1b9 100644 --- a/Hotline/Utility/FoundationExtensions.swift +++ b/Hotline/Utility/FoundationExtensions.swift @@ -7,27 +7,27 @@ enum Endianness { } extension String { - + func convertToAttributedStringWithLinks() -> AttributedString { let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: self) let matches = self.ranges(of: RegularExpressions.relaxedLink) for match in matches { let matchString = String(self[match]) if matchString.isEmailAddress() { - attributedString.addAttribute(.link, value: "mailto:\(matchString)", range: NSRange(match, in: self)) - } - else { + 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)) + // 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 @@ -39,12 +39,12 @@ extension String { return false } } - + func isImageURL() -> Bool { guard let url = URL(string: self) else { return false } - + switch url.pathExtension.lowercased() { case "jpg", "jpeg", "png", "gif": return true @@ -52,29 +52,27 @@ extension String { return false } } - + func convertingLinksToMarkdown() -> String { var cp = String(self) cp.replace(RegularExpressions.relaxedLink) { match -> String in let linkText = self[match.range] var injectedScheme = "https://" - if let _ = try? RegularExpressions.supportedLinkScheme.prefixMatch(in: linkText) { + if (try? RegularExpressions.supportedLinkScheme.prefixMatch(in: linkText)) != nil { injectedScheme = "" } - + return "[\(linkText)](\(injectedScheme)\(linkText))" } return cp } } - - extension Binding where Value: OptionSet, Value == Value.Element { func bindedValue(_ options: Value) -> Bool { return wrappedValue.contains(options) } - + func bind(_ options: Value) -> Binding<Bool> { return .init { () -> Bool in self.wrappedValue.contains(options) diff --git a/Hotline/Utility/NSWindowBridge.swift b/Hotline/Utility/NSWindowBridge.swift index 5cd7197..ad56105 100644 --- a/Hotline/Utility/NSWindowBridge.swift +++ b/Hotline/Utility/NSWindowBridge.swift @@ -1,25 +1,25 @@ import SwiftUI -fileprivate class NSWindowAccessorView: NSView { - let executeBlock: (_ window: NSWindow? ) -> () - - init(_ inConfigFunction: @escaping (_ window: NSWindow? ) -> () ) { +private class NSWindowAccessorView: NSView { + let executeBlock: (_ window: NSWindow?) -> Void + + init(_ inConfigFunction: @escaping (_ window: NSWindow?) -> Void) { executeBlock = inConfigFunction - super.init( frame: NSRect() ) + 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. + executeBlock(self.window) // We pass it through even if it is nil. } } public struct NSWindowAccessor: NSViewRepresentable { - var configCode: (_ window: NSWindow? ) -> () - + var configCode: (_ window: NSWindow?) -> Void + public init(_ configCode: @escaping (_: NSWindow?) -> Void) { self.configCode = configCode } - public func makeNSView(context: Context) -> NSView { return NSWindowAccessorView( configCode ) } + public func makeNSView(context: Context) -> NSView { return NSWindowAccessorView(configCode) } public func updateNSView(_ nsView: NSView, context: Context) {} } diff --git a/Hotline/Utility/ObservableScrollView.swift b/Hotline/Utility/ObservableScrollView.swift index a6f46cc..05688f1 100644 --- a/Hotline/Utility/ObservableScrollView.swift +++ b/Hotline/Utility/ObservableScrollView.swift @@ -8,27 +8,31 @@ struct ScrollViewOffsetPreferenceKey: PreferenceKey { } } -struct ObservableScrollView<Content>: View where Content : View { +struct ObservableScrollView<Content>: View where Content: View { @Namespace var scrollSpace @Binding var scrollOffset: CGFloat let content: () -> Content - - init(scrollOffset: Binding<CGFloat>, - @ViewBuilder content: @escaping () -> Content) { + + init( + scrollOffset: Binding<CGFloat>, + @ViewBuilder content: @escaping () -> Content + ) { _scrollOffset = scrollOffset self.content = content } - + var body: some View { ScrollView { content() - .background(GeometryReader { geo in - let offset = -geo.frame(in: .named(scrollSpace)).minY - Color.clear - .preference(key: ScrollViewOffsetPreferenceKey.self, - value: offset) - }) - + .background( + GeometryReader { geo in + let offset = -geo.frame(in: .named(scrollSpace)).minY + Color.clear + .preference( + key: ScrollViewOffsetPreferenceKey.self, + value: offset) + }) + } .coordinateSpace(name: scrollSpace) .onPreferenceChange(ScrollViewOffsetPreferenceKey.self) { value in diff --git a/Hotline/Utility/RegularExpressions.swift b/Hotline/Utility/RegularExpressions.swift index c1f2a18..db705ae 100644 --- a/Hotline/Utility/RegularExpressions.swift +++ b/Hotline/Utility/RegularExpressions.swift @@ -20,7 +20,7 @@ struct RegularExpressions { } } } - + static let supportedLinkScheme = Regex { Anchor.startOfLine ChoiceOf { @@ -30,7 +30,7 @@ struct RegularExpressions { } "://" }.ignoresCase().anchorsMatchLineEndings() - + static let relaxedLink = Regex { ChoiceOf { Anchor.startOfLine @@ -138,7 +138,7 @@ struct RegularExpressions { } .anchorsMatchLineEndings() .ignoresCase() - + static let emailAddress = Regex { ChoiceOf { Anchor.startOfLine diff --git a/Hotline/Utility/SoundEffects.swift b/Hotline/Utility/SoundEffects.swift index 93f8b9a..74314e4 100644 --- a/Hotline/Utility/SoundEffects.swift +++ b/Hotline/Utility/SoundEffects.swift @@ -1,5 +1,5 @@ -import Foundation import AVFAudio +import Foundation enum SoundEffects: String { case loggedIn = "logged-in" @@ -15,28 +15,30 @@ enum SoundEffects: String { @Observable class SoundEffectPlayer: NSObject, AVAudioPlayerDelegate { static let shared = SoundEffectPlayer() - + private var activeSounds: [AVAudioPlayer] = [] - + func playSoundEffect(_ name: SoundEffects) { // Load a local sound file - guard let soundFileURL = Bundle.main.url( - forResource: name.rawValue, - withExtension: "aiff" - ) else { + guard + let soundFileURL = Bundle.main.url( + forResource: name.rawValue, + withExtension: "aiff" + ) + else { return } - + DispatchQueue.main.async { [weak self] in guard let self = self else { return } - + if let soundEffect = try? AVAudioPlayer(contentsOf: soundFileURL) { soundEffect.delegate = self soundEffect.volume = 0.75 soundEffect.play() - + self.activeSounds.append(soundEffect) } } diff --git a/Hotline/Utility/SwiftUIExtensions.swift b/Hotline/Utility/SwiftUIExtensions.swift index 3b850e0..27697f8 100644 --- a/Hotline/Utility/SwiftUIExtensions.swift +++ b/Hotline/Utility/SwiftUIExtensions.swift @@ -2,6 +2,8 @@ import SwiftUI extension Color { init(hex: Int, opacity: Double = 1.0) { - self.init(red: Double((hex >> 16) & 0xFF) / 255.0, green: Double((hex >> 8) & 0xFF) / 255.0, blue: Double(hex & 0xFF) / 255.0, opacity: opacity) + self.init( + red: Double((hex >> 16) & 0xFF) / 255.0, green: Double((hex >> 8) & 0xFF) / 255.0, + blue: Double(hex & 0xFF) / 255.0, opacity: opacity) } } diff --git a/Hotline/Utility/TextDocument.swift b/Hotline/Utility/TextDocument.swift index 82727de..a3591fd 100644 --- a/Hotline/Utility/TextDocument.swift +++ b/Hotline/Utility/TextDocument.swift @@ -1,29 +1,29 @@ import Foundation -import UniformTypeIdentifiers import SwiftUI +import UniformTypeIdentifiers struct TextFile: FileDocument { // tell the system we support only plain text static var readableContentTypes = [UTType.plainText, UTType.utf8PlainText] - + // by default our document is empty var text = "" - + // a simple initializer that creates new, empty documents init(initialText: String = "") { text = initialText } - + // this initializer loads data that has been saved previously init(configuration: ReadConfiguration) throws { - + if let data = configuration.file.regularFileContents { if let str = String(data: data, encoding: .utf8) { self.text = str } } } - + // this will be called when the system wants to write our data to disk func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { return FileWrapper(regularFileWithContents: self.text.data(using: .utf8)!) |