|
@@ -20,100 +20,9 @@ extension CGM {
|
|
|
Form {
|
|
Form {
|
|
|
if cgmCurrent.type != .none {
|
|
if cgmCurrent.type != .none {
|
|
|
if cgmCurrent.type == .nightscout {
|
|
if cgmCurrent.type == .nightscout {
|
|
|
- Section(
|
|
|
|
|
- header: Text("Configuration"),
|
|
|
|
|
- content: {
|
|
|
|
|
- VStack(alignment: .leading, spacing: 10) {
|
|
|
|
|
- Text("CGM is not used as heartbeat.").padding(.top)
|
|
|
|
|
-
|
|
|
|
|
- Text(
|
|
|
|
|
- state.url == nil ?
|
|
|
|
|
- "To configure your CGM, tap the button below. In the form that opens, enter your Nightscout credentials to connect to your instance." :
|
|
|
|
|
- "Tap the button below to open your Nightscout instance in your iPhone's default browser."
|
|
|
|
|
- ).font(.footnote)
|
|
|
|
|
- .foregroundColor(.secondary)
|
|
|
|
|
- .lineLimit(nil)
|
|
|
|
|
- .padding(.vertical)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if state.url == nil {
|
|
|
|
|
- NavigationLink(
|
|
|
|
|
- destination: NightscoutConfig.RootView(resolver: resolver, displayClose: false),
|
|
|
|
|
- label: { Text("Configure Nightscout").foregroundStyle(Color.accentColor) }
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- ).listRowBackground(Color.chart)
|
|
|
|
|
-
|
|
|
|
|
- if let url = state.url {
|
|
|
|
|
- Section {
|
|
|
|
|
- Button {
|
|
|
|
|
- UIApplication.shared.open(url, options: [:]) { success in
|
|
|
|
|
- if !success {
|
|
|
|
|
- self.router.alertMessage
|
|
|
|
|
- .send(MessageContent(
|
|
|
|
|
- content: "No URL available",
|
|
|
|
|
- type: .warning
|
|
|
|
|
- ))
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- label: {
|
|
|
|
|
- Label(
|
|
|
|
|
- "Open Nightscout",
|
|
|
|
|
- systemImage: "waveform.path.ecg.rectangle"
|
|
|
|
|
- ).font(.title3)
|
|
|
|
|
- .padding() }
|
|
|
|
|
- .frame(maxWidth: .infinity, alignment: .center)
|
|
|
|
|
- .buttonStyle(.bordered)
|
|
|
|
|
- }
|
|
|
|
|
- .listRowBackground(Color.clear)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ nightscoutSection
|
|
|
} else {
|
|
} else {
|
|
|
- Section(
|
|
|
|
|
- header: Text("Configuration"),
|
|
|
|
|
- content: {
|
|
|
|
|
- if cgmCurrent.type == .xdrip {
|
|
|
|
|
- VStack(alignment: .leading) {
|
|
|
|
|
- if let cgmTransmitterDeviceAddress = UserDefaults.standard
|
|
|
|
|
- .cgmTransmitterDeviceAddress
|
|
|
|
|
- {
|
|
|
|
|
- Text("CGM address :").padding(.top)
|
|
|
|
|
- Text(cgmTransmitterDeviceAddress)
|
|
|
|
|
- } else {
|
|
|
|
|
- Text("CGM is not used as heartbeat.").padding(.top)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- HStack(alignment: .center) {
|
|
|
|
|
- Text(
|
|
|
|
|
- "A heartbeat tells Trio to start a loop cycle. This is required for closed loop."
|
|
|
|
|
- )
|
|
|
|
|
- .font(.footnote)
|
|
|
|
|
- .foregroundColor(.secondary)
|
|
|
|
|
- .lineLimit(nil)
|
|
|
|
|
- Spacer()
|
|
|
|
|
- }.padding(.vertical)
|
|
|
|
|
- }
|
|
|
|
|
- } else if cgmCurrent.type == .simulator {
|
|
|
|
|
- Text(
|
|
|
|
|
- "Trio's glucose simulator does not offer any configuration. Its use is strictly for demonstration purposes only."
|
|
|
|
|
- )
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if let link = cgmCurrent.type.externalLink {
|
|
|
|
|
- Button {
|
|
|
|
|
- UIApplication.shared.open(link, options: [:], completionHandler: nil)
|
|
|
|
|
- } label: {
|
|
|
|
|
- HStack {
|
|
|
|
|
- Text("About this source")
|
|
|
|
|
- Spacer()
|
|
|
|
|
- Image(systemName: "chevron.right")
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- .frame(maxWidth: .infinity, alignment: .leading)
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
- ).listRowBackground(Color.chart)
|
|
|
|
|
|
|
+ customCGMSection
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if let appURL = cgmCurrent.type.appURL {
|
|
if let appURL = cgmCurrent.type.appURL {
|
|
@@ -146,7 +55,7 @@ extension CGM {
|
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
|
.toolbar {
|
|
.toolbar {
|
|
|
/// proper positioning should be .leading
|
|
/// proper positioning should be .leading
|
|
|
- /// but to keep this in line with LoopKit submodules, set placement to .trailing
|
|
|
|
|
|
|
+ /// LoopKit submodules set placement to .trailing; we'll keep it "proper" here
|
|
|
ToolbarItem(placement: .topBarLeading) {
|
|
ToolbarItem(placement: .topBarLeading) {
|
|
|
Button("Close") {
|
|
Button("Close") {
|
|
|
presentationMode.wrappedValue.dismiss()
|
|
presentationMode.wrappedValue.dismiss()
|
|
@@ -173,6 +82,107 @@ extension CGM {
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ var nightscoutSection: some View {
|
|
|
|
|
+ Group {
|
|
|
|
|
+ Section(
|
|
|
|
|
+ header: Text("Configuration"),
|
|
|
|
|
+ content: {
|
|
|
|
|
+ VStack(alignment: .leading, spacing: 10) {
|
|
|
|
|
+ Text("CGM is not used as heartbeat.").padding(.top)
|
|
|
|
|
+
|
|
|
|
|
+ Text(
|
|
|
|
|
+ state.url == nil ?
|
|
|
|
|
+ "To configure your CGM, tap the button below. In the form that opens, enter your Nightscout credentials to connect to your instance." :
|
|
|
|
|
+ "Tap the button below to open your Nightscout instance in your iPhone's default browser."
|
|
|
|
|
+ ).font(.footnote)
|
|
|
|
|
+ .foregroundColor(.secondary)
|
|
|
|
|
+ .lineLimit(nil)
|
|
|
|
|
+ .padding(.vertical)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if state.url == nil {
|
|
|
|
|
+ NavigationLink(
|
|
|
|
|
+ destination: NightscoutConfig.RootView(resolver: resolver, displayClose: false),
|
|
|
|
|
+ label: { Text("Configure Nightscout").foregroundStyle(Color.accentColor) }
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ ).listRowBackground(Color.chart)
|
|
|
|
|
+
|
|
|
|
|
+ if let url = state.url {
|
|
|
|
|
+ Section {
|
|
|
|
|
+ Button {
|
|
|
|
|
+ UIApplication.shared.open(url, options: [:]) { success in
|
|
|
|
|
+ if !success {
|
|
|
|
|
+ self.router.alertMessage
|
|
|
|
|
+ .send(MessageContent(
|
|
|
|
|
+ content: "No URL available",
|
|
|
|
|
+ type: .warning
|
|
|
|
|
+ ))
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ label: {
|
|
|
|
|
+ Label(
|
|
|
|
|
+ "Open Nightscout",
|
|
|
|
|
+ systemImage: "waveform.path.ecg.rectangle"
|
|
|
|
|
+ ).font(.title3)
|
|
|
|
|
+ .padding() }
|
|
|
|
|
+ .frame(maxWidth: .infinity, alignment: .center)
|
|
|
|
|
+ .buttonStyle(.bordered)
|
|
|
|
|
+ }
|
|
|
|
|
+ .listRowBackground(Color.clear)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ var customCGMSection: some View {
|
|
|
|
|
+ Section(
|
|
|
|
|
+ header: Text("Configuration"),
|
|
|
|
|
+ content: {
|
|
|
|
|
+ if cgmCurrent.type == .xdrip {
|
|
|
|
|
+ VStack(alignment: .leading) {
|
|
|
|
|
+ if let cgmTransmitterDeviceAddress = UserDefaults.standard
|
|
|
|
|
+ .cgmTransmitterDeviceAddress
|
|
|
|
|
+ {
|
|
|
|
|
+ Text("CGM address :").padding(.top)
|
|
|
|
|
+ Text(cgmTransmitterDeviceAddress)
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Text("CGM is not used as heartbeat.").padding(.top)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ HStack(alignment: .center) {
|
|
|
|
|
+ Text(
|
|
|
|
|
+ "A heartbeat tells Trio to start a loop cycle. This is required for closed loop."
|
|
|
|
|
+ )
|
|
|
|
|
+ .font(.footnote)
|
|
|
|
|
+ .foregroundColor(.secondary)
|
|
|
|
|
+ .lineLimit(nil)
|
|
|
|
|
+ Spacer()
|
|
|
|
|
+ }.padding(.vertical)
|
|
|
|
|
+ }
|
|
|
|
|
+ } else if cgmCurrent.type == .simulator {
|
|
|
|
|
+ Text(
|
|
|
|
|
+ "Trio's glucose simulator does not offer any configuration. Its use is strictly for demonstration purposes only."
|
|
|
|
|
+ )
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if let link = cgmCurrent.type.externalLink {
|
|
|
|
|
+ Button {
|
|
|
|
|
+ UIApplication.shared.open(link, options: [:], completionHandler: nil)
|
|
|
|
|
+ } label: {
|
|
|
|
|
+ HStack {
|
|
|
|
|
+ Text("About this source")
|
|
|
|
|
+ Spacer()
|
|
|
|
|
+ Image(systemName: "chevron.right")
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ .frame(maxWidth: .infinity, alignment: .leading)
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ ).listRowBackground(Color.chart)
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
var stickyDeleteButton: some View {
|
|
var stickyDeleteButton: some View {
|
|
|
ZStack {
|
|
ZStack {
|
|
|
Rectangle()
|
|
Rectangle()
|