Explorar o código

Merge remote-tracking branch 'ivalkou/dev' into Crowdin

Jon B.M %!s(int64=4) %!d(string=hai) anos
pai
achega
3385b2a369

+ 1 - 1
Config.xcconfig

@@ -1,5 +1,5 @@
 APP_DISPLAY_NAME = FreeAPS X
-BUILD_VERSION = 0.2.5
+BUILD_VERSION = 0.2.6
 DEVELOPER_TEAM = ##TEAM_ID##
 BUNDLE_IDENTIFIER = ru.artpancreas.$(DEVELOPMENT_TEAM).FreeAPS
 APP_GROUP_ID = group.com.$(DEVELOPMENT_TEAM).loopkit.LoopGroup

+ 25 - 0
FreeAPS/Sources/AnimatedBackground/SnowScene.swift

@@ -1,3 +1,4 @@
+import Foundation
 import SpriteKit
 
 class SnowScene: SKScene {
@@ -9,6 +10,22 @@ class SnowScene: SKScene {
         snowEmitterNode.particleLifetime = 2
         snowEmitterNode.particleLifetimeRange = 6
         addChild(snowEmitterNode)
+        subscribe()
+    }
+
+    private func subscribe() {
+        Foundation.NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(didEnterBackground),
+            name: UIApplication.didEnterBackgroundNotification,
+            object: nil
+        )
+        Foundation.NotificationCenter.default.addObserver(
+            self,
+            selector: #selector(willEnterForeground),
+            name: UIApplication.willEnterForegroundNotification,
+            object: nil
+        )
     }
 
     override func didChangeSize(_: CGSize) {
@@ -16,4 +33,12 @@ class SnowScene: SKScene {
         snowEmitterNode.particlePosition = CGPoint(x: size.width / 2, y: size.height)
         snowEmitterNode.particlePositionRange = CGVector(dx: size.width, dy: size.height)
     }
+
+    @objc private func didEnterBackground() {
+        isPaused = true
+    }
+
+    @objc private func willEnterForeground() {
+        isPaused = false
+    }
 }

+ 86 - 72
FreeAPS/Sources/Modules/Home/View/HomeRootView.swift

@@ -37,82 +37,100 @@ extension Home {
             return scene
         }
 
