Skip to content
Merged
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
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ uses semantic versioning (`MAJOR.MINOR.PATCH`).
that matters when your authenticator is lost or on a replaced phone;
before, the field only accepted 6 digits and locked those users out.

- **Action buttons are readable by screen readers.** The home "Switch"
button and the New poll / New reminder / New invite buttons exposed no
label to accessibility services, so TalkBack users could not find or
activate them. They now announce their action.

- **Watch data screens no longer fail to load.** The Wear OS app read
network responses on the wrong thread, so member, front and history
screens would show "Failed to load" (reliably on large responses,
intermittently at sign-in). Responses are now read off the main thread.

## [1.2.1] - 2026-07-04

### Added
Expand Down
11 changes: 11 additions & 0 deletions sheaf/app/src/main/java/systems/lupine/sheaf/ui/home/HomeScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import androidx.compose.material3.pulltorefresh.PullToRefreshBox
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.style.TextOverflow
Expand Down Expand Up @@ -111,6 +114,14 @@ fun HomeScreen(
onClick = { viewModel.openSwitchSheet() },
icon = { Icon(Icons.Outlined.SwitchAccount, contentDescription = null) },
text = { Text("Switch") },
// The FAB's label lives in the text slot, which Material3 wraps in
// an AnimatedVisibility for the expand/collapse animation; that can
// drop the text's semantics and leave the merged node unlabeled (and
// effectively invisible to TalkBack / uiautomator). Set the label on
// the FAB itself so it never depends on the animated child.
modifier = Modifier
.testTag("home_switch_fab")
.semantics { contentDescription = "Switch" },
)
},
// Quick-switch chip row pinned above the bottom navigation. Sits
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import systems.lupine.sheaf.data.model.NotificationChannelRead
Expand Down Expand Up @@ -77,6 +80,11 @@ fun ChannelsYouOwnScreen(
onClick = onCreateNew,
icon = { Icon(Icons.Outlined.Add, contentDescription = null) },
text = { Text("New invite") },
// Label the FAB directly; the text slot's semantics can be dropped
// by Material3's expand/collapse AnimatedVisibility. See HomeScreen.
modifier = Modifier
.testTag("channels_new_fab")
.semantics { contentDescription = "New invite" },
)
},
) { padding ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import systems.lupine.sheaf.data.model.ReminderRead
Expand Down Expand Up @@ -77,6 +80,11 @@ fun RemindersScreen(
onClick = onCreateNew,
icon = { Icon(Icons.Outlined.Add, contentDescription = null) },
text = { Text("New reminder") },
// Label the FAB directly; the text slot's semantics can be dropped
// by Material3's expand/collapse AnimatedVisibility. See HomeScreen.
modifier = Modifier
.testTag("reminders_new_fab")
.semantics { contentDescription = "New reminder" },
)
},
) { padding ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import systems.lupine.sheaf.data.model.PollRead
Expand Down Expand Up @@ -59,6 +62,11 @@ fun PollsScreen(
onClick = onCreateNew,
icon = { Icon(Icons.Outlined.Add, contentDescription = null) },
text = { Text("New poll") },
// Label the FAB directly; the text slot's semantics can be dropped
// by Material3's expand/collapse AnimatedVisibility. See HomeScreen.
modifier = Modifier
.testTag("polls_new_fab")
.semantics { contentDescription = "New poll" },
)
},
) { padding ->
Expand Down
Loading