Consumer IoT companion app · 2024–2026
Dash Cam LINK
Reframing a legacy IoT companion app around reliable footage retrieval under pressure.
- Client
- Thinkware (South Korea)
- Role
- Sole UI/UX designer on the BA team
- Outcome
- 100K+ users · 70% / 60% Android / iOS satisfaction maintained
















My Role
Sole UI/UX Designer, embedded in the BA team
I was the only product designer in Thinkware's Vietnam office, sitting in the BA sub-team with no design lead. I redesigned the whole app on a new UI, from camera connection over Wi-Fi and BLE to the connection guide, help center, live view, and media file list; the flows in this case study are a subset of that work. Today I hold and maintain most of the product's UI/UX documentation.
- Team
- Two BA peers, the PM, native Android (Kotlin) and iOS (SwiftUI) engineers, and QA
- Product owner and executives in Korea HQ, reviewed across time zones daily
- Camera hardware and firmware owned by Korea HQ
- What I owned
- Audit of 100+ existing screens before any redesign
- UI for the full redesign of the legacy app, shipped, covering existing features and new ones alike
- Connection flow, dynamic font scale, and in-app rating, the three features this case study follows
- End-to-end UX documentation for connection, retrieval, loading, and error flows, where none existed
- About 80% of the product's UI/UX documentation in Figma; the BA peers wrote the rest
- Cross-platform design system on a Material Design baseline, tokens in Figma variables
- Strategy & collaboration
- Learned the product by testing the camera hardware hands-on for a full week before touching a screen
- Analyzed requirements and drew flows the way a BA would, then designed the UI, one seat covering both
- Mapped user actions against scan, handshake, and fetch to find where friction was actually generated
- Used a Painkiller-versus-Vitamin lens to keep reliability ahead of the visual refresh
- Translated firmware and hardware limits into design decisions with engineers and QA in every sprint
- Kept Figma as the source of truth, with flows and annotations on the design surface for Korea HQ review
Context
Thinkware Dash Cam LINK connects more than 100,000 drivers worldwide to their in-vehicle cameras. Years of incremental updates for new models had left it dependent on a fragmented legacy architecture, making connection, loading, and system feedback increasingly inconsistent.






Diagnosis
Users experienced slow scanning, unstable connection, delayed video loading, and technical configuration they had no reason to understand. These were not isolated interface defects; they emerged from varied camera models, connection methods, hardware limitations, and an aging foundation.
I mapped opening, connecting, and viewing against the underlying scan, handshake, and fetch processes. This exposed three bottlenecks—slow discovery, unstable connection, and load delay—and showed where guidance could reduce uncertainty even when the constraint remained.
User action
what the driver does
open app
connect
view video
System process
what the app runs underneath
scan
handshake
fetch
Bottleneck
where the legacy foundation breaks
slow scan
unstable connection
load delay
Bottleneck notes
Slow scan
Legacy foundation can't parallelize device discovery — Wi-Fi enumeration stalls on multi-camera setups.
Unstable connection
Bluetooth handshake drops when the phone backgrounds the app, forcing manual re-pair.
Load delay
Thumbnail decode blocks the gallery thread on hardware-constrained devices, freezing the list.
Strategy
Dash cam use is situational. Drivers may ignore the app for long periods, then open it after an accident when speed and certainty matter. Its core job was not general video management, but reliable retrieval under pressure.
Dash Cam LINK is not a UI problem. It is a system problem.
I used a Painkiller-versus-Vitamin lens to prioritize the redesign. Reliable connection, loading, playback, and retrieval were the painkillers. A modern visual language was supporting value. Success shifted from feature completeness to time-to-retrieve, from visual polish to reliability, and from navigation depth to direct access. Changes that did not support the critical task were deprioritized.
Decisions
Keep connection state visible
Different cameras and connection methods created varied setup paths and failures. I designed guidance for Bluetooth, Wi-Fi, and QR code, auto-reconnection for paired Bluetooth models, and explicit feedback across scanning, pairing, failure, and retry. The interface could not remove complexity, but it could prevent silent uncertainty.
Engineering had to maintain more edge-case logic across camera models and connection methods.
Activity flow
Branches
Auto-reconnect
IdlePairingPreviously paired Bluetooth cameras skip Scanning, Discovered and the Connection guide — straight to Pairing on app launch.
Guidance
ScanningHelpStalled scan offers a Help branch with model-specific instructions and connection-method picker.
Error retry
Error guidePairingEach error mode has a specific labeled cause and recovery steps; once resolved, the flow loops back to Pairing rather than restarting from Idle.
Organize retrieval around the incident
The legacy gallery used rigid folders and repeated information across camera-angle views. I proposed grouping related clips around the incident and exposing camera angle as a tag, reducing navigation between an event and its footage.
This prioritizes incident retrieval over browsing by camera angle. The proposal has not shipped, so its effect on retrieval time remains unvalidated.






Respect the user's text preference
I introduced dynamic font scaling backed by shared typography tokens. Layouts adapt to OS-driven text settings, improving legibility without requiring users to zoom.
Dynamic type expanded the responsive-layout and testing matrix across two native platforms.
Capture feedback inside the product
I designed an in-app rating feature to collect first-party feedback with product context. Internal data records 600–1,000 reviews per month; the figures below come from this channel, not public app-store ratings.
First-party feedback adds storage, moderation, and triage work, but gives the team a more actionable signal.

70% / 60%
Android / iOS in-app rating maintained
600–1,000
reviews collected per month
Source: internal in-app rating data, confirmed by the designer. These are not public app-store ratings. The measurement period and calculation method are not specified here.
Foundation
I used Material Design as the baseline for native Android in Kotlin and iOS in SwiftUI, with Noto Sans for multilingual consistency. Figma variables defined shared spacing, typography, and color rules. The choice served scalability and maintenance rather than a visual reset.
- 01
System fidelity over visual novelty
Stay true to MD3 baseline — UI is not where this product wins.
- 02
Android-first, iOS-aligned
Tokens validate on Kotlin first; SwiftUI inherits unchanged.
- 03
Refactor, don't rewrite
Components map onto legacy code so the UI ships in place.
- 20
- components
- 80
- tokens
- 2
- themes
- 2
- platforms
Color · derived from #1062AD
Typography · Noto Sans
Buttons
Filled · Tonal · TextIcon button
Standard · Filled · TonalText field
FilledList item
Featured · Actionable, 2-line- LeadingTonal blue 16% · 24 dp
- HeadlineBody-medium · on-surface
- SupportingBody-small · primary
- Trailingchevron_right
Snackbar
With actionDialog
BasicI also audited more than 100 screens and documented connection, retrieval, loading, error, and edge-case flows, creating a shared reference across design, BA, engineering, and QA.
Outcome
100K+
users worldwide
70% / 60%
Android / iOS in-app rating maintained
Internal in-app rating data. The measurement period and calculation method are not specified here; these are not public app-store ratings.
Steady
user growth through redesign rollout
The released work maintained the reported internal rating figures while replacing missing UX documentation with a structured cross-platform foundation. The connection flow, dynamic font scale, and in-app rating feature shipped; the event-first gallery did not, and no released outcome is attributed to it.
The project changed how I approach constrained products: diagnose where the friction is generated before redesigning its surface, prioritize the critical user task over feature breadth, and make system state understandable when the underlying complexity cannot yet be removed.
Next case study