Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
565 commits
Select commit Hold shift + click to select a range
ada7d8c
Fix #721
timbms Jul 4, 2025
6e11fcb
Other cases to be handled. Monospaceddigit font for better handling
timbms Jul 4, 2025
37bc048
rm sitemap.json
timbms Jul 24, 2025
ab12f8b
Stuck on updateNavigationTitle
timbms Jul 25, 2025
5035748
swiftline
timbms Jul 25, 2025
7b3c358
Stable display of icon
timbms Jul 25, 2025
b46e8a8
testing for more robust icon loading
timbms Jul 25, 2025
be814ea
Small cleanup in OpenHABSitemapViewController
timbms Jul 25, 2025
1fcfbb2
Upgraded package to Kingfisher > 8.5.0
timbms Jul 27, 2025
e87be93
Implement IconCacheTracker as actor
timbms Jul 27, 2025
c6a15c1
minor evolution
timbms Jul 29, 2025
85a1209
Stabilize IconView display, use id composed out of pageId and widget.id
timbms Jul 31, 2025
bdffae5
replace os_log by logger
timbms Jul 31, 2025
2d76e04
Merge branch 'openapigen' into openapigen-swiftui
timbms Jul 31, 2025
ce64279
id for buttongrid
timbms Jul 31, 2025
5ceb179
Handle readOnly
timbms Jul 31, 2025
ee935f6
Reworked hexString
timbms Jul 31, 2025
9bdf803
SVG view on macOS
timbms Aug 1, 2025
3d1fb80
Throttling output for Slider, Color, ColorTemperature
timbms Aug 1, 2025
9a068c7
ButtonGridRowView to observe widget with ObservedObject
timbms Aug 1, 2025
750fd22
Handle refresh for images
timbms Aug 2, 2025
c543f54
redacted view during loading
timbms Aug 2, 2025
59052df
preview compiler requires Logger methods to use string interpolation …
timbms Aug 2, 2025
735d325
Support for SSE events via openapigen (#901)
timbms Aug 2, 2025
b0fe121
test cases for UIColor.hexString
timbms Aug 3, 2025
11c34a2
Some linting
timbms Aug 3, 2025
a05cc45
Support for SSE events via openapigen (#901)
timbms Aug 2, 2025
3f82bab
Merged openapigen
timbms Aug 3, 2025
7f56d9b
Import SFSafeSymbols into ItemSelectionView
timbms Aug 3, 2025
44e3bb4
Import SFSafeSymbols into ItemSelectionView
timbms Aug 3, 2025
e6e3d0f
implementing some changes suggested by Copilot review
timbms Aug 3, 2025
79df2b4
Co-pilot feedback
digitaldan Aug 3, 2025
fc7d2fe
Track path changed in the MainUI SPA
digitaldan Aug 3, 2025
76bea2c
Update README
digitaldan Aug 3, 2025
abaf337
Switch to a home as soon as selected
digitaldan Aug 4, 2025
93a6fd5
Screenshots for Release (#902)
timbms Aug 4, 2025
f491470
readme update
digitaldan Aug 4, 2025
9a4b5cf
Merge openapigen
timbms Aug 5, 2025
a26d0ac
Minor change
timbms Aug 5, 2025
8a95723
Improve entry of URL for server
timbms Aug 5, 2025
c84fe66
Addressing issues brought up by gemini review
timbms Aug 5, 2025
210e87f
Merge remote-tracking branch 'origin/openapigen' into openapigen-swiftui
timbms Aug 5, 2025
9cc6814
Revert change InternalImportsByDefault
timbms Aug 5, 2025
bdc3294
Created SitemapNavigationView as navigation container
timbms Aug 5, 2025
62e056b
Merge develop
timbms Aug 6, 2025
1fddf20
Merging develop step 2
timbms Aug 6, 2025
2156606
Merge branch 'develop' into openapigen-swiftui
timbms Aug 6, 2025
5b7358c
Presenting Settings with Cancel and Save again
timbms Aug 6, 2025
28261a1
Merge branch 'develop' into openapigen-swiftui
timbms Aug 11, 2025
3b0f2f5
Merge branch 'develop' into openapigen-swiftui
timbms Aug 12, 2025
8d0bb52
Safer icon display
timbms Aug 14, 2025
d7a6b9e
Merge develop
timbms Aug 14, 2025
e5ea803
prepare for Xcode 26
timbms Aug 15, 2025
1bc1156
Merge branch 'develop' into openapigen-swiftui
timbms Aug 16, 2025
6a0d85a
Merge develop
timbms Aug 19, 2025
ec148a5
Cleaning up ImageView duplication
timbms Aug 19, 2025
18e95ff
Merge develop
timbms Aug 22, 2025
75221c0
Merge branch 'develop' into openapigen-swiftui
timbms Aug 22, 2025
d36dc62
Update openHAB/NoIconDisplayableCell.swift
timbms Aug 22, 2025
3d8a1da
Fix compiler bugs with Xcode 26
timbms Sep 17, 2025
da5d26b
Merge branch 'develop' into openapigen-swiftui
timbms Sep 17, 2025
adc9dde
Remove double import
timbms Sep 17, 2025
14b6160
Merge branch 'develop' into openapigen-swiftui
timbms Sep 17, 2025
873b854
Set @MainActor on protocol OpenHABViewable
timbms Sep 17, 2025
2e35247
Merge develop
timbms Sep 23, 2025
16e3e4e
Merge branch 'develop' into openapigen-swiftui
timbms Sep 25, 2025
84c588e
Merge branch 'develop' into openapigen-swiftui
timbms Sep 25, 2025
342e79e
Merge branch 'develop' into openapigen-swiftui
timbms Sep 29, 2025
abe9e27
Merge branch 'develop' into openapigen-swiftui
timbms Oct 10, 2025
3129ada
Merged develop
timbms Oct 11, 2025
2463e01
Merge develop
timbms Oct 20, 2025
d68fcf9
Merge branch 'develop' into openapigen-swiftui
timbms Oct 20, 2025
920a41e
Properly using SF Symbols
timbms Oct 20, 2025
fe52ccd
Cleaning up remainder of watch extension
timbms Oct 20, 2025
50757a5
Merge branch 'develop' into openapigen-swiftui
timbms Oct 25, 2025
eb5a768
Unblock after merging develop
timbms Oct 26, 2025
86ef5c3
Reduce row spacing in SitemapPageView
timbms Oct 27, 2025
60d1dd9
Merged develop
timbms Nov 5, 2025
0fa43b7
Cleanup
timbms Nov 5, 2025
311200f
Merge branch 'develop' into openapigen-swiftui
timbms Nov 5, 2025
7211c41
Enable self-signed certificates
timbms Nov 9, 2025
484ae20
SegmentedRow: add widget.labelValue, adjust row heigh
timbms Nov 9, 2025
e8d1059
Merge branch 'develop' into openapigen-swiftui
timbms Nov 15, 2025
00fd280
Merge branch 'develop' into openapigen-swiftui
timbms Nov 16, 2025
e3f0f73
Port mjpeg handling to SwiftUI
timbms Nov 16, 2025
7b06446
Merge branch 'develop' into openapigen-swiftui
timbms Nov 16, 2025
3819b71
Complete merge of branch develop
timbms Dec 4, 2025
798dbe9
Merge branch 'develop' into openapigen-swiftui
timbms Dec 4, 2025
215d514
Merge branch 'develop' into openapigen-swiftui
timbms Dec 4, 2025
1759fa5
Merge branch 'develop' into openapigen-swiftui
timbms Dec 18, 2025
1628139
Merge branch 'develop' into openapigen-swiftui
timbms Dec 19, 2025
13c34a3
Port functionality to SwiftUI: Search functionality, Title cleanup (r…
timbms Dec 19, 2025
5220c17
Merge branch 'develop' into openapigen-swiftui
timbms Dec 21, 2025
4d83867
Fix sitemap row spacing, duplicate toolbar, and transition errors
timbms Dec 27, 2025
f7328fb
Merge develop
timbms Dec 27, 2025
a7bd869
Reduce logging
timbms Dec 27, 2025
b460afa
Display sitemap labels instead of technical names
timbms Dec 27, 2025
8f90905
Update Package.resolved
timbms Dec 27, 2025
fbec075
Merge develop
timbms Dec 27, 2025
25531cf
Merge develop, update copyright to 2026
timbms Jan 4, 2026
3b927ac
Increased tolerance from 5s to 30s in #expect(info
timbms Jan 5, 2026
a04c0d2
Merge branch 'develop' into openapigen-swiftui
timbms Jan 5, 2026
be25c8c
Resolving merge conflicts, restored widget flattening in openHABWatc…
timbms Jan 15, 2026
ce4e916
Improved sspacing
timbms Jan 16, 2026
c9d0216
Merge branch 'develop' into openapigen-swiftui
timbms Jan 19, 2026
bda4776
Merge branch 'develop' into openapigen-swiftui
timbms Jan 19, 2026
8059d95
Merge branch 'develop' into openapigen-swiftui
timbms Jan 20, 2026
0468af5
Merge branch 'develop' into openapigen-swiftui
timbms Jan 27, 2026
7fd3a63
Resolve merge mess in openHAB.xcodeproj/project.pbxproj
timbms Jan 27, 2026
352dae3
Merge branch 'develop' into openapigen-swiftui
timbms Jan 28, 2026
796a9ec
Changes Made:
timbms Jan 28, 2026
485a137
Merge branch 'develop' into openapigen-swiftui
timbms Jan 28, 2026
9be604c
Replace onTapGesture with Button where appropriate
timbms Jan 28, 2026
7a4a370
Merge branch 'develop' into openapigen-swiftui
timbms Jan 28, 2026
1b3e979
Merge develop
timbms Jan 29, 2026
827260f
Merge branch 'develop' into openapigen-swiftui
timbms Jan 30, 2026
ddc2abc
Implement the press-and-release mappings for switches
timbms Jan 30, 2026
4019242
Some improvements for current target iOS 16
timbms Jan 30, 2026
edf5dfd
Completed merge / Conflicts resolved
timbms Jan 30, 2026
b898bfb
Fix valuecolor support and match UIKit styling in SwiftUI views
timbms Jan 30, 2026
0dd0119
Pass iconColor to OpenHABImageProcessor in SwiftUI IconView
timbms Jan 30, 2026
bdeb9c2
Replace Picker with button-based segmented control in SegmentedRowView
timbms Jan 30, 2026
0ca8a4b
Fix icon size, row heights, and background colors in SwiftUI views
timbms Jan 30, 2026
c2c4ede
Fix dark mode icons and improve SegmentedRowView layout
timbms Jan 30, 2026
3b129e3
Add lineLimit(1) to labelText and labelValue in all row views
timbms Jan 30, 2026
876afce
Add navigation titles to SelectionView sheet and SitemapPageView
timbms Jan 30, 2026
7777ddd
Replace SelectionRowView sheet with Menu popover
timbms Jan 31, 2026
e3305fc
Improve SwiftUI views: charts, segmented control animation, and linke…
timbms Jan 31, 2026
65e2132
Fix format string crash with unescaped percent sign
timbms Jan 31, 2026
1fe6cc8
Change of colors
timbms Jan 31, 2026
a5dede4
Distinguish colors for light and dark mode
timbms Jan 31, 2026
9ef6192
Refactored the SliderRowView to conditionally wrap the label content …
timbms Jan 31, 2026
1a97edd
Fix regression on watchOS app
timbms Jan 31, 2026
2c88459
Fix for slider appearing
timbms Jan 31, 2026
a897059
Dark mode for charts
timbms Feb 1, 2026
cb8884b
Merge branch 'develop' into openapigen-swiftui
timbms Feb 1, 2026
3aa5a99
Fix for singleMappingButton
timbms Feb 1, 2026
b8fc979
Improvement on layout of SegmentedRowView
timbms Feb 1, 2026
c1df46c
Removing litter
timbms Feb 1, 2026
2d74671
Merge branch 'develop' into openapigen-swiftui
timbms Feb 1, 2026
131184a
Fix for path and filename for openHABWatch/openHABWatch.entitlements
timbms Feb 1, 2026
530ee0d
Merge branch 'develop' into openapigen-swiftui
timbms Feb 1, 2026
bd9d3f8
Improving color selection
timbms Feb 1, 2026
f6f5bc5
Fix for duplicate rows
timbms Feb 1, 2026
aeeda62
Partially reverting b8fc979 Improvement on layout of SegmentedRowView…
timbms Feb 1, 2026
02f7943
Merge branch 'develop' into openapigen-swiftui
timbms Feb 1, 2026
307555d
Align labelText of SegmentedRowView with other RowViews
timbms Feb 1, 2026
5e916d7
Reworked widget update logic
timbms Feb 1, 2026
b937ba1
Flip switchSupport logic
timbms Feb 1, 2026
b6bdb09
SelectionRowView adjustment
timbms Feb 1, 2026
1157079
Add TextRow to watchOS and remove legacy WidgetTypeEnum
timbms Feb 2, 2026
2847818
Add SelectionRow to watchOS and fix TextRow disclosure indicator
timbms Feb 2, 2026
f361ad2
Fix Setpoint buttons on watchOS and improve unit handling
timbms Feb 2, 2026
cd14549
Move TextLabelView to CommonUI for reuse across iOS and watchOS
timbms Feb 2, 2026
d7736be
Minor layout and style cleanups
timbms Feb 2, 2026
e21a577
Fix valuecolor parsing in watchOS DetailTextLabelView
timbms Feb 2, 2026
91712b6
Improve SegmentedRowView previews and add fallback icon support
timbms Feb 3, 2026
d970489
Fix linter warnings
timbms Feb 3, 2026
c28c263
Fix iOS slider external updates and merge watchOS slider rows
timbms Feb 3, 2026
d915603
Improve slider behavior and show current value while dragging
timbms Feb 3, 2026
872fa01
Wrap PreviewConstants in DEBUG and fix preview labels
timbms Feb 3, 2026
6626e9d
Style pressReleaseButtons to match segmentedButtons
timbms Feb 3, 2026
31f0324
Unify singleMappingButton and pressReleaseButton styling
timbms Feb 4, 2026
233e73a
Align single mapping and pressRelease buttons to trailing edge
timbms Feb 4, 2026
5cd3cdc
Add isNilOrEmpty extension and use in SegmentedRowView
timbms Feb 4, 2026
e29078c
Simplify isNilOrEmpty implementation
timbms Feb 4, 2026
b92fcb7
Redo preferences storage with JSON
timbms Feb 4, 2026
3bc535e
Style pressRelease buttons individually with spacing
timbms Feb 4, 2026
8d30083
Revert "Redo preferences storage with JSON"
timbms Feb 4, 2026
4834cfb
Update SegmentedRowView layout and add shutter preview
timbms Feb 4, 2026
79f7d85
Use isNilOrEmpty for singleMappingButton spacer check
timbms Feb 4, 2026
d681b49
Increase spacing between pressRelease buttons
timbms Feb 4, 2026
24f4942
Show selected state on single mapping button
timbms Feb 5, 2026
c23351a
Fix slider jumping by always sending final value and adding step
timbms Feb 5, 2026
0771e67
Send single mapping button command on touch down
timbms Feb 5, 2026
1f28532
Fix single mapping button sending duplicate commands
timbms Feb 6, 2026
78a8a47
Fix crash, bugs, and duplication from PR review
timbms Feb 6, 2026
9fd4930
Move PreviewList to SegmentedRowView as shared internal type
timbms Feb 6, 2026
7f9e776
Reorder ButtonGridRowView declarations and remove lint suppression
timbms Feb 6, 2026
9d69736
Remove empty setupActiveConnectionObserver stub
timbms Feb 6, 2026
7afbc8f
Defer non-essential AppDelegate setup and add placeholder title
timbms Feb 6, 2026
2167c86
Fix Task leak, hidden TextField, ignored search pref, and linked-page…
timbms Feb 6, 2026
8b10413
Fix connection observer lifecycle and redacted title during loading
timbms Feb 7, 2026
4ec8a52
Simplify connection observer and prevent same-URL restart loop
timbms Feb 7, 2026
5154a61
Default isLoading to true to show skeleton on first render
timbms Feb 7, 2026
798b5ff
Remove duplicate PreviewConstants and decouple skeleton from preview …
timbms Feb 7, 2026
6c31741
Use semantic gray colors for better segmented control track contrast
timbms Feb 8, 2026
f909def
Add inline buttons for single and press-release mappings on watchOS
timbms Feb 8, 2026
0800e10
Constrain inline button hit area with contentShape
timbms Feb 8, 2026
1987513
Fix inline button hit area extending beyond visible bounds
timbms Feb 8, 2026
b3bad83
Validate touch coordinates to constrain button hit area on watchOS
timbms Feb 8, 2026
05f15fc
Skip widgets array reassignment when list structure is unchanged
timbms Feb 8, 2026
b89b6fa
Copy sendCommand closure when updating existing widget instances
timbms Feb 8, 2026
36fd106
Fire single-mapping button on release within bounds, not on press
timbms Feb 8, 2026
3dee5cc
Put up to 2 inline buttons on same row as title on watchOS
timbms Feb 8, 2026
8bc10e0
Removing unused code
timbms Feb 8, 2026
07fe9eb
Sync WidgetRowViewModel for all SegmentRow branches
timbms Feb 8, 2026
314bca4
Migrate WidgetRowViewModel to Observation framework
timbms Feb 9, 2026
8e02461
Update project
timbms Feb 9, 2026
b5be93a
Adopt WidgetRowViewModel and clean up watchOS row views
timbms Feb 9, 2026
8a5f408
Extract WidgetRowFactory and decouple previews from UserData
timbms Feb 9, 2026
ce492e4
Add PreviewNavigationContainer and use it across all row previews
timbms Feb 9, 2026
50d3d76
Centralize watchOS typography with WatchTypography and WatchLabelText
timbms Feb 9, 2026
30b610d
Extract WidgetCommandSender for centralized command dispatch
timbms Feb 9, 2026
b67e80e
Fix WidgetCommandSender cleanup and setpoint unit preservation
timbms Feb 10, 2026
ab7b3fe
Simplify stateless rows by removing unnecessary WidgetRowViewModel
timbms Feb 10, 2026
c634c23
Replace IconView with model-driven WatchIconView
timbms Feb 10, 2026
cf4d654
Simplify SwitchRow and SelectionRow with direct data passing
timbms Feb 10, 2026
456c620
Simplify SliderRow, SetpointRow, and SegmentSelectionView with direct…
timbms Feb 10, 2026
b1d06bb
Restore WidgetRowViewModel for complex rows and unify stateToken pattern
timbms Feb 10, 2026
c37ae53
Migrate ColorSelection to WidgetCommandSender with debounce policy
timbms Feb 10, 2026
0fd73d1
Decouple WatchLabelText and DetailTextLabelView from OpenHABWidget
timbms Feb 10, 2026
45fb0df
Add watchTextStyle modifier and accessibility labels across watchOS v…
timbms Feb 10, 2026
0bc1bcc
Adopt stateToken pattern in SegmentRow and ColorPickerRow
timbms Feb 10, 2026
8b4b75d
Add dedicated watchOS test target and interactive state token previews
timbms Feb 10, 2026
29fb7d6
Add unit tests for WidgetCommandSender
timbms Feb 10, 2026
9d32fb7
Merge branch 'develop' into openapigen-swiftui
timbms Feb 10, 2026
4b5a649
Fix scroll-to-top on long-poll updates and image flickering
timbms Feb 10, 2026
c7c0c95
Fix ButtonGrid commands to target parent widget item
timbms Feb 10, 2026
d7353da
Move test helpers above test suites for consistency
timbms Feb 10, 2026
e938fd2
Merge branch 'develop' into openapigen-swiftui
timbms Feb 11, 2026
b88f390
Fix webview authentication in SwiftUI sitemap renderer
timbms Feb 11, 2026
5a558a3
Minor cleanup
timbms Feb 11, 2026
af10036
Merge branch 'develop' into openapigen-swiftui
timbms Feb 12, 2026
6d9e7df
Merge branch 'develop' into openapigen-swiftui
timbms Feb 12, 2026
719fe96
Provide command source for SwiftUI and watchOS
timbms Feb 12, 2026
44aee42
Move WidgetCommandDispatcher into OpenHABCore for shared use
timbms Feb 13, 2026
74154ff
Extract WidgetDisplayState for consistent widget rendering
timbms Feb 13, 2026
7e1685e
Fix watchOS commands silently failing after long poll
timbms Feb 14, 2026
37a833c
Align setpoint value formatting across iOS and watchOS
timbms Feb 14, 2026
9521bcc
Fix thread safety, command source, and display state consistency
timbms Feb 14, 2026
f53e773
Missing return
timbms Feb 14, 2026
fa0ce12
Refactor SwiftUI views for improved readability
timbms Feb 14, 2026
694d185
Merge branch 'develop' into openapigen-swiftui
timbms Feb 14, 2026
5bfbcc0
Add OHTextToken design system and improve value formatting
timbms Feb 14, 2026
5bfb239
Cancel long-polling on view disappear to prevent duplicate tasks
timbms Feb 14, 2026
dd1760f
Add deduplication and staleness guards to page handling
timbms Feb 14, 2026
e72fb01
Add command lifecycle tracking and refactor page handling
timbms Feb 14, 2026
afacbfc
Move command lifecycle indicator to leading toolbar and hide when idle
timbms Feb 14, 2026
9f352a5
Add toolbar search button with on-demand searchable field
timbms Feb 15, 2026
9aa79de
disable linting and format for swiftui auto build
TAKeanice Dec 19, 2025
123da03
group views by technology
TAKeanice Dec 26, 2025
b6b68ae
Replace SideMenu drawer with SwiftUI TabView navigation
TAKeanice Feb 14, 2026
272ab7a
Refine TabView: reactive notifications, settings dirty tracking, tab …
TAKeanice Feb 14, 2026
93d3d3d
Fix tab reset and add tab customization in settings
TAKeanice Feb 14, 2026
b30800f
Add reorder handles to tab settings and make config per-home
TAKeanice Feb 14, 2026
fb63406
Add visible drag handles and refresh tabs on home switch
TAKeanice Feb 14, 2026
bd9302c
Remove @MainActor from Preferences, delete legacy UIKit cells, and re…
TAKeanice Feb 16, 2026
c2c5bba
Refactor sitemap navigation and adopt async Preferences API
TAKeanice Feb 16, 2026
6d89e35
Adopt SwiftUI App lifecycle, remove Main.storyboard, and delete legac…
TAKeanice Feb 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CommonUI/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.DS_Store
/.build
/Packages
xcuserdata/
DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
96 changes: 96 additions & 0 deletions CommonUI/Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

45 changes: 45 additions & 0 deletions CommonUI/Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// swift-tools-version: 6.2
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "CommonUI",
platforms: [.iOS("26.0"), .watchOS("26.0"), .macOS("26.0")],
products: [
// Products define the executables and libraries a package produces, making them visible to other packages.
.library(
name: "CommonUI",
targets: ["CommonUI"]
)
],
dependencies: [
.package(path: "../OpenHABCore"),
.package(url: "https://github.com/apple/swift-numerics", from: "1.0.0")
],
targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.target(
name: "CommonUI",
dependencies: ["OpenHABCore"],
swiftSettings: [
.enableUpcomingFeature("ExistentialAny"),
// .enableUpcomingFeature("InternalImportsByDefault"),
.enableUpcomingFeature("MemberImportVisibility"),
.enableUpcomingFeature("StrictConcurrency"),
.unsafeFlags([
"-Xfrontend", "-enable-actor-data-race-checks",
"-Xfrontend", "-strict-concurrency=complete"
])
]
),
.testTarget(
name: "CommonUITests",
dependencies: [
.product(name: "Numerics", package: "swift-numerics"),
"CommonUI"
]
)
]
)
53 changes: 53 additions & 0 deletions CommonUI/Sources/CommonUI/ColorExtension.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright (c) 2010-2026 Contributors to the openHAB project
//
// See the NOTICE file(s) distributed with this work for additional
// information.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0
//
// SPDX-License-Identifier: EPL-2.0

import OpenHABCore
import SwiftUI

public extension Color {
init(fromString string: String) {
self.init(UIColor(fromString: string))
}

init(hex: String) {
self.init(UIColor(hex: hex))
}
}

public typealias Kelvin = Double

public extension Color {
init(temperature: Kelvin) {
let components = componentsForColorTemperature(temperature: temperature)
self.init(red: components.r, green: components.g, blue: components.b)
}

func hexString() -> String {
let components = cgColor?.components
let r: CGFloat = components?[0] ?? 0.0
let g: CGFloat = components?[1] ?? 0.0
let b: CGFloat = components?[2] ?? 0.0

let hexString = String(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)), lroundf(Float(b * 255)))
return hexString
}
}

