Skip to content

Migrate DatePickerInputRowView from DateFormatter to FormatStyle API#1103

Open
timbms wants to merge 692 commits intodevelopfrom
migration3FormatStyle
Open

Migrate DatePickerInputRowView from DateFormatter to FormatStyle API#1103
timbms wants to merge 692 commits intodevelopfrom
migration3FormatStyle

Conversation

@timbms
Copy link
Copy Markdown
Contributor

@timbms timbms commented Mar 14, 2026

Summary

  • Replaces DateFormatter.iso8601Full with Date.ISO8601FormatStyle(includingFractionalSeconds: true) for parsing server state strings in DatePickerInputRowView
  • Replaces DateFormatter.iso8601Full.string(from:) with date.formatted(Date.ISO8601FormatStyle(includingFractionalSeconds: true).timeZone(.current)) for formatting commands sent to the server — .timeZone(.current) preserves the existing behaviour of including the device's local timezone offset
  • Deletes DateFormatterExtension.swift (now unused)

This completes the FormatStyle migration: no NumberFormatter or DateFormatter remains in the codebase.

Test plan

  • Build succeeds with no warnings
  • Open a sitemap containing a DateTime item; verify the DatePicker shows the correct initial value
  • Change the date/time via the picker; verify the command logged and sent to the server is a valid ISO 8601 string with fractional seconds and local timezone offset (e.g. 2026-03-14T10:30:00.000+01:00)
  • Simulate a server-pushed state update; verify the picker updates to the new value

timbms and others added 30 commits January 31, 2026 09:13
…d pages

- Fix charts not displaying in linked pages by setting openHABRootUrl
  from active connection in SitemapPageViewModel init
- Hide labelValue for chart widgets (only show for images)
- Add animated sliding selection indicator to SegmentedRowView
- Improve segmented control contrast with systemGray5/systemGray3 colors

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Escape trailing % in format strings that aren't already escaped.
Server-side patterns like "%.0f %" should become "%.0f %%" to properly
display a literal percent sign in String(format:).

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
…in a Button based on the switchSupport property

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Alignment with develop

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Bert <5411131+timbms@users.noreply.github.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
… to obtain wider segmented buttons

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Update logic skips refreshing the widget's type, leading to stale types showing as switches instead of charts; adding type assignment during updates should fix the display inconsistency.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
adjust the slider binding to reflect the live widget value when not dragging, and sync the internal state when editing starts.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
keep the row visible by separating the visible content from the Menu label, and overlaying a clear hit target

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Refactor watchOS row views to use widget.type directly (matching iOS pattern)
instead of the legacy stateEnum. Add TextRow for text widget support.

- Add TextRow.swift for watchOS text widget display
- Refactor SwitchRow to use local @State for toggle state
- Refactor SegmentRow/SegmentSelectionView to use local @State for selection
- Update SitemapPageView.rowWidget to switch on widget.type
- Remove WidgetTypeEnum, stateEnum, and stateEnumBinding from OpenHABWidget

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
- Add SelectionRow.swift with SelectionListView for selection widget support
- Add disclosure indicator (chevron) to TextRow when widget has linkedPage
- Use chevronUpChevronDown icon for SelectionRow matching iOS style

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
- Change IconWithAction to use Button instead of onTapGesture for reliable tap handling in List rows
- Add disabled state and grayed out styling to watchOS SetpointRow buttons at min/max values
- Use widget.unit as fallback when creating NumberState for dimension items
- Include unit in log messages for better debugging

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Make TextLabelView configurable with optional font and lineLimit
parameters so it can be shared between platforms. iOS defaults to
body font with lineLimit 1, while watchOS explicitly uses caption
font with lineLimit 2 to preserve existing behavior.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
- SegmentedRowView: Move spacer inside conditional to avoid gap when
  there's no value label
- ColorSelection: Remove redundant type annotation
- Add CommonUI Package.resolved

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Use Color(fromString:) from CommonUI to properly parse hex color
strings like "#00AA00". The previous code used Color(widget.valuecolor)
which doesn't handle hex strings, causing values with custom colors
to not display.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
- Add fallbackSymbol parameter to IconView for SF Symbol fallback
  when network icons are unavailable (useful for previews)
- Add fallbackSymbol parameter to SegmentedRowView, forwarded to IconView
- Create PreviewList helper to reduce boilerplate in previews
- Update previews to use List with proper insets matching SitemapPageView
- Scale fallback symbol to 75% for better visual match with network icons

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
timbms and others added 28 commits March 10, 2026 08:21
Remove duplicate PBXFileSystemSynchronizedRootGroup entry and orphaned
(null) SDWebImage framework build file reference.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Add custom back button to NotificationsView and ensure nav bar is
visible when pushing it from OpenHABRootViewController. Also remove
unused maxBackoffDelay constant in UserData.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: openhab-bot <info@openhabfoundation.org>
Signed-off-by: DigiH <17110652+DigiH@users.noreply.github.com>
Same fix as NotificationsView: show nav bar before pushing
HomeSelectionView and add a custom back button to the toolbar.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: DigiH <17110652+DigiH@users.noreply.github.com>
* Fix screensaver layout sizing

