Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions .Jules/palette.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,7 @@
## 2026-05-30 - User-Facing System Notifications
**Learning:** Foreground service notifications and channels are exposed directly to users within their system drawer and app settings. Hardcoding technical or aggressive terminology (e.g., naming a channel ID as the visible name or using "Kill" as an action button) degrades the user experience and violates UX standards. Furthermore, failing to extract these strings to `strings.xml` prevents localization and accessibility optimizations.
**Action:** Always avoid hardcoded, technical, or aggressive terminology in user-facing system notifications and foreground service controls. Utilize standard mobile UX phrasing (e.g., "Stop", "Tap") and ensure all notification text (titles, descriptions, actions) is extracted to localized string resources.

## 2026-05-31 - Initial Content Descriptions for Secondary Actions
**Learning:** Interactive elements with dynamic text that also perform a secondary action (e.g., an IP address `TextView` that copies its text to the clipboard when clicked) must have their actionable `contentDescription` set immediately upon view creation. If the content description is only assigned dynamically *after* an asynchronous data fetch completes, screen readers will incorrectly announce the raw placeholder text (e.g., "0.0.0.0:8080/cam.mjpeg") without any interaction context if the user focuses the view before the fetch finishes.
**Action:** Always programmatically set the initial, actionable `contentDescription` (e.g., combining the default placeholder text with the action tooltip) during view initialization (like in `onCreateView` or `onViewCreated`) to ensure interaction context is available before the first dynamic update occurs.
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ class CameraFragment : Fragment() {
): View {
_fragmentCameraBinding = FragmentCameraBinding.inflate(inflater, container, false)

val defaultIpText = getString(R.string.default_ip)
_fragmentCameraBinding?.textView6?.contentDescription = getString(R.string.actionable_content_description_format, defaultIpText, getString(R.string.copy_ip_tooltip))

// Get the local ip address
viewLifecycleOwner.lifecycleScope.launch {
val localIp = IpUtil.getLocalIpAddress()
Expand Down