mirror of
https://github.com/meshtastic/Meshtastic-Apple.git
synced 2026-04-20 22:13:56 +00:00
Assorted ios 17 updates and live activity cleanup
This commit is contained in:
parent
f3fb06caa9
commit
3658aacbe1
6 changed files with 48 additions and 12 deletions
|
|
@ -688,9 +688,9 @@ func telemetryPacket(packet: MeshPacket, connectedNode: Int64, context: NSManage
|
|||
// Update our live activity if there is one running, not available on mac iOS >= 16.2
|
||||
#if !targetEnvironment(macCatalyst)
|
||||
|
||||
let oneMinuteLater = Calendar.current.date(byAdding: .minute, value: (Int(1) ), to: Date())!
|
||||
let date = Date.now...oneMinuteLater
|
||||
let updatedMeshStatus = MeshActivityAttributes.MeshActivityStatus(timerRange: date, connected: true, channelUtilization: telemetry.channelUtilization, airtime: telemetry.airUtilTx, batteryLevel: UInt32(telemetry.batteryLevel))
|
||||
let oneHourLater = Calendar.current.date(byAdding: .minute, value: (Int(60) ), to: Date())!
|
||||
let date = Date.now...oneHourLater
|
||||
let updatedMeshStatus = MeshActivityAttributes.MeshActivityStatus(timerRange: date, connected: true, channelUtilization: telemetry.channelUtilization, airtime: telemetry.airUtilTx, batteryLevel: UInt32(telemetry.batteryLevel), nodes: 17, nodesOnline: 9)
|
||||
let alertConfiguration = AlertConfiguration(title: "Mesh activity update", body: "Updated Device Metrics Data.", sound: .default)
|
||||
let updatedContent = ActivityContent(state: updatedMeshStatus, staleDate: nil)
|
||||
|
||||
|
|
|
|||
|
|
@ -72,8 +72,17 @@ struct Connect: View {
|
|||
Text("subscribed").font(.callout)
|
||||
.foregroundColor(.green)
|
||||
} else {
|
||||
Text("communicating").font(.callout)
|
||||
.foregroundColor(.orange)
|
||||
|
||||
HStack {
|
||||
if #available(iOS 17.0, macOS 14.0, *) {
|
||||
Image(systemName: "square.stack.3d.down.forward")
|
||||
.symbolRenderingMode(.multicolor)
|
||||
.symbolEffect(.variableColor.reversing.cumulative, options: .repeat(20).speed(3))
|
||||
.foregroundColor(.orange)
|
||||
}
|
||||
Text("communicating").font(.callout)
|
||||
.foregroundColor(.orange)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -304,7 +313,7 @@ struct Connect: View {
|
|||
|
||||
let future = Date(timeIntervalSinceNow: Double(timerSeconds))
|
||||
|
||||
let initialContentState = MeshActivityAttributes.ContentState(timerRange: Date.now...future, connected: true, channelUtilization: mostRecent?.channelUtilization ?? 0.0, airtime: mostRecent?.airUtilTx ?? 0.0, batteryLevel: UInt32(mostRecent?.batteryLevel ?? 0))
|
||||
let initialContentState = MeshActivityAttributes.ContentState(timerRange: Date.now...future, connected: true, channelUtilization: mostRecent?.channelUtilization ?? 0.0, airtime: mostRecent?.airUtilTx ?? 0.0, batteryLevel: UInt32(mostRecent?.batteryLevel ?? 0), nodes: 17, nodesOnline: 9)
|
||||
|
||||
let activityContent = ActivityContent(state: initialContentState, staleDate: Calendar.current.date(byAdding: .minute, value: 2, to: Date())!)
|
||||
|
||||
|
|
|
|||
|
|
@ -74,12 +74,23 @@ struct ChannelMessageList: View {
|
|||
.cornerRadius(15)
|
||||
.overlay(
|
||||
VStack {
|
||||
isDetectionSensorMessage ? Image(systemName: "sensor.fill")
|
||||
if #available(iOS 17.0, macOS 14.0, *) {
|
||||
isDetectionSensorMessage ? Image(systemName: "sensor.fill")
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
|
||||
.foregroundStyle(Color.orange)
|
||||
.symbolRenderingMode(.multicolor)
|
||||
.symbolEffect(.variableColor.reversing.cumulative, options: .repeat(20).speed(3))
|
||||
.offset(x: 20, y: -20)
|
||||
: nil
|
||||
} else {
|
||||
isDetectionSensorMessage ? Image(systemName: "sensor.fill")
|
||||
.padding()
|
||||
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
|
||||
.foregroundStyle(Color.orange)
|
||||
.offset(x: 20, y: -20)
|
||||
: nil
|
||||
: nil
|
||||
}
|
||||
}
|
||||
)
|
||||
.contextMenu {
|
||||
|
|
|
|||
|
|
@ -123,7 +123,11 @@ struct NodeList: View {
|
|||
if let node = selection {
|
||||
NodeDetail(node: node)
|
||||
} else {
|
||||
Text("select.node")
|
||||
if #available (iOS 17, *) {
|
||||
ContentUnavailableView("select.node", systemImage: "flipphone", description: Text("Pick a node from the list."))
|
||||
} else {
|
||||
Text("select.node")
|
||||
}
|
||||
}
|
||||
}
|
||||
.searchable(text: nodesQuery, prompt: "Find a node")
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ struct MeshActivityAttributes: ActivityAttributes {
|
|||
var channelUtilization: Float
|
||||
var airtime: Float
|
||||
var batteryLevel: UInt32
|
||||
var nodes: Int
|
||||
var nodesOnline: Int
|
||||
}
|
||||
|
||||
// Fixed non-changing properties about your activity go here!
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ struct WidgetsLiveActivity: Widget {
|
|||
var body: some WidgetConfiguration {
|
||||
|
||||
ActivityConfiguration(for: MeshActivityAttributes.self) { context in
|
||||
LiveActivityView(nodeName: context.attributes.name, channelUtilization: context.state.channelUtilization, airtime: context.state.airtime, batteryLevel: context.state.batteryLevel, timerRange: context.state.timerRange)
|
||||
LiveActivityView(nodeName: context.attributes.name, channelUtilization: context.state.channelUtilization, airtime: context.state.airtime, batteryLevel: context.state.batteryLevel, nodes: 17, nodesOnline: 7, timerRange: context.state.timerRange)
|
||||
.widgetURL(URL(string: "meshtastic://node/\(context.attributes.name)"))
|
||||
|
||||
} dynamicIsland: { context in
|
||||
|
|
@ -105,7 +105,7 @@ struct WidgetsLiveActivity: Widget {
|
|||
struct WidgetsLiveActivity_Previews: PreviewProvider {
|
||||
static let attributes = MeshActivityAttributes(nodeNum: 123456789, name: "RAK Compact Rotary Handset Gray 8E6G")
|
||||
static let state = MeshActivityAttributes.ContentState(
|
||||
timerRange: Date.now...Date(timeIntervalSinceNow: 3600), connected: true, channelUtilization: 25.84, airtime: 10.01, batteryLevel: 39)
|
||||
timerRange: Date.now...Date(timeIntervalSinceNow: 3600), connected: true, channelUtilization: 25.84, airtime: 10.01, batteryLevel: 39, nodes: 17, nodesOnline: 9)
|
||||
|
||||
static var previews: some View {
|
||||
attributes
|
||||
|
|
@ -133,6 +133,8 @@ struct LiveActivityView: View {
|
|||
var channelUtilization: Float
|
||||
var airtime: Float
|
||||
var batteryLevel: UInt32
|
||||
var nodes: Int
|
||||
var nodesOnline: Int
|
||||
var timerRange: ClosedRange<Date>
|
||||
|
||||
var body: some View {
|
||||
|
|
@ -144,7 +146,7 @@ struct LiveActivityView: View {
|
|||
.aspectRatio(contentMode: .fit)
|
||||
.frame(width: 65)
|
||||
Spacer()
|
||||
NodeInfoView(nodeName: nodeName, timerRange: timerRange, channelUtilization: channelUtilization, airtime: airtime, batteryLevel: batteryLevel)
|
||||
NodeInfoView(nodeName: nodeName, timerRange: timerRange, channelUtilization: channelUtilization, airtime: airtime, batteryLevel: batteryLevel, nodes: nodes, nodesOnline: nodesOnline)
|
||||
Spacer()
|
||||
VStack {
|
||||
BatteryIcon(batteryLevel: Int32(batteryLevel), font: .title, color: .secondary)
|
||||
|
|
@ -188,6 +190,8 @@ struct NodeInfoView: View {
|
|||
var channelUtilization: Float
|
||||
var airtime: Float
|
||||
var batteryLevel: UInt32
|
||||
var nodes: Int
|
||||
var nodesOnline: Int
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
|
|
@ -207,6 +211,12 @@ struct NodeInfoView: View {
|
|||
.foregroundStyle(.secondary)
|
||||
.opacity(isLuminanceReduced ? 0.8 : 1.0)
|
||||
.fixedSize()
|
||||
Text("\(String(format: "Connected: %d of %d online", nodesOnline, nodes))")
|
||||
.font(.callout)
|
||||
.fontWeight(.medium)
|
||||
.foregroundStyle(.secondary)
|
||||
.opacity(isLuminanceReduced ? 0.8 : 1.0)
|
||||
.fixedSize()
|
||||
let now = Date()
|
||||
Text("Last Heard: \(now.formatted())")
|
||||
.font(.caption)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue