2023-05-29 18:23:13 +02:00
|
|
|
import SwiftUI
|
2023-06-03 08:15:00 +02:00
|
|
|
import SFSafeSymbols
|
|
|
|
import BottomSheet
|
2023-05-29 18:23:13 +02:00
|
|
|
|
|
|
|
struct ContentView: View {
|
2023-06-03 08:15:00 +02:00
|
|
|
|
|
|
|
@ObservedObject
|
|
|
|
var client = BluetoothClient()
|
|
|
|
|
|
|
|
init() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
init(client: BluetoothClient) {
|
|
|
|
self.client = client
|
|
|
|
}
|
|
|
|
|
|
|
|
@State
|
|
|
|
var showDeviceInfo = false
|
|
|
|
|
|
|
|
var averageTemperature: Double? {
|
|
|
|
let t1 = client.deviceInfo?.sensor1?.optionalValue
|
|
|
|
guard let t0 = client.deviceInfo?.sensor0?.optionalValue else {
|
|
|
|
return t1
|
|
|
|
}
|
|
|
|
guard let t1 else {
|
|
|
|
return t0
|
|
|
|
}
|
|
|
|
return (t0 + t1) / 2
|
|
|
|
}
|
|
|
|
|
|
|
|
var hasTemperature: Bool {
|
|
|
|
averageTemperature != nil
|
|
|
|
}
|
|
|
|
var temperatureString: String {
|
|
|
|
guard let temp = averageTemperature else {
|
|
|
|
return "?"
|
|
|
|
}
|
|
|
|
return String(format: "%.0f°", locale: .current, temp)
|
|
|
|
}
|
|
|
|
|
|
|
|
var temperatureIcon: SFSymbol {
|
|
|
|
guard let temp = averageTemperature else {
|
|
|
|
return .thermometerMediumSlash
|
|
|
|
}
|
|
|
|
guard temp > 0 else {
|
|
|
|
return .thermometerSnowflake
|
|
|
|
}
|
|
|
|
guard temp > 15 else {
|
|
|
|
return .thermometerLow
|
|
|
|
}
|
|
|
|
guard temp > 25 else {
|
|
|
|
return .thermometerMedium
|
|
|
|
}
|
|
|
|
return .thermometerHigh
|
|
|
|
}
|
|
|
|
|
2023-05-29 18:23:13 +02:00
|
|
|
var body: some View {
|
|
|
|
VStack {
|
2023-06-03 08:15:00 +02:00
|
|
|
HStack {
|
|
|
|
Image(systemSymbol: .iphone)
|
|
|
|
.frame(width: 30)
|
|
|
|
Text(client.deviceState.text)
|
|
|
|
Spacer()
|
|
|
|
}
|
|
|
|
Spacer()
|
|
|
|
Image(systemSymbol: temperatureIcon)
|
|
|
|
.font(.system(size: 200, weight: .light))
|
|
|
|
if hasTemperature {
|
|
|
|
Text(temperatureString)
|
|
|
|
.font(.system(size: 100, weight: .light))
|
|
|
|
}
|
|
|
|
|
|
|
|
Spacer()
|
|
|
|
HStack(alignment: .center) {
|
|
|
|
Button(action: {
|
|
|
|
_ = client.collectRecordedData()
|
|
|
|
}) {
|
|
|
|
Text("Transfer")
|
|
|
|
}.padding()
|
|
|
|
Spacer()
|
|
|
|
Button {
|
|
|
|
self.showDeviceInfo = true
|
|
|
|
} label: {
|
|
|
|
Image(systemSymbol: .infoCircle)
|
|
|
|
.font(.system(size: 40, weight: .regular))
|
|
|
|
}.disabled(client.deviceInfo == nil)
|
|
|
|
}.padding()
|
2023-05-29 18:23:13 +02:00
|
|
|
}
|
|
|
|
.padding()
|
2023-06-03 08:15:00 +02:00
|
|
|
.bottomSheet(isPresented: $showDeviceInfo, height: 520) {
|
|
|
|
if let info = client.deviceInfo {
|
|
|
|
DeviceInfoView(info: info)
|
|
|
|
} else {
|
|
|
|
EmptyView()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-29 18:23:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct ContentView_Previews: PreviewProvider {
|
|
|
|
static var previews: some View {
|
2023-06-03 08:15:00 +02:00
|
|
|
ContentView(client: BluetoothClient(deviceInfo: .mock))
|
2023-05-29 18:23:13 +02:00
|
|
|
}
|
|
|
|
}
|
2023-06-03 08:15:00 +02:00
|
|
|
|
|
|
|
extension HorizontalAlignment {
|
|
|
|
|
|
|
|
private struct InfoTextAlignment: AlignmentID {
|
|
|
|
static func defaultValue(in context: ViewDimensions) -> CGFloat {
|
|
|
|
context[HorizontalAlignment.leading]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static let infoTextAlignmentGuide = HorizontalAlignment(
|
|
|
|
InfoTextAlignment.self
|
|
|
|
)
|
|
|
|
}
|