Browse Source

Merge branch 'dev' into feat-staleissues

Sjoerd-Bo3 1 year ago
parent
commit
901685a3fd

+ 1 - 1
CGMBLEKit

@@ -1 +1 @@
-Subproject commit a92e9752994e7b143cdb007d3c7bcba0c0cc9214
+Subproject commit 15af9cf319bff2ac49c361da254ad667461d4687

+ 6 - 1
FreeAPS/Sources/Modules/DataTable/View/DataTableRootView.swift

@@ -316,7 +316,12 @@ extension DataTable {
                         state.units == .mmolL ? $0.asMmolL : Decimal($0)
                         state.units == .mmolL ? $0.asMmolL : Decimal($0)
                     ) as NSNumber)!
                     ) as NSNumber)!
                 } ?? "--")
                 } ?? "--")
-                Text(item.glucose.direction?.symbol ?? "--")
+                if item.glucose.type == "Manual" {
+                    Image(systemName: "drop.fill")
+                        .foregroundColor(Color.loopRed)
+                } else {
+                    Text(item.glucose.direction?.symbol ?? "--")
+                }
                 Spacer()
                 Spacer()
 
 
                 Text(dateFormatter.string(from: item.glucose.dateString))
                 Text(dateFormatter.string(from: item.glucose.dateString))

+ 52 - 2
FreeAPS/Sources/Modules/Home/View/Chart/MainChartView.swift

@@ -57,6 +57,7 @@ struct MainChartView: View {
     @State var didAppearTrigger = false
     @State var didAppearTrigger = false
     @State private var glucoseDots: [CGRect] = []
     @State private var glucoseDots: [CGRect] = []
     @State private var unSmoothedGlucoseDots: [CGRect] = []
     @State private var unSmoothedGlucoseDots: [CGRect] = []
+    @State private var manualGlucoseDots: [CGRect] = []
     @State private var predictionDots: [PredictionType: [CGRect]] = [:]
     @State private var predictionDots: [PredictionType: [CGRect]] = [:]
     @State private var bolusDots: [DotInfo] = []
     @State private var bolusDots: [DotInfo] = []
     @State private var bolusPath = Path()
     @State private var bolusPath = Path()
@@ -270,6 +271,7 @@ struct MainChartView: View {
                     bolusView(fullSize: fullSize)
                     bolusView(fullSize: fullSize)
                     if smooth { unSmoothedGlucoseView(fullSize: fullSize) }
                     if smooth { unSmoothedGlucoseView(fullSize: fullSize) }
                     glucoseView(fullSize: fullSize)
                     glucoseView(fullSize: fullSize)
+                    manualGlucoseView(fullSize: fullSize)
                     predictionsView(fullSize: fullSize)
                     predictionsView(fullSize: fullSize)
                 }
                 }
                 timeLabelsView(fullSize: fullSize)
                 timeLabelsView(fullSize: fullSize)
@@ -363,6 +365,32 @@ struct MainChartView: View {
         }
         }
     }
     }
 
 
