From e3392bb948ad53889ad334140952f2acf614668e Mon Sep 17 00:00:00 2001 From: Dustin Mierau Date: Wed, 6 Dec 2023 22:52:09 -0800 Subject: Some work on news. More UI tweaks across the board. --- Hotline/Utility/DataExtensions.swift | 86 -------------------------- Hotline/Utility/FoundationExtensions.swift | 96 ++++++++++++++++++++++++++++++ Hotline/Utility/ObservableScrollView.swift | 38 ++++++++++++ Hotline/Utility/SwiftUIExtensions.swift | 7 +++ 4 files changed, 141 insertions(+), 86 deletions(-) delete mode 100644 Hotline/Utility/DataExtensions.swift create mode 100644 Hotline/Utility/FoundationExtensions.swift create mode 100644 Hotline/Utility/ObservableScrollView.swift create mode 100644 Hotline/Utility/SwiftUIExtensions.swift (limited to 'Hotline/Utility') diff --git a/Hotline/Utility/DataExtensions.swift b/Hotline/Utility/DataExtensions.swift deleted file mode 100644 index aefd204..0000000 --- a/Hotline/Utility/DataExtensions.swift +++ /dev/null @@ -1,86 +0,0 @@ -import Foundation - -enum Endianness { - case big - case little -} - -extension Data { - init(_ val: UInt8) { - self.init() - self.appendUInt8(val) - } - - init(_ val: UInt16) { - self.init() - self.appendUInt16(val) - } - - init(_ val: UInt32) { - self.init() - self.appendUInt32(val) - } - - func readUInt8(at offset: Int) -> UInt8? { - guard offset >= 0, offset + 1 <= self.count else { - return nil - } - return self[offset] - } - - func readUInt16(at offset: Int) -> UInt16? { - guard offset >= 0, offset + 2 <= self.count else { - return nil - } - - return (UInt16(self[offset]) << 8) + UInt16(self[offset + 1]) - } - - func readUInt32(at offset: Int) -> UInt32? { - guard offset >= 0, offset + 4 <= self.count else { - return nil - } - - return (UInt32(self[offset]) << 24) + (UInt32(self[offset + 1]) << 16) + (UInt32(self[offset + 2]) << 8) + UInt32(self[offset + 3]) - } - - func readData(at offset: Int, length: Int) -> Data? { - guard offset >= 0, offset + length <= self.count else { - return nil - } - return self.subdata(in: offset..<(offset + length)) - } - - func readString(at offset: Int, length: Int) -> String? { - var str: String? - - str = String(data: self[offset..<(offset + length)], encoding: .utf8) - if str == nil { - str = String(data: self[offset..<(offset + length)], encoding: .ascii) - } - - return str - } - - - mutating func appendUInt8(_ value: UInt8, endianness: Endianness = .big) { - var val = endianness == .big ? value.bigEndian : value.littleEndian - append(&val, count: MemoryLayout.size) - } - - mutating func appendUInt16(_ value: UInt16, endianness: Endianness = .big) { - var val = endianness == .big ? value.bigEndian : value.littleEndian - Swift.withUnsafeBytes(of: &val) { buffer in - append(buffer.bindMemory(to: UInt8.self)) - } -// append(&val, count: MemoryLayout.size) - } - - mutating func appendUInt32(_ value: UInt32, endianness: Endianness = .big) { - var val = endianness == .big ? value.bigEndian : value.littleEndian - Swift.withUnsafeBytes(of: &val) { buffer in - append(buffer.bindMemory(to: UInt8.self)) - } -// append(&val, count: MemoryLayout.size) - } -} diff --git a/Hotline/Utility/FoundationExtensions.swift b/Hotline/Utility/FoundationExtensions.swift new file mode 100644 index 0000000..c6ca251 --- /dev/null +++ b/Hotline/Utility/FoundationExtensions.swift @@ -0,0 +1,96 @@ +import Foundation + +enum Endianness { + case big + case little +} + +extension Data { + init(_ val: UInt8) { + self.init() + self.appendUInt8(val) + } + + init(_ val: UInt16) { + self.init() + self.appendUInt16(val) + } + + init(_ val: UInt32) { + self.init() + self.appendUInt32(val) + } + + func readUInt8(at offset: Int) -> UInt8? { + guard offset >= 0, offset + 1 <= self.count else { + return nil + } + return self[offset] + } + + func readUInt16(at offset: Int) -> UInt16? { + guard offset >= 0, offset + 2 <= self.count else { + return nil + } + + return (UInt16(self[offset]) << 8) + UInt16(self[offset + 1]) + } + + func readUInt32(at offset: Int) -> UInt32? { + guard offset >= 0, offset + 4 <= self.count else { + return nil + } + + return (UInt32(self[offset]) << 24) + (UInt32(self[offset + 1]) << 16) + (UInt32(self[offset + 2]) << 8) + UInt32(self[offset + 3]) + } + + func readData(at offset: Int, length: Int) -> Data? { + guard offset >= 0, offset + length <= self.count else { + return nil + } + return self.subdata(in: offset..<(offset + length)) + } + + func readString(at offset: Int, length: Int) -> String? { + var str: String? + + str = String(data: self[offset..<(offset + length)], encoding: .utf8) + if str == nil { + str = String(data: self[offset..<(offset + length)], encoding: .ascii) + } + + return str + } + + func readPString(at offset: Int) -> (String?, Int) { + let len = Int(self.readUInt8(at: offset)!) + return (self.readString(at: offset+1, length: len), 1 + len) + } + + func readLongPString(at offset: Int) -> (String?, Int) { + let len = Int(self.readUInt16(at: offset)!) + return (self.readString(at: offset+2, length: len), 2 + len) + } + + + mutating func appendUInt8(_ value: UInt8, endianness: Endianness = .big) { + var val = endianness == .big ? value.bigEndian : value.littleEndian + append(&val, count: MemoryLayout.size) + } + + mutating func appendUInt16(_ value: UInt16, endianness: Endianness = .big) { + var val = endianness == .big ? value.bigEndian : value.littleEndian + Swift.withUnsafeBytes(of: &val) { buffer in + append(buffer.bindMemory(to: UInt8.self)) + } +// append(&val, count: MemoryLayout.size) + } + + mutating func appendUInt32(_ value: UInt32, endianness: Endianness = .big) { + var val = endianness == .big ? value.bigEndian : value.littleEndian + Swift.withUnsafeBytes(of: &val) { buffer in + append(buffer.bindMemory(to: UInt8.self)) + } +// append(&val, count: MemoryLayout.size) + } +} diff --git a/Hotline/Utility/ObservableScrollView.swift b/Hotline/Utility/ObservableScrollView.swift new file mode 100644 index 0000000..a6f46cc --- /dev/null +++ b/Hotline/Utility/ObservableScrollView.swift @@ -0,0 +1,38 @@ +import SwiftUI + +struct ScrollViewOffsetPreferenceKey: PreferenceKey { + typealias Value = CGFloat + static var defaultValue = CGFloat.zero + static func reduce(value: inout Value, nextValue: () -> Value) { + value += nextValue() + } +} + +struct ObservableScrollView: View where Content : View { + @Namespace var scrollSpace + @Binding var scrollOffset: CGFloat + let content: () -> Content + + init(scrollOffset: Binding, + @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) + }) + + } + .coordinateSpace(name: scrollSpace) + .onPreferenceChange(ScrollViewOffsetPreferenceKey.self) { value in + scrollOffset = value + } + } +} diff --git a/Hotline/Utility/SwiftUIExtensions.swift b/Hotline/Utility/SwiftUIExtensions.swift new file mode 100644 index 0000000..3b850e0 --- /dev/null +++ b/Hotline/Utility/SwiftUIExtensions.swift @@ -0,0 +1,7 @@ +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) + } +} -- cgit