forked from JohanDegraeve/xdripswift
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'JohanDegraeve:master' into master
- Loading branch information
Showing
80 changed files
with
2,188 additions
and
421 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
xDrip Notification Context Extension/Base.lproj/MainInterface.storyboard
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="M4Y-Lb-cyx"> | ||
<device id="retina6_12" orientation="portrait" appearance="light"/> | ||
<dependencies> | ||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/> | ||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> | ||
</dependencies> | ||
<scenes> | ||
<!--Notification View Controller--> | ||
<scene sceneID="cwh-vc-ff4"> | ||
<objects> | ||
<viewController id="M4Y-Lb-cyx" userLabel="Notification View Controller" customClass="NotificationViewController" customModule="xDrip_Notification_Context_Extension" customModuleProvider="target" sceneMemberID="viewController"> | ||
<view key="view" userInteractionEnabled="NO" contentMode="scaleToFill" simulatedAppContext="notificationCenter" id="S3S-Oj-5AN"> | ||
<rect key="frame" x="0.0" y="0.0" width="393" height="400"/> | ||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
<subviews> | ||
<containerView opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" translatesAutoresizingMaskIntoConstraints="NO" id="v5J-R6-SOJ"> | ||
<rect key="frame" x="16" y="59" width="361" height="307"/> | ||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
</containerView> | ||
</subviews> | ||
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> | ||
<constraints> | ||
<constraint firstAttribute="bottomMargin" secondItem="v5J-R6-SOJ" secondAttribute="bottom" id="5EB-eI-ger"/> | ||
<constraint firstAttribute="trailingMargin" secondItem="v5J-R6-SOJ" secondAttribute="trailing" id="KhW-l2-lEL"/> | ||
<constraint firstItem="v5J-R6-SOJ" firstAttribute="top" secondItem="S3S-Oj-5AN" secondAttribute="topMargin" id="Ml7-At-PgR"/> | ||
<constraint firstItem="v5J-R6-SOJ" firstAttribute="leading" secondItem="S3S-Oj-5AN" secondAttribute="leadingMargin" id="ODQ-Ev-Dnu"/> | ||
</constraints> | ||
</view> | ||
<extendedEdge key="edgesForExtendedLayout"/> | ||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/> | ||
<size key="freeformSize" width="393" height="400"/> | ||
<connections> | ||
<outlet property="notificationViewContainer" destination="v5J-R6-SOJ" id="7kK-ad-IHz"/> | ||
</connections> | ||
</viewController> | ||
<placeholder placeholderIdentifier="IBFirstResponder" id="vXp-U4-Rya" userLabel="First Responder" sceneMemberID="firstResponder"/> | ||
</objects> | ||
<point key="canvasLocation" x="138.1679389312977" y="4.2253521126760569"/> | ||
</scene> | ||
</scenes> | ||
</document> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
<plist version="1.0"> | ||
<dict> | ||
<key>AppGroupIdentifier</key> | ||
<string>$(APP_GROUP_IDENTIFIER)</string> | ||
<key>NSExtension</key> | ||
<dict> | ||
<key>NSExtensionAttributes</key> | ||
<dict> | ||
<key>UNNotificationExtensionCategory</key> | ||
<string>snoozeCategoryIdentifier</string> | ||
<key>UNNotificationExtensionDefaultContentHidden</key> | ||
<true/> | ||
<key>UNNotificationExtensionInitialContentSizeRatio</key> | ||
<integer>1</integer> | ||
<key>UNNotificationExtensionOverridesDefaultTitle</key> | ||
<false/> | ||
<key>UNNotificationExtensionUserInteractionEnabled</key> | ||
<false/> | ||
</dict> | ||
<key>NSExtensionMainStoryboard</key> | ||
<string>MainInterface</string> | ||
<key>NSExtensionPointIdentifier</key> | ||
<string>com.apple.usernotifications.content-extension</string> | ||
</dict> | ||
</dict> | ||
</plist> |
154 changes: 154 additions & 0 deletions
154
xDrip Notification Context Extension/NotificationView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
// | ||
// NotificationView.swift | ||
// xDrip Notification Context Extension | ||
// | ||
// Created by Paul Plant on 8/6/24. | ||
// Copyright © 2024 Johan Degraeve. All rights reserved. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct NotificationView: View { | ||
var alertTitle: String? | ||
var bgReadingValues: [Double]? | ||
var bgReadingDates: [Date]? | ||
var isMgDl: Bool? | ||
var slopeOrdinal: Int? | ||
var deltaChangeInMgDl: Double? | ||
var urgentLowLimitInMgDl: Double? | ||
var lowLimitInMgDl: Double? | ||
var highLimitInMgDl: Double? | ||
var urgentHighLimitInMgDl: Double? | ||
var alertUrgencyType: AlertUrgencyType? | ||
|
||
var bgUnitString: String? | ||
var bgValueInMgDl: Double? | ||
var bgReadingDate: Date? | ||
var bgValueStringInUserChosenUnit: String? | ||
|
||
var body: some View { | ||
ZStack { | ||
Color(ConstantsAlerts.notificationBackgroundColor) | ||
.ignoresSafeArea() | ||
|
||
VStack(alignment: .center, spacing: 0) { | ||
Text("\(alertTitle ?? "LOW ALARM")") | ||
.font(.title).fontWeight(.bold) | ||
.foregroundStyle(alertUrgencyType?.bannerTextColor ?? .white.opacity(0.85)) | ||
.lineLimit(1) | ||
.minimumScaleFactor(0.2) | ||
.frame(maxWidth: .infinity, maxHeight: 55) | ||
.background(alertUrgencyType?.bannerBackgroundColor ?? .black) | ||
.padding(.top, -15) | ||
|
||
// this is the standard widget view | ||
HStack(alignment: .center) { | ||
Text("\(bgValueStringInUserChosenUnit ?? "")\(trendArrow())") | ||
.font(.system(size: 45)).fontWeight(.bold) | ||
.foregroundStyle(bgTextColor()) | ||
.lineLimit(1) | ||
|
||
Spacer() | ||
|
||
VStack(alignment: .trailing, spacing: -4) { | ||
Text(deltaChangeStringInUserChosenUnit()) | ||
.font(.system(size: 30)).fontWeight(.bold) | ||
.foregroundStyle(.colorPrimary) | ||
.lineLimit(1) | ||
|
||
Text(bgUnitString ?? "") | ||
.font(.system(size: 15)).fontWeight(.semibold) | ||
.foregroundStyle(.colorSecondary) | ||
.lineLimit(1) | ||
} | ||
} | ||
.padding(12) | ||
|
||
GlucoseChartView(glucoseChartType: .notificationExpanded, bgReadingValues: bgReadingValues, bgReadingDates: bgReadingDates, isMgDl: isMgDl ?? true, urgentLowLimitInMgDl: urgentLowLimitInMgDl ?? 60, lowLimitInMgDl: lowLimitInMgDl ?? 70, highLimitInMgDl: highLimitInMgDl ?? 180, urgentHighLimitInMgDl: urgentHighLimitInMgDl ?? 250, liveActivitySize: nil, hoursToShowScalingHours: nil, glucoseCircleDiameterScalingHours: nil, overrideChartHeight: nil, overrideChartWidth: nil, highContrast: nil) | ||
} | ||
.background(ConstantsAlerts.notificationBackgroundColor) | ||
} | ||
} | ||
|
||
func alertTitleColor() -> Color { | ||
if let alertUrgencyType = alertUrgencyType { | ||
switch alertUrgencyType { | ||
case .urgent: | ||
return .red | ||
case .warning: | ||
return .yellow | ||
default: | ||
return .colorPrimary | ||
} | ||
} | ||
|
||
return .colorPrimary | ||
} | ||
|
||
/// Blood glucose color dependant on the user defined limit values and based upon the time since the last reading | ||
/// - Returns: a Color either red, yellow or green | ||
func bgTextColor() -> Color { | ||
if let bgValueInMgDl = bgValueInMgDl, let urgentLowLimitInMgDl = urgentLowLimitInMgDl, let lowLimitInMgDl = lowLimitInMgDl, let highLimitInMgDl = highLimitInMgDl, let urgentHighLimitInMgDl = urgentHighLimitInMgDl { | ||
|
||
if bgValueInMgDl >= urgentHighLimitInMgDl || bgValueInMgDl <= urgentLowLimitInMgDl { | ||
return .red | ||
} else if bgValueInMgDl >= highLimitInMgDl || bgValueInMgDl <= lowLimitInMgDl { | ||
return .yellow | ||
} else { | ||
return .green | ||
} | ||
} | ||
return .green | ||
} | ||
|
||
/// convert the optional delta change int (in mg/dL) to a formatted change value in the user chosen unit making sure all zero values are shown as a positive change to follow Nightscout convention | ||
/// - Returns: a string holding the formatted delta change value (i.e. +0.4 or -6) | ||
func deltaChangeStringInUserChosenUnit() -> String { | ||
if let deltaChangeInMgDl = deltaChangeInMgDl, let isMgDl = isMgDl { | ||
let deltaSign: String = deltaChangeInMgDl > 0 ? "+" : "" | ||
let valueAsString = deltaChangeInMgDl.mgdlToMmolAndToString(mgdl: isMgDl) | ||
|
||
// quickly check "value" and prevent "-0mg/dl" or "-0.0mmol/l" being displayed | ||
// show unitized zero deltas as +0 or +0.0 as per Nightscout format | ||
if isMgDl { | ||
return (deltaChangeInMgDl > -1 && deltaChangeInMgDl < 1) ? "+0" : (deltaSign + valueAsString) | ||
} else { | ||
return (deltaChangeInMgDl > -0.1 && deltaChangeInMgDl < 0.1) ? "+0.0" : (deltaSign + valueAsString) | ||
} | ||
} else { | ||
return (isMgDl ?? true) ? "-" : "-.-" | ||
} | ||
} | ||
|
||
|
||
/// returns a string holding the trend arrow | ||
/// - Returns: trend arrow string (i.e. "↑") | ||
func trendArrow() -> String { | ||
if let slopeOrdinal = slopeOrdinal { | ||
switch slopeOrdinal { | ||
case 7: | ||
return "\u{2193}\u{2193}" // ↓↓ | ||
case 6: | ||
return "\u{2193}" // ↓ | ||
case 5: | ||
return "\u{2198}" // ↘ | ||
case 4: | ||
return "\u{2192}" // → | ||
case 3: | ||
return "\u{2197}" // ↗ | ||
case 2: | ||
return "\u{2191}" // ↑ | ||
case 1: | ||
return "\u{2191}\u{2191}" // ↑↑ | ||
default: | ||
return "" | ||
} | ||
} else { | ||
return "" | ||
} | ||
} | ||
} | ||
|
||
#Preview { | ||
NotificationView() | ||
} |
Oops, something went wrong.