Skip to content

Commit 5fdac5d

Browse files
committed
transfer v2.2.8 updates from LF to LF_3
1 parent 55b2ffb commit 5fdac5d

51 files changed

Lines changed: 6186 additions & 2660 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Config.xcconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
unique_id = ${DEVELOPMENT_TEAM}
77

88
//Version (DEFAULT)
9-
LOOP_FOLLOW_MARKETING_VERSION = 2.2.7
9+
LOOP_FOLLOW_MARKETING_VERSION = 2.2.8

LoopFollow.xcodeproj/project.pbxproj

Lines changed: 147 additions & 4 deletions
Large diffs are not rendered by default.

LoopFollow.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 69 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

LoopFollow/Application/Base.lproj/Main.storyboard

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17701" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="49e-Tb-3d3">
2+
<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="49e-Tb-3d3">
33
<device id="retina6_5" orientation="portrait" appearance="light"/>
44
<dependencies>
55
<deployment identifier="iOS"/>
6-
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17703"/>
6+
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22685"/>
77
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
88
<capability name="Stack View standard spacing" minToolsVersion="9.0"/>
99
<capability name="System colors in document resources" minToolsVersion="11.0"/>
@@ -86,7 +86,7 @@
8686
</constraints>
8787
<prototypes>
8888
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="LabelCell" textLabel="gif-qe-9mv" detailTextLabel="hfT-xF-eNt" style="IBUITableViewCellStyleValue1" id="GJo-f1-ajA">
89-
<rect key="frame" x="0.0" y="28" width="243.33333333333337" height="43.666667938232422"/>
89+
<rect key="frame" x="0.0" y="50" width="243.33333333333337" height="43.666667938232422"/>
9090
<autoresizingMask key="autoresizingMask"/>
9191
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="GJo-f1-ajA" id="2H1-eI-xS5">
9292
<rect key="frame" x="0.0" y="0.0" width="243.33333333333337" height="43.666667938232422"/>
@@ -348,7 +348,7 @@
348348
</variation>
349349
</label>
350350
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Delta" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YCF-22-z3g" userLabel="Delta">
351-
<rect key="frame" x="0.0" y="263" width="398" height="48"/>
351+
<rect key="frame" x="0.0" y="263" width="398" height="77.666666666666686"/>
352352
<fontDescription key="fontDescription" type="system" pointSize="70"/>
353353
<nil key="textColor"/>
354354
<color key="highlightedColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -357,7 +357,7 @@
357357
</variation>
358358
</label>
359359
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MinAgo" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HNC-P8-PbV">
360-
<rect key="frame" x="0.0" y="311" width="398" height="48"/>
360+
<rect key="frame" x="0.0" y="340.66666666666669" width="398" height="48"/>
361361
<fontDescription key="fontDescription" type="system" pointSize="70"/>
362362
<nil key="textColor"/>
363363
<nil key="highlightedColor"/>
@@ -366,13 +366,13 @@
366366
</variation>
367367
</label>
368368
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xzZ-jc-k2v">
369-
<rect key="frame" x="0.0" y="359" width="398" height="352"/>
369+
<rect key="frame" x="0.0" y="388.66666666666674" width="398" height="322.33333333333326"/>
370370
<subviews>
371371
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="HFL-Ye-6HR">
372-
<rect key="frame" x="103.66666666666667" y="142" width="190.66666666666663" height="68"/>
372+
<rect key="frame" x="103.33333333333333" y="112.33333333333331" width="191.66666666666669" height="97.666666666666686"/>
373373
<subviews>
374374
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Clock" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="r85-eB-vVd">
375-
<rect key="frame" x="0.0" y="0.0" width="190.66666666666666" height="48"/>
375+
<rect key="frame" x="0.0" y="0.0" width="191.66666666666666" height="77.666666666666671"/>
376376
<fontDescription key="fontDescription" type="system" pointSize="70"/>
377377
<nil key="textColor"/>
378378
<nil key="highlightedColor"/>
@@ -381,7 +381,7 @@
381381
</variation>
382382
</label>
383383
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Alert Name" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsLetterSpacingToFitWidth="YES" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="tiA-fs-ZRV">
384-
<rect key="frame" x="0.0" y="58" width="190.66666666666666" height="0.0"/>
384+
<rect key="frame" x="0.0" y="87.666666666666629" width="191.66666666666666" height="0.0"/>
385385
<fontDescription key="fontDescription" type="system" pointSize="70"/>
386386
<nil key="textColor"/>
387387
<nil key="highlightedColor"/>
@@ -390,7 +390,7 @@
390390
</variation>
391391
</label>
392392
<button hidden="YES" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Meu-VT-byv">
393-
<rect key="frame" x="0.0" y="58" width="190.66666666666666" height="0.0"/>
393+
<rect key="frame" x="0.0" y="87.666666666666629" width="191.66666666666666" height="0.0"/>
394394
<color key="backgroundColor" systemColor="labelColor"/>
395395
<fontDescription key="fontDescription" type="system" pointSize="70"/>
396396
<state key="normal" title="Snooze">
@@ -404,7 +404,7 @@
404404
</connections>
405405
</button>
406406
<stackView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dav-Y8-lSK">
407-
<rect key="frame" x="0.0" y="68" width="190.66666666666666" height="0.0"/>
407+
<rect key="frame" x="0.0" y="97.666666666666629" width="191.66666666666666" height="0.0"/>
408408
<subviews>
409409
<label hidden="YES" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="snoozeMinutes" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="iC4-A1-q9b">
410410
<rect key="frame" x="0.0" y="0.0" width="0.0" height="32"/>
@@ -423,7 +423,7 @@
423423
</subviews>
424424
</stackView>
425425
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" editable="NO" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="9ey-Az-e5u" userLabel="debugTextView">
426-
<rect key="frame" x="8" y="8" width="382" height="336"/>
426+
<rect key="frame" x="8" y="8" width="382" height="306.33333333333331"/>
427427
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
428428
<fontDescription key="fontDescription" type="system" pointSize="14"/>
429429
<textInputTraits key="textInputTraits" autocapitalizationType="sentences" autocorrectionType="no"/>
@@ -522,7 +522,7 @@
522522
</objects>
523523
<point key="canvasLocation" x="130" y="700"/>
524524
</scene>
525-
<!--Alarms-->
525+
<!--Alarm View Controller-->
526526
<scene sceneID="a12-B3-C4d">
527527
<objects>
528528
<viewController storyboardIdentifier="AlarmViewController" id="b34-C5-D6e" customClass="AlarmViewController" customModule="Loop_Follow" customModuleProvider="target" sceneMemberID="viewController">
@@ -577,11 +577,11 @@
577577
</scene>
578578
</scenes>
579579
<resources>
580-
<image name="alarm" catalog="system" width="124" height="128"/>
581-
<image name="gear" catalog="system" width="128" height="119"/>
582-
<image name="house" catalog="system" width="128" height="106"/>
583-
<image name="safari" catalog="system" width="128" height="121"/>
584-
<image name="zzz" catalog="system" width="121" height="128"/>
580+
<image name="antenna.radiowaves.left.and.right" catalog="system" width="128" height="111"/>
581+
<image name="gear" catalog="system" width="128" height="122"/>
582+
<image name="house" catalog="system" width="128" height="104"/>
583+
<image name="safari" catalog="system" width="128" height="123"/>
584+
<image name="zzz" catalog="system" width="119" height="128"/>
585585
<systemColor name="labelColor">
586586
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
587587
</systemColor>
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//
2+
// ContactImageUpdater.swift
3+
// LoopFollow
4+
//
5+
// Created by Jonas Björkert on 2024-12-10.
6+
// Copyright © 2024 Jon Fawcett. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import Contacts
11+
import UIKit
12+
13+
class ContactImageUpdater {
14+
private let contactStore = CNContactStore()
15+
private let queue = DispatchQueue(label: "ContactImageUpdaterQueue")
16+
17+
func updateContactImage(bgValue: String, extra: String, stale: Bool) {
18+
queue.async {
19+
guard CNContactStore.authorizationStatus(for: .contacts) == .authorized else {
20+
print("Access to contacts is not authorized.")
21+
return
22+
}
23+
24+
guard let imageData = self.generateContactImage(bgValue: bgValue, extra: extra, stale: stale)?.pngData() else {
25+
print("Failed to generate contact image.")
26+
return
27+
}
28+
29+
let bundleDisplayName = Bundle.main.object(forInfoDictionaryKey: "CFBundleDisplayName") as? String ?? "LoopFollow"
30+
let contactName = "\(bundleDisplayName) - BG"
31+
let predicate = CNContact.predicateForContacts(matchingName: contactName)
32+
let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey, CNContactImageDataKey] as [CNKeyDescriptor]
33+
34+
do {
35+
let contacts = try self.contactStore.unifiedContacts(matching: predicate, keysToFetch: keysToFetch)
36+
37+
if let contact = contacts.first, let mutableContact = contact.mutableCopy() as? CNMutableContact {
38+
mutableContact.imageData = imageData
39+
let saveRequest = CNSaveRequest()
40+
saveRequest.update(mutableContact)
41+
try self.contactStore.execute(saveRequest)
42+
print("Contact image updated successfully.")
43+
} else {
44+
let newContact = CNMutableContact()
45+
newContact.givenName = contactName
46+
newContact.imageData = imageData
47+
let saveRequest = CNSaveRequest()
48+
saveRequest.add(newContact, toContainerWithIdentifier: nil)
49+
try self.contactStore.execute(saveRequest)
50+
print("New contact created with updated image.")
51+
}
52+
} catch {
53+
print("Failed to update or create contact: \(error)")
54+
}
55+
}
56+
}
57+
58+
private func generateContactImage(bgValue: String, extra: String, stale: Bool) -> UIImage? {
59+
let size = CGSize(width: 300, height: 300)
60+
UIGraphicsBeginImageContextWithOptions(size, false, 0)
61+
guard let context = UIGraphicsGetCurrentContext() else { return nil }
62+
63+
UIColor.black.setFill()
64+
context.fill(CGRect(origin: .zero, size: size))
65+
66+
let paragraphStyle = NSMutableParagraphStyle()
67+
paragraphStyle.alignment = .center
68+
69+
let maxFontSize: CGFloat = extra.isEmpty ? 200 : 160
70+
let fontSize = maxFontSize - CGFloat(bgValue.count * 15)
71+
72+
var bgAttributes: [NSAttributedString.Key: Any] = [
73+
.font: UIFont.boldSystemFont(ofSize: fontSize),
74+
.foregroundColor: stale ? UIColor.gray : UIColor.white,
75+
.paragraphStyle: paragraphStyle
76+
]
77+
78+
if stale {
79+
bgAttributes[.strikethroughStyle] = NSUnderlineStyle.single.rawValue
80+
}
81+
82+
let extraAttributes: [NSAttributedString.Key: Any] = [
83+
.font: UIFont.systemFont(ofSize: 90),
84+
.foregroundColor: UIColor.white,
85+
.paragraphStyle: paragraphStyle
86+
]
87+
88+
let bgRect = extra.isEmpty
89+
? CGRect(x: 0, y: 46, width: size.width, height: size.height - 80)
90+
: CGRect(x: 0, y: 26, width: size.width, height: size.height / 2)
91+
92+
bgValue.draw(in: bgRect, withAttributes: bgAttributes)
93+
94+
if !extra.isEmpty {
95+
let extraRect = CGRect(x: 0, y: size.height / 2 + 6, width: size.width, height: size.height / 2 - 20)
96+
extra.draw(in: extraRect, withAttributes: extraAttributes)
97+
}
98+
99+
let image = UIGraphicsGetImageFromCurrentImageContext()
100+
UIGraphicsEndImageContext()
101+
return image
102+
}
103+
}

0 commit comments

Comments
 (0)