+    private func manualGlucoseView(fullSize: CGSize) -> some View {
+        ZStack {
+            Path { path in
+                for rect in manualGlucoseDots {
+                    path.addEllipse(in: rect)
+                }
+            }
+            .fill(Color.loopRed)
+            Path { path in
+                for rect in manualGlucoseDots {
+                    path.addEllipse(in: rect)
+                }
+            }
+            .stroke(Color.primary, lineWidth: 0.5)
+        }
+        .onChange(of: glucose) { _ in
+            update(fullSize: fullSize)
+        }
+        .onChange(of: didAppearTrigger) { _ in
+            update(fullSize: fullSize)
+        }
+        .onReceive(Foundation.NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in
+            update(fullSize: fullSize)
+        }
+    }
+
     private func bolusView(fullSize: CGSize) -> some View {
     private func bolusView(fullSize: CGSize) -> some View {
         ZStack {
         ZStack {
             bolusPath
             bolusPath
@@ -489,6 +517,7 @@ extension MainChartView {
         calculatePredictionDots(fullSize: fullSize, type: .uam)
         calculatePredictionDots(fullSize: fullSize, type: .uam)
         calculateGlucoseDots(fullSize: fullSize)
         calculateGlucoseDots(fullSize: fullSize)
         calculateUnSmoothedGlucoseDots(fullSize: fullSize)
         calculateUnSmoothedGlucoseDots(fullSize: fullSize)
+        calculateManualGlucoseDots(fullSize: fullSize)
         calculateBolusDots(fullSize: fullSize)
         calculateBolusDots(fullSize: fullSize)
         calculateCarbsDots(fullSize: fullSize)
         calculateCarbsDots(fullSize: fullSize)
         calculateFPUsDots(fullSize: fullSize)
         calculateFPUsDots(fullSize: fullSize)
@@ -499,7 +528,10 @@ extension MainChartView {
 
 
     private func calculateGlucoseDots(fullSize: CGSize) {
     private func calculateGlucoseDots(fullSize: CGSize) {
         calculationQueue.async {
         calculationQueue.async {
-            let dots = glucose.concurrentMap { value -> CGRect in
+            let sgvs = glucose
+                .filter { $0.type != "Manual"
+                } // as fingerpricks will be drawn differently, slightly larger and red - so do not draw them here
+            let dots = sgvs.concurrentMap { value -> CGRect in
                 let position = glucoseToCoordinate(value, fullSize: fullSize)
                 let position = glucoseToCoordinate(value, fullSize: fullSize)
                 return CGRect(x: position.x - 2, y: position.y - 2, width: 4, height: 4)
                 return CGRect(x: position.x - 2, y: position.y - 2, width: 4, height: 4)
             }
             }
@@ -515,7 +547,8 @@ extension MainChartView {
 
 
     private func calculateUnSmoothedGlucoseDots(fullSize: CGSize) {
     private func calculateUnSmoothedGlucoseDots(fullSize: CGSize) {
         calculationQueue.async {
         calculationQueue.async {
-            let dots = glucose.concurrentMap { value -> CGRect in
+            let sgvs = glucose.filter { $0.type == "sgv" }
+            let dots = sgvs.concurrentMap { value -> CGRect in
                 let position = UnSmoothedGlucoseToCoordinate(value, fullSize: fullSize)
                 let position = UnSmoothedGlucoseToCoordinate(value, fullSize: fullSize)
                 return CGRect(x: position.x - 2, y: position.y - 2, width: 4, height: 4)
                 return CGRect(x: position.x - 2, y: position.y - 2, width: 4, height: 4)
             }
             }
@@ -529,6 +562,23 @@ extension MainChartView {
         }
         }
     }
     }
 
 
+    private func calculateManualGlucoseDots(fullSize: CGSize) {
+        calculationQueue.async {
+            let manuals = glucose.filter { $0.type == "Manual" }
+            let dots = manuals.concurrentMap { value -> CGRect in
+                let position = glucoseToCoordinate(value, fullSize: fullSize)
+                return CGRect(x: position.x - 2, y: position.y - 2, width: 6, height: 6)
+            }
+
+            let range = self.getGlucoseYRange(fullSize: fullSize)
+
+            DispatchQueue.main.async {
+                glucoseYRange = range
+                manualGlucoseDots = dots
+            }
+        }
+    }
+
     private func calculateBolusDots(fullSize: CGSize) {
     private func calculateBolusDots(fullSize: CGSize) {
         calculationQueue.async {
         calculationQueue.async {
             let dots = boluses.map { value -> DotInfo in
             let dots = boluses.map { value -> DotInfo in

+ 4 - 0
FreeAPS/Sources/Modules/NightscoutConfig/View/NightscoutUploadView.swift

@@ -13,6 +13,10 @@ struct NightscoutUploadView: View {
                         "The Upload Treatments toggle enables uploading of carbs, temp targets, device status, preferences and settings."
                         "The Upload Treatments toggle enables uploading of carbs, temp targets, device status, preferences and settings."
                     )
                     )
                     Text("\nThe Upload Glucose toggle enables uploading of CGM readings.")
                     Text("\nThe Upload Glucose toggle enables uploading of CGM readings.")
+
+                    if !state.changeUploadGlucose {
+                        Text("\nTo flip the Upload Glucose toggle, go to ⚙️ > CGM > CGM Configuration")
+                    }
                 }
                 }
             )
             )
                 {
                 {

+ 9 - 10
FreeAPS/Sources/Modules/TargetsEditor/TargetsEditorStateModel.swift

@@ -6,7 +6,7 @@ extension TargetsEditor {
 
 
         let timeValues = stride(from: 0.0, to: 1.days.timeInterval, by: 30.minutes.timeInterval).map { $0 }
         let timeValues = stride(from: 0.0, to: 1.days.timeInterval, by: 30.minutes.timeInterval).map { $0 }
 
 
-        var rateValues: [Double] {
+        var rateValues: [Decimal] {
             switch units {
             switch units {
             case .mgdL:
             case .mgdL:
                 return stride(from: 72, to: 180.01, by: 1.0).map { $0 }
                 return stride(from: 72, to: 180.01, by: 1.0).map { $0 }
@@ -27,8 +27,8 @@ extension TargetsEditor {
             units = profile.units
             units = profile.units
             items = profile.targets.map { value in
             items = profile.targets.map { value in
                 let timeIndex = timeValues.firstIndex(of: Double(value.offset * 60)) ?? 0
                 let timeIndex = timeValues.firstIndex(of: Double(value.offset * 60)) ?? 0
-                let lowIndex = rateValues.firstIndex(of: Double(value.low)) ?? 0
-                let highIndex = lowIndex
+                let lowIndex = rateValues.firstIndex(of: value.low) ?? 0
+                let highIndex = rateValues.firstIndex(of: value.high) ?? 0
                 return Item(lowIndex: lowIndex, highIndex: highIndex, timeIndex: timeIndex)
                 return Item(lowIndex: lowIndex, highIndex: highIndex, timeIndex: timeIndex)
             }
             }
         }
         }
@@ -50,14 +50,14 @@ extension TargetsEditor {
 
 
         func save() {
         func save() {
             let targets = items.map { item -> BGTargetEntry in
             let targets = items.map { item -> BGTargetEntry in
-                let fotmatter = DateFormatter()
-                fotmatter.timeZone = TimeZone(secondsFromGMT: 0)
-                fotmatter.dateFormat = "HH:mm:ss"
+                let formatter = DateFormatter()
+                formatter.timeZone = TimeZone(secondsFromGMT: 0)
+                formatter.dateFormat = "HH:mm:ss"
                 let date = Date(timeIntervalSince1970: self.timeValues[item.timeIndex])
                 let date = Date(timeIntervalSince1970: self.timeValues[item.timeIndex])
                 let minutes = Int(date.timeIntervalSince1970 / 60)
                 let minutes = Int(date.timeIntervalSince1970 / 60)
-                let low = Decimal(self.rateValues[item.lowIndex])
+                let low = self.rateValues[item.lowIndex]
                 let high = low
                 let high = low
-                return BGTargetEntry(low: low, high: high, start: fotmatter.string(from: date), offset: minutes)
+                return BGTargetEntry(low: low, high: high, start: formatter.string(from: date), offset: minutes)
             }
             }
             let profile = BGTargets(units: units, userPrefferedUnits: settingsManager.settings.units, targets: targets)
             let profile = BGTargets(units: units, userPrefferedUnits: settingsManager.settings.units, targets: targets)
             provider.saveProfile(profile)
             provider.saveProfile(profile)
@@ -68,8 +68,7 @@ extension TargetsEditor {
                 let uniq = Array(Set(self.items))
                 let uniq = Array(Set(self.items))
                 let sorted = uniq.sorted { $0.timeIndex < $1.timeIndex }
                 let sorted = uniq.sorted { $0.timeIndex < $1.timeIndex }
                     .map { item -> Item in
                     .map { item -> Item in
-                        guard item.highIndex < item.lowIndex else { return item }
-                        return Item(lowIndex: item.lowIndex, highIndex: item.lowIndex, timeIndex: item.timeIndex)
+                        Item(lowIndex: item.lowIndex, highIndex: item.highIndex, timeIndex: item.timeIndex)
                     }
                     }
                 sorted.first?.timeIndex = 0
                 sorted.first?.timeIndex = 0
                 self.items = sorted
                 self.items = sorted

+ 18 - 16
Gemfile.lock

@@ -5,22 +5,22 @@ GEM
       base64
       base64
       nkf
       nkf
       rexml
       rexml
-    addressable (2.8.6)
-      public_suffix (>= 2.0.2, < 6.0)
+    addressable (2.8.7)
+      public_suffix (>= 2.0.2, < 7.0)
     artifactory (3.0.17)
     artifactory (3.0.17)
     atomos (0.1.3)
     atomos (0.1.3)
     aws-eventstream (1.3.0)
     aws-eventstream (1.3.0)
-    aws-partitions (1.921.0)
-    aws-sdk-core (3.193.0)
+    aws-partitions (1.949.0)
+    aws-sdk-core (3.200.0)
       aws-eventstream (~> 1, >= 1.3.0)
       aws-eventstream (~> 1, >= 1.3.0)
       aws-partitions (~> 1, >= 1.651.0)
       aws-partitions (~> 1, >= 1.651.0)
       aws-sigv4 (~> 1.8)
       aws-sigv4 (~> 1.8)
       jmespath (~> 1, >= 1.6.1)
       jmespath (~> 1, >= 1.6.1)
-    aws-sdk-kms (1.80.0)
-      aws-sdk-core (~> 3, >= 3.193.0)
+    aws-sdk-kms (1.87.0)
+      aws-sdk-core (~> 3, >= 3.199.0)
       aws-sigv4 (~> 1.1)
       aws-sigv4 (~> 1.1)
-    aws-sdk-s3 (1.148.0)
-      aws-sdk-core (~> 3, >= 3.193.0)
+    aws-sdk-s3 (1.155.0)
+      aws-sdk-core (~> 3, >= 3.199.0)
       aws-sdk-kms (~> 1)
       aws-sdk-kms (~> 1)
       aws-sigv4 (~> 1.8)
       aws-sigv4 (~> 1.8)
     aws-sigv4 (1.8.0)
     aws-sigv4 (1.8.0)
@@ -69,7 +69,7 @@ GEM
     faraday_middleware (1.2.0)
     faraday_middleware (1.2.0)
       faraday (~> 1.0)
       faraday (~> 1.0)
     fastimage (2.3.1)
     fastimage (2.3.1)
-    fastlane (2.220.0)
+    fastlane (2.221.1)
       CFPropertyList (>= 2.3, < 4.0.0)
       CFPropertyList (>= 2.3, < 4.0.0)
       addressable (>= 2.8, < 3.0.0)
       addressable (>= 2.8, < 3.0.0)
       artifactory (~> 3.0)
       artifactory (~> 3.0)
@@ -148,31 +148,32 @@ GEM
       os (>= 0.9, < 2.0)
       os (>= 0.9, < 2.0)
       signet (>= 0.16, < 2.a)
       signet (>= 0.16, < 2.a)
     highline (2.0.3)
     highline (2.0.3)
-    http-cookie (1.0.5)
+    http-cookie (1.0.6)
       domain_name (~> 0.5)
       domain_name (~> 0.5)
     httpclient (2.8.3)
     httpclient (2.8.3)
     jmespath (1.6.2)
     jmespath (1.6.2)
     json (2.7.2)
     json (2.7.2)
-    jwt (2.8.1)
+    jwt (2.8.2)
       base64
       base64
-    mini_magick (4.12.0)
+    mini_magick (4.13.1)
     mini_mime (1.1.5)
     mini_mime (1.1.5)
     multi_json (1.15.0)
     multi_json (1.15.0)
-    multipart-post (2.4.0)
+    multipart-post (2.4.1)
     nanaimo (0.3.0)
     nanaimo (0.3.0)
     naturally (2.2.1)
     naturally (2.2.1)
     nkf (0.2.0)
     nkf (0.2.0)
     optparse (0.5.0)
     optparse (0.5.0)
     os (1.1.4)
     os (1.1.4)
     plist (3.7.1)
     plist (3.7.1)
-    public_suffix (5.0.5)
+    public_suffix (5.1.1)
     rake (13.2.1)
     rake (13.2.1)
     representable (3.2.0)
     representable (3.2.0)
       declarative (< 0.1.0)
       declarative (< 0.1.0)
       trailblazer-option (>= 0.1.1, < 0.2.0)
       trailblazer-option (>= 0.1.1, < 0.2.0)
       uber (< 0.2.0)
       uber (< 0.2.0)
     retriable (3.1.2)
     retriable (3.1.2)
-    rexml (3.2.6)
+    rexml (3.2.9)
+      strscan
     rouge (2.0.7)
     rouge (2.0.7)
     ruby2_keywords (0.0.5)
     ruby2_keywords (0.0.5)
     rubyzip (2.3.2)
     rubyzip (2.3.2)
@@ -185,6 +186,7 @@ GEM
     simctl (1.6.10)
     simctl (1.6.10)
       CFPropertyList
       CFPropertyList
       naturally
       naturally
+    strscan (3.1.0)
     terminal-notifier (2.0.0)
     terminal-notifier (2.0.0)
     terminal-table (3.0.2)
     terminal-table (3.0.2)
       unicode-display_width (>= 1.1.1, < 3)
       unicode-display_width (>= 1.1.1, < 3)
@@ -222,4 +224,4 @@ DEPENDENCIES
   fastlane
   fastlane
 
 
 BUNDLED WITH
 BUNDLED WITH
-   2.4.19
+   2.4.19

+ 4 - 6
fastlane/Fastfile

@@ -184,24 +184,22 @@ platform :ios do
       }
       }
     end
     end
 
 
-    configure_bundle_id("FreeAPS", "#{BUNDLE_ID}", [
+    configure_bundle_id("Trio", "#{BUNDLE_ID}", [
       Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS,
       Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS,
       Spaceship::ConnectAPI::BundleIdCapability::Type::HEALTHKIT,
       Spaceship::ConnectAPI::BundleIdCapability::Type::HEALTHKIT,
       Spaceship::ConnectAPI::BundleIdCapability::Type::NFC_TAG_READING
       Spaceship::ConnectAPI::BundleIdCapability::Type::NFC_TAG_READING
     ])
     ])
 
 
-    configure_bundle_id("FreeAPSWatch WatchKit Extension", "#{BUNDLE_ID}.watchkitapp.watchkitextension", [
+    configure_bundle_id("Trio WatchKit Extension", "#{BUNDLE_ID}.watchkitapp.watchkitextension", [
       Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS,
       Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS,
       Spaceship::ConnectAPI::BundleIdCapability::Type::HEALTHKIT
       Spaceship::ConnectAPI::BundleIdCapability::Type::HEALTHKIT
     ])
     ])
     
     
-    configure_bundle_id("FreeAPSWatch", "#{BUNDLE_ID}.watchkitapp", [
+    configure_bundle_id("Trio Watch", "#{BUNDLE_ID}.watchkitapp", [
       Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS
       Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS
     ])
     ])
 
 
-    configure_bundle_id("LiveActivityExtension", "#{BUNDLE_ID}.LiveActivity", [
-      Spaceship::ConnectAPI::BundleIdCapability::Type::APP_GROUPS
-    ])
+    configure_bundle_id("Trio LiveActivity", "#{BUNDLE_ID}.LiveActivity", [])
     
     
   end
   end
 
 

+ 71 - 23
fastlane/testflight.md

@@ -2,7 +2,7 @@
 
 
 These instructions allow you to build Trio without having access to a Mac.
 These instructions allow you to build Trio without having access to a Mac.
 
 
-* You can install Trio on phones via TestFlight that are not connected to your computer
+* You can install Trio on phones using TestFlight that are not connected to your computer
 * You can send builds and updates to those you care for
 * You can send builds and updates to those you care for
 * You can install Trio on your phone using only the TestFlight app if a phone was lost or the app is accidentally deleted
 * You can install Trio on your phone using only the TestFlight app if a phone was lost or the app is accidentally deleted
 * You do not need to worry about specific Xcode/Mac versions for a given iOS
 * You do not need to worry about specific Xcode/Mac versions for a given iOS
@@ -22,12 +22,14 @@ These instructions allow you to build Trio without having access to a Mac.
 
 
 The setup steps are somewhat involved, but nearly all are one time steps. Subsequent builds are trivial. Your app must be updated once every 90 days, but it's a simple click to make a new build and can be done from anywhere.
 The setup steps are somewhat involved, but nearly all are one time steps. Subsequent builds are trivial. Your app must be updated once every 90 days, but it's a simple click to make a new build and can be done from anywhere.
 
 
-Note that TestFlight requires apple id accounts 13 years or older. This can be circumvented by logging into Media & Purchase on the child's phone with an adult's account. More details on this can be found in [LoopDocs](https://loopkit.github.io/loopdocs/gh-actions/gh-deploy/#install-testflight-loop-for-child).
+Note that installing with TestFlight requires the Apple ID account holder for the phone be 13 years or older (age varies with country). This can be circumvented by logging into Media & Purchase on the child's phone with an adult's account. More details on this can be found in [LoopDocs](https://loopkit.github.io/loopdocs/gh-actions/gh-deploy/#install-testflight-loop-for-child).
 
 
 This method for building without a Mac was ported from Loop. If you have used this method for Loop or one of the other DIY apps (Loop Caregiver, Loop Follow, Xdrip4iOS), some of the steps can be re-used and the full set of instructions does not need to be repeated. This will be mentioned in relevant sections below.
 This method for building without a Mac was ported from Loop. If you have used this method for Loop or one of the other DIY apps (Loop Caregiver, Loop Follow, Xdrip4iOS), some of the steps can be re-used and the full set of instructions does not need to be repeated. This will be mentioned in relevant sections below.
 
 
 There are more detailed instructions in LoopDocs for doing Browser Builds of Loop and other apps, including troubleshooting and build errors. Please refer to [LoopDocs](https://loopkit.github.io/loopdocs/gh-actions/gh-other-apps/) for more details.
 There are more detailed instructions in LoopDocs for doing Browser Builds of Loop and other apps, including troubleshooting and build errors. Please refer to [LoopDocs](https://loopkit.github.io/loopdocs/gh-actions/gh-other-apps/) for more details.
 
 
+If you build multiple apps, you may want to use a free *GitHub* organization. Please refer to [LoopDocs: Use a *GitHub* Organization Account](https://loopkit.github.io/loopdocs/gh-actions/gh-other-apps/#use-a-github-organization-account).
+
 ## Prerequisites
 ## Prerequisites
 
 
 * A [github account](https://github.com/signup). The free level comes with plenty of storage and free compute time to build Trio, multiple times a day, if you wanted to.
 * A [github account](https://github.com/signup). The free level comes with plenty of storage and free compute time to build Trio, multiple times a day, if you wanted to.
@@ -44,6 +46,8 @@ You require 6 Secrets (alphanumeric items) to use the GitHub build method and if
 * Be sure to save the 6 Secrets in a text file using a text editor
 * Be sure to save the 6 Secrets in a text file using a text editor
     - Do **NOT** use a smart editor, which might auto-correct and change case, because these Secrets are case sensitive
     - Do **NOT** use a smart editor, which might auto-correct and change case, because these Secrets are case sensitive
 
 
+Refer to [LoopDocs: Make a Secrets Reference File](https://loopkit.github.io/loopdocs/gh-actions/gh-first-time/#make-a-secrets-reference-file) for a handy template to use when saving your Secrets.
+
 ## Generate App Store Connect API Key
 ## Generate App Store Connect API Key
 
 
 This step is common for all GitHub Browser Builds; do this step only once. You will be saving 4 Secrets from your Apple Account in this step.
 This step is common for all GitHub Browser Builds; do this step only once. You will be saving 4 Secrets from your Apple Account in this step.
@@ -57,7 +61,7 @@ This step is common for all GitHub Browser Builds; do this step only once. You w
 
 
 ## Create GitHub Personal Access Token
 ## Create GitHub Personal Access Token
 
 
-If you have previously built another app using the "browser build" method, you can can re-use your previous personal access token (`GH_PAT`) and skip this step.
+If you have previously built another app using the "browser build" method, you use the same personal access token (`GH_PAT`), so skip this step.
 
 
 Log into your GitHub account to create a personal access token; this is one of two GitHub secrets needed for your build.
 Log into your GitHub account to create a personal access token; this is one of two GitHub secrets needed for your build.
 
 
@@ -72,18 +76,14 @@ Log into your GitHub account to create a personal access token; this is one of t
 
 
 This is the second one of two GitHub secrets needed for your build.
 This is the second one of two GitHub secrets needed for your build.
 
 
-The first time you build with the GitHub Browser Build method for any DIY app, you will make up a password and record it as `MATCH_PASSWORD`. Note, if you later lose `MATCH_PASSWORD`, you will need to delete and make a new Match-Secrets repository (next step).
-
-## Setup GitHub Match-Secrets Repository
+The first time you build with the GitHub Browser Build method for any DIY app, you will make up a password and record it as `MATCH_PASSWORD`. You use the same password for all DIY apps. Note, if you later lose `MATCH_PASSWORD`, you will need to delete your Match-Secrets repository (automatically created), and go through the GitHub actions again.
 
 
-The creation of the Match-Secrets repository is a common step for all GitHub Browser Builds; do this step only once. You must be logged into your GitHub account.
+## GitHub Match-Secrets Repository
 
 
-1. Create a [new empty repository](https://github.com/new) titled `Match-Secrets`. It should be private.
-
-Once created, you will not take any direct actions with this repository; it needs to be there for the GitHub to use as you progress through the steps.
+> A private Match-Secrets repository is automatically created under your GitHub username the first time you run a GitHub Action. Because it is a private repository - only you can see it. You will not take any direct actions with this repository; it needs to be there for GitHub to use as you progress through the steps.
 
 
 ## Setup Github Trio repository
 ## Setup Github Trio repository
-1. Fork https://github.com/nightscout/Trio into your account. If you already have a fork of Trio in GitHub, you can't make another one. You can continue to work with your existing fork, or delete that from GitHub and then and fork https://github.com/nightscout/Trio.
+1. Fork https://github.com/nightscout/Trio into your account. If you already have a fork of Trio in GitHub, you can't make another one. You can continue to work with your existing fork, or delete that from GitHub and then fork https://github.com/nightscout/Trio.
 1. In the forked Trio repo, go to Settings -> Secrets and variables -> Actions.
 1. In the forked Trio repo, go to Settings -> Secrets and variables -> Actions.
 1. For each of the following secrets, tap on "New repository secret", then add the name of the secret, along with the value you recorded for it:
 1. For each of the following secrets, tap on "New repository secret", then add the name of the secret, along with the value you recorded for it:
     * `TEAMID`
     * `TEAMID`
@@ -95,7 +95,7 @@ Once created, you will not take any direct actions with this repository; it need
 
 
 ## Validate repository secrets
 ## Validate repository secrets
 
 
-This step validates most of your six Secrets and provides error messages if it detects an issue with one or more.
+This step validates most of your six Secrets and provides error messages if it detects an issue with one or more. In addition, if you do not have a private Match-Secrets repository it creates one for you.
 
 
 1. Click on the "Actions" tab of your Trio repository and enable workflows if needed
 1. Click on the "Actions" tab of your Trio repository and enable workflows if needed
 1. On the left side, select "1. Validate Secrets".
 1. On the left side, select "1. Validate Secrets".
@@ -103,6 +103,8 @@ This step validates most of your six Secrets and provides error messages if it d
 1. Wait, and within a minute or two you should see a green checkmark indicating the workflow succeeded.
 1. Wait, and within a minute or two you should see a green checkmark indicating the workflow succeeded.
 1. The workflow will check if the required secrets are added and that they are correctly formatted. If errors are detected, please check the run log for details.
 1. The workflow will check if the required secrets are added and that they are correctly formatted. If errors are detected, please check the run log for details.
 
 
+> There can be a delay after you start a workflow before the screen changes. Refresh your browser to see if it started. And if it seems to take a long time to finish - refresh your browser to see if it is done.
+
 ## Add Identifiers for Trio App
 ## Add Identifiers for Trio App
 
 
 1. Click on the "Actions" tab of your Trio repository.
 1. Click on the "Actions" tab of your Trio repository.
@@ -112,32 +114,78 @@ This step validates most of your six Secrets and provides error messages if it d
 
 
 ## Create App Group
 ## Create App Group
 
 
-If you have already built Trio via Xcode using this Apple ID, you can skip on to [Create Trio App in App Store Connect](#create-trio-app-in-app-store-connect).
-_Please note that in default builds of Trio, the app group is actually identical to the one used with Loop, so please enter these details exactly as described below. This is to ease the setup of apps such as Xdrip4iOS. It may require some caution if transfering between Trio and Loop._
+If you previously built Trio using Mac with Xcode with this Apple ID, skip ahead to [Optional: App Group Description Modification](#optional-app-group-description-modification).
+
+_Please note that Trio uses the same app group as Loop. This enables other apps such as Xdrip4iOS to share data with Trio. It may require some caution if transfering between Trio and Loop._
 
 
 1. Go to [Register an App Group](https://developer.apple.com/account/resources/identifiers/applicationGroup/add/) on the apple developer site.
 1. Go to [Register an App Group](https://developer.apple.com/account/resources/identifiers/applicationGroup/add/) on the apple developer site.
 1. For Description, use "Loop App Group".
 1. For Description, use "Loop App Group".
 1. For Identifier, enter "group.com.TEAMID.loopkit.LoopGroup", substituting your team id for `TEAMID`.
 1. For Identifier, enter "group.com.TEAMID.loopkit.LoopGroup", substituting your team id for `TEAMID`.
+    * If you are told that this group already exists, skip ahead to [Optional: App Group Description Modification](#optional-app-group-description-modification)
 1. Click "Continue" and then "Register".
 1. Click "Continue" and then "Register".
 
 
+### Optional: App Group Description Modification
+
+> This step is not required, but if you previously built using a Mac with Xcode, it is a good idea to update the **NAME** associated with the **IDENTIFIER** for the Loop App Group. Notice in the table below that the XCode version of the **NAME** is the same as the **IDENTIFIER** but with the `.` replaced with a space.
+
+_Referring to the link and table below, tap on the **IDENTIFIER** for the `Loop App Group`, edit the Description to match the **NAME**, then Save the change._
+
+* [App Group List](https://developer.apple.com/account/resources/identifiers/list/applicationGroup)
+
+| NAME | XCode version | IDENTIFIER |
+|:--|:--|:--|
+| Loop App Group | group com TEAMID loopkit LoopGroup| group.com.TEAMID.loopkit.LoopGroup |
+
+## Bundle Identifiers
+
+Open this link in a separate browser window:
+
+* [Certificates, Identifiers & Profiles](https://developer.apple.com/account/resources/identifiers/list) on the Apple developer site
+* You will select each of the Identifiers as instructed below, modify it if needed and then save it.
+
+### Optional: Identifier Description Modification
+
+> This step is not required, but if you previously built using a Mac with Xcode or during early Beta testing for Trio, it is a good idea to update the **NAME** associated with each **IDENTIFIER** to match the table below.
+
+_Referring to the table below, tap on each **IDENTIFIER** that has a different **NAME**, edit the Description to match the **NAME**, then Save the change for that identifier._
+
+#### Table of Identifiers
+
+* If you built previously using a Mac with Xcode, you may see the XCode version in your **NAME** column - it starts with XC and then the **IDENTIFIER** is appended where the `.` is replaced with a space, the example for Trio is shown in detail
+* If you built during early beta testing, you might not have `Trio` at the beginning of each **IDENTIFIER** and the full **NAME** may be slightly different
+
+| NAME | XCode version | IDENTIFIER |
+|:--|:--|:--|
+| Trio | XC org nightscout TEAMID trio | org.nightscout.TEAMID.trio |
+| Trio LiveActivity | - | org.nightscout.TEAMID.trio.LiveActivity |
+| Trio Watch | XC IDENTIFIER | org.nightscout.TEAMID.trio.watchkitapp |
+| Trio WatchKit Extension | XC IDENTIFIER | org.nightscout.TEAMID.trio.watchkitapp.watchkitextension |
+
 ## Add App Group to Bundle Identifiers
 ## Add App Group to Bundle Identifiers
 
 
+> This step is required for first-time builders using GitHub Actions (Browser Build).
+
+> If you previously built using a Mac with Xcode you can skip ahead to [Create Trio App in App Store Connect](#create-trio-app-in-app-store-connect).
+
 1. Go to [Certificates, Identifiers & Profiles](https://developer.apple.com/account/resources/identifiers/list) on the Apple developer site.
 1. Go to [Certificates, Identifiers & Profiles](https://developer.apple.com/account/resources/identifiers/list) on the Apple developer site.
-1. For each of the following identifier names:
-    * FreeAPS
-    * FreeAPS watchkitapp
-    * FreeAPS watchkitapp watchkitextension
-1. Click on the identifier's name.
-1. On the "App Groups" capabilies, click on the "Configure" button.
-1. Select the "Loop App Group" _(yes, "Loop App Group" is correct)_
+1. Repeat this step for these three Identifier **NAMES** - refer to the [Table](#table-of-identifiers) above if your Names look different; if they do, see [Optional: Identifier Description Modification](#optional-identifier-description-modification)
+    * Trio
+    * Trio Watch
+    * Trio WatchKit Extension
+1. Click on the **IDENTIFIER** row.
+1. Scroll down to the "App Groups" capabilies row, click on the "Configure" (or "Edit") button.
+1. Select (or verify the selection for) the "Loop App Group" _(yes, "Loop App Group" is correct)_
 1. Click "Continue".
 1. Click "Continue".
 1. Click "Save".
 1. Click "Save".
 1. Click "Confirm".
 1. Click "Confirm".
-1. Remember to do this for each of the identifiers above.
+1. Remember to do this for each of three identifiers listed under step 2.
+
+There is an additional identifier, but it does not need the App Group added to it:
+* Trio LiveActivity
 
 
 ## Create Trio App in App Store Connect
 ## Create Trio App in App Store Connect
 
 
-If you have created a Trio app in App Store Connect before, you can skip this section as well.
+If you created a Trio app in App Store Connect before, skip ahead to [Create Building Certficates](#create-building-certficates).
 
 
 1. Go to the [apps list](https://appstoreconnect.apple.com/apps) on App Store Connect and click the blue "plus" icon to create a New App.
 1. Go to the [apps list](https://appstoreconnect.apple.com/apps) on App Store Connect and click the blue "plus" icon to create a New App.
     * Select "iOS".
     * Select "iOS".