// For algorithm see https://web.archive.org/web/20151024031939/http://www.zombieprototypes.com/?p=210
// Algorithm see http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/
// swiftlint:disable:next large_tuple
func componentsForColorTemperature(temperature: Kelvin) -> (r: Double, g: Double, b: Double) {
let k = temperature / 100
let r = (k <= 66 ? 255 : (329.698727446 * pow(k - 60, -0.1332047592))).clamped(to: 0 ... 255.0) / 255
let g = (k <= 66 ? (99.4708025861 * log(k) - 161.1195681661) : 288.1221695283 * pow(k - 60, -0.0755148492)).clamped(to: 0 ... 255.0) / 255
let b = (k >= 66 ? 255 : (k <= 19 ? 0 : 138.5177312231 * log(k - 10) - 305.0447927307)).clamped(to: 0 ... 255.0) / 255
return (r: r, g: g, b: b)
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import SwiftUI

// Thanks to https://useyourloaf.com/blog/fetching-oslog-messages-in-swift/

struct LogsViewer: View {
public struct LogsViewer: View {
private static let template = NSPredicate(format:
"(subsystem BEGINSWITH $PREFIX)")

Expand All @@ -25,7 +25,7 @@ struct LogsViewer: View {
.system(size: 10)
.monospaced()

var body: some View {
public var body: some View {
ScrollView {
Text(text)
.font(myFont)
Expand All @@ -36,6 +36,8 @@ struct LogsViewer: View {
}
}

public init() {}

private func fetchLogs() async -> String {
let calendar = Calendar.current
guard let dayAgo = calendar.date(
Expand Down
79 changes: 79 additions & 0 deletions CommonUI/Sources/CommonUI/OHTextTokenStyle.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright (c) 2010-2026 Contributors to the openHAB project
//
// See the NOTICE file(s) distributed with this work for additional
// information.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License 2.0 which is available at
// http://www.eclipse.org/legal/epl-2.0
//
// SPDX-License-Identifier: EPL-2.0

import SwiftUI

public enum OHTextToken {
case rowLabel
case rowValue
case rowValueCompact
case rowValueCallout
case section
case control
case secondary
case emphasis
}

public enum OHAccessibilityToken {
public static let minimumHitTarget: CGFloat = 44
}

private struct OHTextTokenModifier: ViewModifier {
let token: OHTextToken

func body(content: Content) -> some View {
let style = OHTextTokenStyle.from(token)
content
.font(style.font)
.lineLimit(style.lineLimit)
.minimumScaleFactor(style.minimumScaleFactor)
.truncationMode(.tail)
.multilineTextAlignment(.leading)
}
}

private struct OHTextTokenStyle {
let font: Font
let lineLimit: Int
let minimumScaleFactor: CGFloat

static func from(_ token: OHTextToken) -> OHTextTokenStyle {
switch token {
case .rowLabel:
OHTextTokenStyle(font: .body, lineLimit: 1, minimumScaleFactor: 0.9)
case .rowValue:
OHTextTokenStyle(font: .body, lineLimit: 1, minimumScaleFactor: 0.9)
case .rowValueCompact:
OHTextTokenStyle(font: .caption, lineLimit: 1, minimumScaleFactor: 0.9)
case .rowValueCallout:
OHTextTokenStyle(font: .callout, lineLimit: 1, minimumScaleFactor: 0.9)
case .section:
OHTextTokenStyle(font: .callout, lineLimit: 1, minimumScaleFactor: 0.85)
case .control:
OHTextTokenStyle(font: .footnote, lineLimit: 1, minimumScaleFactor: 0.85)
case .secondary:
OHTextTokenStyle(font: .caption, lineLimit: 1, minimumScaleFactor: 0.9)
case .emphasis:
OHTextTokenStyle(font: .headline, lineLimit: 1, minimumScaleFactor: 0.9)
}
}
}

public extension View {
func ohTextToken(_ token: OHTextToken) -> some View {
modifier(OHTextTokenModifier(token: token))
}

/// Applies the standard minimum tappable target used across row controls.
func ohMinimumHitTarget(_ minHeight: CGFloat = OHAccessibilityToken.minimumHitTarget) -> some View {
frame(minHeight: minHeight)
}
}
Loading