---------

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Replace NumberFormatter (with invalid "US" locale) with
Float(_:format:) using en_US_POSIX for reliable decimal parsing.
Add CGFloatExtensionTests covering basic division, decimal input,
locale robustness, invalid strings, and edge cases.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
…ingTests

Replace legacy DateFormatter.iso8601Full with JSONDecoder.makeISO8601TolerantDecoder()
which uses Date.ISO8601FormatStyle. Update HTTPClient to use the new decoder.
Add comprehensive DateFormattingTests covering ISO8601 parsing, round-trip,
JSON decoding, log formatting, screensaver time, and notification timestamp formats.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Replace legacy regex and NumberFormatter usage in StringExtension with
modern Swift equivalents. Add comprehensive StringExtensionTests covering
doubleValue, intValue, numberValue, and asDouble parsing behaviour.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Without it, internal members (doubleValue, intValue, etc.) are
inaccessible from the test target.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
The ASAN configuration was the only one, forcing all runs to use Address
Sanitizer. This caused 'Undefined symbol: ___asan_alloca_poison' because
the host app binary isn't built with ASAN instrumentation. Add a plain
default 'Test' configuration; ASAN remains available for explicit use.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Add OTHER_LDFLAGS = -undefined dynamic_lookup to the test target so the
linker defers resolution of dynamic framework symbols (SDWebImageSVGCoder,
etc.) to runtime, where they are already loaded by the host app.

Also remove the redundant SDImageSVGCoder registration in OpenHABSVGTests
setUpWithError — AppDelegate already registers the coder before tests run.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Replace 'import SDWebImageSVGCoder' with ObjC runtime lookup via
NSClassFromString("SDImageSVGCoder"). This eliminates the hard link-time
dependency on SDWebImage data symbols (_SDImageCoderDecodePreserveAspectRatio
etc.) that BUNDLE_LOADER and -undefined dynamic_lookup cannot reliably resolve.

The coder is already registered by AppDelegate before any tests run,
so runtime lookup is sufficient. Also revert the -undefined dynamic_lookup
OTHER_LDFLAGS added in the previous commit.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
- Add OpenAPIErrorInspector utility to OpenHABCore, centralising all
  ClientError unwrapping so callers don't need to import OpenAPIRuntime
- Remove OpenAPIRuntime imports from SitemapPageViewModel and
  SingleConnectionSettingsView; replace ClientError casts with inspector
- Add SDWebImage as explicit Package.swift dependency (required now that
  OpenHABCore uses SDWebImage APIs directly)
- Add process(data:) convenience on OpenHABImageProcessor for test use
- Migrate OpenHABSVGTests from XCTest to Swift Testing (@Suite/@Test/#expect)
  and replace fragile ObjC-runtime SDImageSVGCoder lookup with direct
  OpenHABImageProcessor call via @testable import OpenHABCore
- Add dedicated openHABTestsSwift.xctestplan; point openHABTestsSwift
  scheme at it; remove ASAN config from openHABTests plan

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
The Main UI script editor height does not account for the bottom
toolbar's safe area padding on iPhone, causing the last 2-3 lines
to be hidden behind the toolbar and unreachable by scrolling.

Inject a JavaScript fix via WKWebView that adds bottom padding to
the page content and CodeMirror scroll container equal to the native
safe area inset plus any FAB button height. A MutationObserver
re-applies the fix on SPA navigation back to the script editor page.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
CI uses testplan: 'openHABTests' in the Fastfile unittests lane, but the
scheme only had openHABTestsSwift.xctestplan associated, causing xcodebuild
to error with 'Scheme does not have an associated test plan named openHABTests'.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
ASan instrumentation causes undefined symbol errors (___asan_alloca_poison)
when Swift Package Manager dependencies are not recompiled with ASan support.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: openhab-bot <info@openhabfoundation.org>
…1102)

* Fix empty string commands and switch sendItemCommand to JSON payload

Text input items can now be cleared by submitting an empty string. Previously,
empty commands were silently dropped in both InputCommandFormatter and
WidgetCommandDispatcher. The guard order in InputCommandFormatter.command() is
corrected so that only number hints reject empty input; text hints pass through
an empty string as a valid "clear" command.

Also fixes the openapi.json schema for sendItemCommand, which incorrectly
declared the application/json body as type:string. It is now type:object with a
required "value" field, matching the actual server contract. Types.swift and
OpenAPIService are regenerated/updated accordingly.

---------

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: openhab-bot <info@openhabfoundation.org>
Replace DateFormatter.iso8601Full with Date.ISO8601FormatStyle for both
parsing and formatting in DatePickerInputRowView. Delete the now-unused
DateFormatterExtension.swift. This completes the FormatStyle migration;
no NumberFormatter or DateFormatter remains in the codebase.

Formatting uses .timeZone(.current) to preserve the existing behaviour
of sending the device's local timezone offset to the server.

Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
Signed-off-by: Tim Mueller-Seydlitz <timbms@gmail.com>
@TAKeanice TAKeanice force-pushed the openapigen-swiftui branch from 1f242b5 to 166a59c Compare March 26, 2026 19:49
Base automatically changed from openapigen-swiftui to develop March 30, 2026 19:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants