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.

feat: Share more Settings and Tag fields over RPC

Adds the extra fields to the DTO that will be needed to
implement full support on the watch for the behavioral settings
defined on the phone.

Joseph Hale (Feb 26, 2024, 10:27 PM -0700) 801355ff 83cfd398

+50 -27
+18 -6
app/src/main/java/com/example/util/simpletimetracker/wear/DomainAPI.kt
··· 11 11 import com.example.util.simpletimetracker.domain.interactor.RemoveRunningRecordMediator 12 12 import com.example.util.simpletimetracker.domain.interactor.RunningRecordInteractor 13 13 import com.example.util.simpletimetracker.domain.mapper.AppColorMapper 14 + import com.example.util.simpletimetracker.domain.model.RecordTag 14 15 import com.example.util.simpletimetracker.domain.model.RunningRecord 15 16 import com.example.util.simpletimetracker.wearrpc.Activity 16 17 import com.example.util.simpletimetracker.wearrpc.CurrentActivity ··· 42 43 record.id, 43 44 record.timeStarted, 44 45 record.tagIds.map { tagId -> 45 - val tag = recordTagInteractor.get(tagId) 46 - Tag(id = tag?.id ?: -1, name = tag?.name ?: "") 46 + asTag(recordTagInteractor.get(tagId)) 47 47 }.filter { it.id > 0 }.toTypedArray(), 48 48 ) 49 49 }.toTypedArray() ··· 68 68 } 69 69 70 70 override suspend fun queryTagsForActivity(activityId: Long): Array<Tag> { 71 - return recordTagInteractor.getByTypeOrUntyped(activityId).filter { !it.archived }.map { 72 - Tag(id = it.id, name = it.name) 73 - }.toTypedArray() 71 + return recordTagInteractor.getByTypeOrUntyped(activityId).filter { !it.archived } 72 + .map { asTag(it) }.toTypedArray() 73 + } 74 + 75 + private fun asTag(recordTag: RecordTag?): Tag { 76 + return Tag( 77 + id = recordTag?.id ?: -1, 78 + name = recordTag?.name ?: "", 79 + isGeneral = recordTag?.typeId == 0L, 80 + ) 74 81 } 75 82 76 83 override suspend fun querySettings(): Settings { 77 - return Settings(prefsInteractor.getAllowMultitasking()) 84 + return Settings( 85 + allowMultitasking = prefsInteractor.getAllowMultitasking(), 86 + showRecordTagSelection = prefsInteractor.getShowRecordTagSelection(), 87 + recordTagSelectionCloseAfterOne = prefsInteractor.getRecordTagSelectionCloseAfterOne(), 88 + recordTagSelectionEvenForGeneralTags = prefsInteractor.getRecordTagSelectionEvenForGeneralTags(), 89 + ) 78 90 } 79 91 80 92 }
+2 -2
wear/src/main/java/com/example/util/simpletimetracker/presentation/components/ActivityChip.kt
··· 159 159 ActivityChip( 160 160 Activity(456, "Sleeping", "🛏️", "#ABCDEF"), startedAt = 1706751601000L, 161 161 tags = arrayOf( 162 - Tag(id = 2, name = "Work"), 163 - Tag(id = 4, name = "Hotel"), 162 + Tag(id = 2, name = "Work", isGeneral = false), 163 + Tag(id = 4, name = "Hotel", isGeneral = false), 164 164 ), 165 165 ) 166 166 }
+1 -1
wear/src/main/java/com/example/util/simpletimetracker/presentation/mediators/CurrentActivitiesMediator.kt
··· 18 18 startedAt = System.currentTimeMillis(), 19 19 tags = tags 20 20 ) 21 - if (settings().multitasking) { 21 + if (settings().allowMultitasking) { 22 22 this.rpc.setCurrentActivities(currents.plus(newCurrent)) 23 23 } else { 24 24 this.rpc.setCurrentActivities(arrayOf(newCurrent))
+7 -4
wearrpc/src/main/java/com/example/util/simpletimetracker/wearrpc/DTO.kt
··· 11 11 * Object definitions for records sent between Wear/Mobile 12 12 */ 13 13 14 - import java.util.Date 15 - 16 14 data class Activity(val id: Long, val name: String, val icon: String, val color: String) 17 15 18 16 data class CurrentActivity(val id: Long, val startedAt: Long, val tags: Array<Tag>) { ··· 37 35 } 38 36 } 39 37 40 - data class Tag(val id: Long, val name: String /*, val color: String */) 38 + data class Tag(val id: Long, val name: String, val isGeneral: Boolean /*, val color: String */) 41 39 42 - data class Settings(val multitasking: Boolean) 40 + data class Settings( 41 + val allowMultitasking: Boolean, 42 + val showRecordTagSelection: Boolean, 43 + val recordTagSelectionCloseAfterOne: Boolean, 44 + val recordTagSelectionEvenForGeneralTags: Boolean, 45 + )
+22 -14
wearrpc/src/test/java/com/example/util/simpletimetracker/wearrpc/WearRPCTest.kt
··· 93 93 val response = client.queryCurrentActivities() 94 94 assertArrayEquals(activities, response) 95 95 } 96 + 96 97 @Test 97 98 fun returns_one_activity_when_one_exists() = runTest { 98 99 val jan_31_2024_afternoon = 1706704801L ··· 100 101 CurrentActivity( 101 102 42, 102 103 jan_31_2024_afternoon, 103 - arrayOf(Tag(1, "Friends"), Tag(2, "Family")), 104 + arrayOf(Tag(1, "Friends", isGeneral = false), Tag(2, "Family", isGeneral = false)), 104 105 ), 105 106 ) 106 107 api.mock_queryCurrentActivities(activities) ··· 116 117 CurrentActivity( 117 118 42, 118 119 jan_31_2024_afternoon, 119 - arrayOf(Tag(1, "Friends"), Tag(2, "Family")), 120 + arrayOf(Tag(1, "Friends", isGeneral = false), Tag(2, "Family", isGeneral = false)), 120 121 ), 121 122 CurrentActivity( 122 123 42, 123 124 jan_31_2024_evening, 124 - arrayOf(Tag(5, "Shopping")), 125 + arrayOf(Tag(5, "Shopping", isGeneral = false)), 125 126 ), 126 127 ) 127 128 api.mock_queryCurrentActivities(activities) ··· 130 131 } 131 132 } 132 133 133 - class QueryTagsForActivityTest: WearRPCServerTestBase() { 134 + class QueryTagsForActivityTest : WearRPCServerTestBase() { 134 135 @Test 135 136 fun returns_no_tags_if_activity_has_none() = runTest { 136 137 api.mock_queryTagsForActivity(mapOf(13L to arrayOf())) ··· 146 147 147 148 @Test 148 149 fun returns_one_tag_associated_with_activity() = runTest { 149 - val tags = arrayOf(Tag(5, "Shopping")) 150 + val tags = arrayOf(Tag(5, "Shopping", isGeneral = false)) 150 151 api.mock_queryTagsForActivity(mapOf(13L to tags)) 151 152 val response = client.queryTagsForActivity(13) 152 153 assertArrayEquals(tags, response) ··· 154 155 155 156 @Test 156 157 fun returns_all_tags_associated_with_activity() = runTest { 157 - val tags = arrayOf(Tag(5, "Shopping"), Tag(14, "Work")) 158 + val tags = arrayOf(Tag(5, "Shopping", isGeneral = false), Tag(14, "Work", isGeneral = false)) 158 159 api.mock_queryTagsForActivity(mapOf(13L to tags)) 159 160 val response = client.queryTagsForActivity(13L) 160 161 assertArrayEquals(tags, response) ··· 162 163 163 164 @Test 164 165 fun returns_only_tags_associated_with_requested_activity() = runTest { 165 - val tags = arrayOf(Tag(5, "Shopping"), Tag(14, "Work")) 166 - val otherTags = arrayOf(Tag(7, "Chores"), Tag(13, "Sleep")) 166 + val tags = arrayOf(Tag(5, "Shopping", isGeneral = false), Tag(14, "Work", isGeneral = false)) 167 + val otherTags = arrayOf(Tag(7, "Chores", isGeneral = false), Tag(13, "Sleep", isGeneral = false)) 167 168 api.mock_queryTagsForActivity(mapOf(10L to tags, 17L to otherTags)) 168 169 val response = client.queryTagsForActivity(10L) 169 170 assertArrayEquals(tags, response) ··· 172 173 } 173 174 } 174 175 175 - class QuerySettingsTest: WearRPCServerTestBase() { 176 + class QuerySettingsTest : WearRPCServerTestBase() { 177 + private val sampleSettings = Settings( 178 + allowMultitasking = true, 179 + showRecordTagSelection = false, 180 + recordTagSelectionCloseAfterOne = false, 181 + recordTagSelectionEvenForGeneralTags = false, 182 + ) 176 183 @Test 177 184 fun returns_settings_with_multitasking_enabled() = runTest { 178 - api.mock_querySettings(Settings(multitasking = true)) 185 + api.mock_querySettings(sampleSettings) 179 186 val response = client.querySettings() 180 - assertTrue(response.multitasking) 187 + assertTrue(response.allowMultitasking) 181 188 } 182 189 183 190 @Test 184 191 fun returns_settings_with_multitasking_disabled() = runTest { 185 - api.mock_querySettings(Settings(multitasking = false)) 192 + api.mock_querySettings(sampleSettings.copy(allowMultitasking = false)) 186 193 val response = client.querySettings() 187 - assertFalse(response.multitasking) 194 + assertFalse(response.allowMultitasking) 188 195 } 189 196 } 190 197 ··· 212 219 this.currentActivities = activities 213 220 } 214 221 215 - override suspend fun setCurrentActivities(activities: Array<CurrentActivity>): Unit { 222 + override suspend fun setCurrentActivities(activities: Array<CurrentActivity>) { 216 223 TODO("Not yet implemented") 217 224 } 218 225 219 226 override suspend fun queryTagsForActivity(activityId: Long): Array<Tag> { 220 227 return this.tags.getOrDefault(activityId, arrayOf()) 221 228 } 229 + 222 230 fun mock_queryTagsForActivity(tags: Map<Long, Array<Tag>>) { 223 231 this.tags = tags 224 232 }