A fork of Simple Time Tracker with WearOS support. (Now integrated upstream)
0

Configure Feed

Select the types of activity you want to include in your feed.

refactor(wear): Clean up resources

- Delete unused icons
- Extract hard-coded strings
- Add Spanish Translations for WearOS

Joseph Hale (Feb 26, 2024, 10:27 PM -0700) a5b0a71b 0a7b1458

+93 -94
+40 -11
wear/src/main/java/com/example/util/simpletimetracker/presentation/components/ActivitiesList.kt
··· 5 5 */ 6 6 package com.example.util.simpletimetracker.presentation.components 7 7 8 + import androidx.compose.foundation.layout.padding 8 9 import androidx.compose.runtime.Composable 10 + import androidx.compose.ui.Modifier 11 + import androidx.compose.ui.platform.LocalContext 9 12 import androidx.compose.ui.tooling.preview.Preview 13 + import androidx.compose.ui.unit.dp 14 + import androidx.wear.compose.material.Text 10 15 import androidx.wear.tooling.preview.devices.WearDevices 16 + import com.example.util.simpletimetracker.R 11 17 import com.example.util.simpletimetracker.presentation.layout.ScaffoldedScrollingColumn 12 18 import com.example.util.simpletimetracker.wearrpc.Activity 13 19 import com.example.util.simpletimetracker.wearrpc.CurrentActivity ··· 22 28 onRefresh: () -> Unit, 23 29 ) { 24 30 ScaffoldedScrollingColumn { 25 - for (activity in activities) { 26 - val currentActivity = currentActivities.filter { it.id == activity.id }.getOrNull(0) 27 - item(key = activity.id) { 28 - ActivityChip( 29 - activity, 30 - startedAt = currentActivity?.startedAt, 31 - tags = currentActivity?.tags ?: arrayOf(), 32 - onPress = { onSelectActivity(activity) }, 33 - onToggleOn = { onEnableActivity(activity) }, 34 - onToggleOff = { onDisableActivity(activity) }, 31 + if (activities.isEmpty()) { 32 + item { 33 + Text( 34 + LocalContext.current.getString(R.string.no_activities), 35 + modifier = Modifier.padding(8.dp), 35 36 ) 36 37 } 38 + } else { 39 + for (activity in activities) { 40 + val currentActivity = currentActivities.filter { it.id == activity.id }.getOrNull(0) 41 + item(key = activity.id) { 42 + ActivityChip( 43 + activity, 44 + startedAt = currentActivity?.startedAt, 45 + tags = currentActivity?.tags ?: arrayOf(), 46 + onPress = { onSelectActivity(activity) }, 47 + onToggleOn = { onEnableActivity(activity) }, 48 + onToggleOff = { onDisableActivity(activity) }, 49 + ) 50 + } 51 + } 37 52 } 53 + 38 54 item { RefreshButton(onClick = onRefresh) } 39 55 } 40 56 } 41 57 42 58 @Preview(device = WearDevices.LARGE_ROUND) 43 59 @Composable 60 + private fun NoActivities() { 61 + ActivitiesList( 62 + activities = arrayOf(), 63 + currentActivities = arrayOf(), 64 + onSelectActivity = { /* `it` is the selected activity */ }, 65 + onEnableActivity = { /* `it` is the enabled activity */ }, 66 + onDisableActivity = { /* `it` is the disabled activity */ }, 67 + onRefresh = { /* What to do when requesting a refresh */ }, 68 + ) 69 + } 70 + 71 + @Preview(device = WearDevices.LARGE_ROUND) 72 + @Composable 44 73 private fun Preview() { 45 74 val activities = arrayOf( 46 75 Activity(1234, "Chores", "🧹", 0xFFFA0000), ··· 50 79 CurrentActivity(id = 4321, startedAt = 1708241427000L, tags = arrayOf()), 51 80 ) 52 81 ActivitiesList( 53 - activities, 82 + activities = activities, 54 83 currentActivities = currents, 55 84 onSelectActivity = { /* `it` is the selected activity */ }, 56 85 onEnableActivity = { /* `it` is the enabled activity */ },
+9 -2
wear/src/main/java/com/example/util/simpletimetracker/presentation/components/RefreshButton.kt
··· 16 16 import androidx.compose.ui.unit.dp 17 17 import androidx.wear.compose.material.Icon 18 18 import androidx.wear.compose.material.OutlinedButton 19 + import com.example.util.simpletimetracker.R 19 20 20 21 @Composable 21 - fun RefreshButton(onClick: () -> Unit, contentDescription: String = "Refresh") { 22 + fun RefreshButton(onClick: () -> Unit, contentDescription: String? = null) { 22 23 val context = LocalContext.current 24 + 23 25 24 26 OutlinedButton( 25 27 onClick = { ··· 28 30 onClick() 29 31 }, 30 32 content = { 31 - Icon(Icons.Rounded.Refresh, contentDescription = contentDescription) 33 + Icon( 34 + Icons.Rounded.Refresh, 35 + contentDescription = contentDescription ?: context.getString( 36 + R.string.refresh_button_default_content_description, 37 + ), 38 + ) 32 39 }, 33 40 modifier = Modifier.padding(all = 8.dp), 34 41 )
+8 -2
wear/src/main/java/com/example/util/simpletimetracker/presentation/components/SubmitButton.kt
··· 10 10 import androidx.compose.material.icons.automirrored.rounded.Send 11 11 import androidx.compose.runtime.Composable 12 12 import androidx.compose.ui.Modifier 13 + import androidx.compose.ui.platform.LocalContext 13 14 import androidx.compose.ui.tooling.preview.Preview 14 15 import androidx.compose.ui.unit.dp 15 16 import androidx.wear.compose.material.Icon 16 17 import androidx.wear.compose.material.OutlinedButton 18 + import com.example.util.simpletimetracker.R 17 19 18 20 @Composable 19 - fun SubmitButton(onClick: () -> Unit, contentDescription: String = "Submit") { 21 + fun SubmitButton(onClick: () -> Unit, contentDescription: String? = null) { 20 22 OutlinedButton( 21 23 onClick = onClick, 22 24 content = { 23 - Icon(Icons.AutoMirrored.Rounded.Send, contentDescription = contentDescription) 25 + Icon( 26 + Icons.AutoMirrored.Rounded.Send, 27 + contentDescription = contentDescription 28 + ?: LocalContext.current.getString(R.string.submit_button_default_content_description), 29 + ) 24 30 }, 25 31 modifier = Modifier.padding(all = 8.dp), 26 32 )
+24 -11
wear/src/main/java/com/example/util/simpletimetracker/presentation/components/TagList.kt
··· 12 12 import androidx.compose.runtime.remember 13 13 import androidx.compose.runtime.setValue 14 14 import androidx.compose.ui.Modifier 15 + import androidx.compose.ui.platform.LocalContext 15 16 import androidx.compose.ui.tooling.preview.Preview 16 17 import androidx.compose.ui.unit.dp 17 18 import androidx.wear.compose.material.Text 18 19 import androidx.wear.tooling.preview.devices.WearDevices 20 + import com.example.util.simpletimetracker.R 19 21 import com.example.util.simpletimetracker.presentation.layout.ScaffoldedScrollingColumn 20 22 import com.example.util.simpletimetracker.wearrpc.Tag 21 23 ··· 28 30 var selectedTags: List<Tag> by remember { mutableStateOf(listOf()) } 29 31 ScaffoldedScrollingColumn { 30 32 if (tags.isEmpty()) { 31 - item { Text("No tags", modifier = Modifier.padding(8.dp)) } 33 + item { 34 + Text( 35 + LocalContext.current.getString(R.string.no_tags), 36 + modifier = Modifier.padding(8.dp), 37 + ) 38 + } 32 39 } else { 33 40 for (tag in tags) { 34 41 item { 35 - TagChip(tag = tag, mode = mode, onClick = { 36 - when (mode) { 37 - TagSelectionMode.SINGLE -> { onSelectionComplete(arrayOf(tag)) } 38 - TagSelectionMode.MULTI -> { 39 - if (selectedTags.contains(tag)) { 40 - selectedTags = selectedTags.minus(tag) 41 - } else { 42 - selectedTags = selectedTags.plus(tag) 42 + TagChip( 43 + tag = tag, mode = mode, 44 + onClick = { 45 + when (mode) { 46 + TagSelectionMode.SINGLE -> { 47 + onSelectionComplete(arrayOf(tag)) 48 + } 49 + 50 + TagSelectionMode.MULTI -> { 51 + if (selectedTags.contains(tag)) { 52 + selectedTags = selectedTags.minus(tag) 53 + } else { 54 + selectedTags = selectedTags.plus(tag) 55 + } 43 56 } 44 57 } 45 - } 46 - }) 58 + }, 59 + ) 47 60 } 48 61 } 49 62 }
-5
wear/src/main/res/drawable/baseline_bed_24.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="@android:color/white" android:pathData="M21,10.78V8c0,-1.65 -1.35,-3 -3,-3h-4c-0.77,0 -1.47,0.3 -2,0.78C11.47,5.3 10.77,5 10,5H6C4.35,5 3,6.35 3,8v2.78C2.39,11.33 2,12.12 2,13v6h2v-2h16v2h2v-6C22,12.12 21.61,11.33 21,10.78zM14,7h4c0.55,0 1,0.45 1,1v2h-6V8C13,7.45 13.45,7 14,7zM5,8c0,-0.55 0.45,-1 1,-1h4c0.55,0 1,0.45 1,1v2H5V8z"/> 5 - </vector>
-5
wear/src/main/res/drawable/baseline_check_box_24.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="@android:color/white" android:pathData="M19,3L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.11,0 2,-0.9 2,-2L21,5c0,-1.1 -0.89,-2 -2,-2zM10,17l-5,-5 1.41,-1.41L10,14.17l7.59,-7.59L19,8l-9,9z"/> 5 - </vector>
-5
wear/src/main/res/drawable/baseline_church_24.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="@android:color/white" android:pathData="M18,12.22V9l-5,-2.5V5h2V3h-2V1h-2v2H9v2h2v1.5L6,9v3.22L2,14v8h8v-3c0,-1.1 0.9,-2 2,-2s2,0.9 2,2v3h8v-8L18,12.22zM12,13.5c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5s1.5,0.67 1.5,1.5S12.83,13.5 12,13.5z"/> 5 - </vector>
-5
wear/src/main/res/drawable/baseline_computer_24.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="@android:color/white" android:pathData="M20,18c1.1,0 1.99,-0.9 1.99,-2L22,6c0,-1.1 -0.9,-2 -2,-2H4c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2H0v2h24v-2h-4zM4,6h16v10H4V6z"/> 5 - </vector>
-5
wear/src/main/res/drawable/baseline_directions_car_24.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="@android:color/white" android:pathData="M18.92,6.01C18.72,5.42 18.16,5 17.5,5h-11c-0.66,0 -1.21,0.42 -1.42,1.01L3,12v8c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1h12v1c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-8l-2.08,-5.99zM6.5,16c-0.83,0 -1.5,-0.67 -1.5,-1.5S5.67,13 6.5,13s1.5,0.67 1.5,1.5S7.33,16 6.5,16zM17.5,16c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM5,11l1.5,-4.5h11L19,11L5,11z"/> 5 - </vector>
-5
wear/src/main/res/drawable/baseline_heart_broken_24.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="@android:color/white" android:pathData="M16.5,3c-0.96,0 -1.9,0.25 -2.73,0.69L12,9h3l-3,10l1,-9h-3l1.54,-5.39C10.47,3.61 9.01,3 7.5,3C4.42,3 2,5.42 2,8.5c0,4.13 4.16,7.18 10,12.5c5.47,-4.94 10,-8.26 10,-12.5C22,5.42 19.58,3 16.5,3z"/> 5 - </vector>
-6
wear/src/main/res/drawable/baseline_home_work_24.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="@android:color/white" android:pathData="M1,11l0,10l5,0l0,-6l4,0l0,6l5,0l0,-10l-7,-5z"/> 5 - <path android:fillColor="@android:color/white" android:pathData="M10,3v1.97l7,5V11h2v2h-2v2h2v2h-2v4h6V3H10zM19,9h-2V7h2V9z"/> 6 - </vector>
-6
wear/src/main/res/drawable/baseline_horizontal_rule_24.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="@android:color/white" 5 - android:fillType="evenOdd" android:pathData="M4,11h16v2h-16z"/> 6 - </vector>
-5
wear/src/main/res/drawable/baseline_people_24.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="@android:color/white" android:pathData="M16,11c1.66,0 2.99,-1.34 2.99,-3S17.66,5 16,5c-1.66,0 -3,1.34 -3,3s1.34,3 3,3zM8,11c1.66,0 2.99,-1.34 2.99,-3S9.66,5 8,5C6.34,5 5,6.34 5,8s1.34,3 3,3zM8,13c-2.33,0 -7,1.17 -7,3.5L1,19h14v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5zM16,13c-0.29,0 -0.62,0.02 -0.97,0.05 1.16,0.84 1.97,1.97 1.97,3.45L17,19h6v-2.5c0,-2.33 -4.67,-3.5 -7,-3.5z"/> 5 - </vector>
-5
wear/src/main/res/drawable/baseline_question_mark_24.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="@android:color/white" android:pathData="M11.07,12.85c0.77,-1.39 2.25,-2.21 3.11,-3.44c0.91,-1.29 0.4,-3.7 -2.18,-3.7c-1.69,0 -2.52,1.28 -2.87,2.34L6.54,6.96C7.25,4.83 9.18,3 11.99,3c2.35,0 3.96,1.07 4.78,2.41c0.7,1.15 1.11,3.3 0.03,4.9c-1.2,1.77 -2.35,2.31 -2.97,3.45c-0.25,0.46 -0.35,0.76 -0.35,2.24h-2.89C10.58,15.22 10.46,13.95 11.07,12.85zM14,20c0,1.1 -0.9,2 -2,2s-2,-0.9 -2,-2c0,-1.1 0.9,-2 2,-2S14,18.9 14,20z"/> 5 - </vector>
-6
wear/src/main/res/drawable/baseline_timer_24.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="@android:color/white" android:pathData="M9,1h6v2h-6z"/> 5 - <path android:fillColor="@android:color/white" android:pathData="M19.03,7.39l1.42,-1.42c-0.43,-0.51 -0.9,-0.99 -1.41,-1.41l-1.42,1.42C16.07,4.74 14.12,4 12,4c-4.97,0 -9,4.03 -9,9c0,4.97 4.02,9 9,9s9,-4.03 9,-9C21,10.88 20.26,8.93 19.03,7.39zM13,14h-2V8h2V14z"/> 6 - </vector>
-5
wear/src/main/res/drawable/ic_android_black_24dp.xml
··· 1 - <vector android:height="24dp" android:tint="#000000" 2 - android:viewportHeight="24" android:viewportWidth="24" 3 - android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android"> 4 - <path android:fillColor="#FF000000" android:pathData="M17.6,11.48 L19.44,8.3a0.63,0.63 0,0 0,-1.09 -0.63l-1.88,3.24a11.43,11.43 0,0 0,-8.94 0L5.65,7.67a0.63,0.63 0,0 0,-1.09 0.63L6.4,11.48A10.81,10.81 0,0 0,1 20L23,20A10.81,10.81 0,0 0,17.6 11.48ZM7,17.25A1.25,1.25 0,1 1,8.25 16,1.25 1.25,0 0,1 7,17.25ZM17,17.25A1.25,1.25 0,1 1,18.25 16,1.25 1.25,0 0,1 17,17.25Z"/> 5 - </vector>
+7
wear/src/main/res/values-es/strings.xml
··· 1 + <?xml version="1.0" encoding="utf-8"?> 2 + <resources> 3 + <string name="submit_button_default_content_description">Enviar</string> 4 + <string name="refresh_button_default_content_description">Actualizar</string> 5 + <string name="no_tags">Sin etiquetas</string> 6 + <string name="no_activities">Sin actividates</string> 7 + </resources>
-3
wear/src/main/res/values-round/strings.xml
··· 1 - <resources> 2 - <string name="hello_world">From the Round world,\nHello, %1$s!</string> 3 - </resources>
+5 -2
wear/src/main/res/values/strings.xml
··· 1 1 <resources> 2 - <string name="app_name">Simple Time Tracker</string> 2 + <string name="app_name" translatable="false">Simple Time Tracker</string> 3 3 <!-- 4 4 This string is used for square devices and overridden by hello_world in 5 5 values-round/strings.xml for round devices. 6 6 --> 7 - <string name="hello_world">From the Square world,\nHello, %1$s!</string> 7 + <string name="submit_button_default_content_description">Submit</string> 8 + <string name="refresh_button_default_content_description">Refresh</string> 9 + <string name="no_tags">No tags</string> 10 + <string name="no_activities">No activities</string> 8 11 </resources>