-        var header: some View {
+        @ViewBuilder func header(_ geo: GeometryProxy) -> some View {
             HStack(alignment: .bottom) {
                 Spacer()
-                VStack(alignment: .leading, spacing: 12) {
-                    HStack {
-                        Text("IOB").font(.caption2).foregroundColor(.secondary)
-                        Text(
-                            (numberFormatter.string(from: (state.suggestion?.iob ?? 0) as NSNumber) ?? "0") +
-                                NSLocalizedString(" U", comment: "Insulin unit")
-                        )
-                        .font(.system(size: 12, weight: .bold))
-                    }
-                    HStack {
-                        Text("COB").font(.caption2).foregroundColor(.secondary)
-                        Text(
-                            (numberFormatter.string(from: (state.suggestion?.cob ?? 0) as NSNumber) ?? "0") +
-                                NSLocalizedString(" g", comment: "gram of carbs")
-                        )
-                        .font(.system(size: 12, weight: .bold))
-                    }
-                }
+                cobIobView
+                Spacer()
+                glucoseView
+                Spacer()
+                pumpView
                 Spacer()
+                loopView
+                Spacer()
+            }
+            .frame(maxWidth: .infinity)
+            .frame(maxHeight: 70)
+            .padding(.top, geo.safeAreaInsets.top)
+            .background(Color.gray.opacity(0.2))
+        }
 
-                CurrentGlucoseView(
-                    recentGlucose: $state.recentGlucose,
-                    delta: $state.glucoseDelta,
-                    units: $state.units,
-                    alarm: $state.alarm
-                )
-                .onTapGesture {
-                    if state.alarm == nil {
-                        state.openCGM()
-                    } else {
-                        state.showModal(for: .snooze)
-                    }
+        var cobIobView: some View {
+            VStack(alignment: .leading, spacing: 12) {
+                HStack {
+                    Text("IOB").font(.caption2).foregroundColor(.secondary)
+                    Text(
+                        (numberFormatter.string(from: (state.suggestion?.iob ?? 0) as NSNumber) ?? "0") +
+                            NSLocalizedString(" U", comment: "Insulin unit")
+                    )
+                    .font(.system(size: 12, weight: .bold))
                 }
-                .onLongPressGesture {
-                    let impactHeavy = UIImpactFeedbackGenerator(style: .heavy)
-                    impactHeavy.impactOccurred()
-                    if state.alarm == nil {
-                        state.showModal(for: .snooze)
-                    } else {
-                        state.openCGM()
-                    }
+                HStack {
+                    Text("COB").font(.caption2).foregroundColor(.secondary)
+                    Text(
+                        (numberFormatter.string(from: (state.suggestion?.cob ?? 0) as NSNumber) ?? "0") +
+                            NSLocalizedString(" g", comment: "gram of carbs")
+                    )
+                    .font(.system(size: 12, weight: .bold))
                 }
+            }
+        }
 
-                Spacer()
-                PumpView(
-                    reservoir: $state.reservoir,
-                    battery: $state.battery,
-                    name: $state.pumpName,
-                    expiresAtDate: $state.pumpExpiresAtDate,
-                    timerDate: $state.timerDate
-                )
-                .onTapGesture {
-                    if state.pumpDisplayState != nil {
-                        state.setupPump = true
-                    }
+        var glucoseView: some View {
+            CurrentGlucoseView(
+                recentGlucose: $state.recentGlucose,
+                delta: $state.glucoseDelta,
+                units: $state.units,
+                alarm: $state.alarm
+            )
+            .onTapGesture {
+                if state.alarm == nil {
+                    state.openCGM()
+                } else {
+                    state.showModal(for: .snooze)
                 }
-                Spacer()
-                LoopView(
-                    suggestion: $state.suggestion,
-                    enactedSuggestion: $state.enactedSuggestion,
-                    closedLoop: $state.closedLoop,
-                    timerDate: $state.timerDate,
-                    isLooping: $state.isLooping,
-                    lastLoopDate: $state.lastLoopDate
-                ).onTapGesture {
-                    isStatusPopupPresented = true
-                }.onLongPressGesture {
-                    let impactHeavy = UIImpactFeedbackGenerator(style: .heavy)
-                    impactHeavy.impactOccurred()
-                    state.runLoop()
+            }
+            .onLongPressGesture {
+                let impactHeavy = UIImpactFeedbackGenerator(style: .heavy)
+                impactHeavy.impactOccurred()
+                if state.alarm == nil {
+                    state.showModal(for: .snooze)
+                } else {
+                    state.openCGM()
                 }
-                Spacer()
-            }.frame(maxWidth: .infinity)
+            }
+        }
+
+        var pumpView: some View {
+            PumpView(
+                reservoir: $state.reservoir,
+                battery: $state.battery,
+                name: $state.pumpName,
+                expiresAtDate: $state.pumpExpiresAtDate,
+                timerDate: $state.timerDate
+            )
+            .onTapGesture {
+                if state.pumpDisplayState != nil {
+                    state.setupPump = true
+                }
+            }
+        }
+
+        var loopView: some View {
+            LoopView(
+                suggestion: $state.suggestion,
+                enactedSuggestion: $state.enactedSuggestion,
+                closedLoop: $state.closedLoop,
+                timerDate: $state.timerDate,
+                isLooping: $state.isLooping,
+                lastLoopDate: $state.lastLoopDate
+            ).onTapGesture {
+                isStatusPopupPresented = true
+            }.onLongPressGesture {
+                let impactHeavy = UIImpactFeedbackGenerator(style: .heavy)
+                impactHeavy.impactOccurred()
+                state.runLoop()
+            }
         }
 
         var infoPanal: some View {
@@ -330,11 +348,7 @@ extension Home {
         var body: some View {
             GeometryReader { geo in
                 VStack(spacing: 0) {
-                    header
-                        .frame(maxHeight: 70)
-                        .padding(.top, geo.safeAreaInsets.top)
-                        .background(Color.gray.opacity(0.2))
-
+                    header(geo)
                     infoPanal
                     mainChart
                     legendPanal

+ 17 - 2
FreeAPS/Sources/Views/DecimalTextField.swift

@@ -1,3 +1,4 @@
+import Combine
 import SwiftUI
 
 struct DecimalTextField: UIViewRepresentable {
@@ -62,8 +63,11 @@ struct DecimalTextField: UIViewRepresentable {
         return textfield
     }
 
-    func updateUIView(_ textField: UITextField, context _: Context) {
-        if value != 0 {
+    func updateUIView(_ textField: UITextField, context: Context) {
+        let coordinator = context.coordinator
+        if coordinator.isEditing {
+            coordinator.resetEditing()
+        } else if value != 0 {
             textField.text = formatter.string(for: value)
         }
     }
@@ -79,6 +83,15 @@ struct DecimalTextField: UIViewRepresentable {
             parent = textField
         }
 
+        private(set) var isEditing = false
+        private var editingCancellable: AnyCancellable?
+
+        func resetEditing() {
+            editingCancellable = Just(false)
+                .delay(for: 0.5, scheduler: DispatchQueue.main)
+                .weakAssign(to: \.isEditing, on: self)
+        }
+
         func textField(
             _ textField: UITextField,
             shouldChangeCharactersIn range: NSRange,
@@ -106,6 +119,7 @@ struct DecimalTextField: UIViewRepresentable {
 
                 // Set Value
                 let double = number.doubleValue
+                isEditing = true
                 parent.value = Decimal(double)
             }
 
@@ -118,6 +132,7 @@ struct DecimalTextField: UIViewRepresentable {
         ) {
             // Format value with formatter at End Editing
             textField.text = parent.formatter.string(for: parent.value)
+            isEditing = false
         }
     }
 }