···11+/*
22+ * This Source Code Form is subject to the terms of the Mozilla Public
33+ * License, v. 2.0. If a copy of the MPL was not distributed with this
44+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
55+ */
66+package com.example.util.simpletimetracker.presentation
77+88+import android.app.Application
99+import dagger.hilt.android.HiltAndroidApp
1010+1111+@HiltAndroidApp
1212+class WearApp : Application()
···11+/*
22+ * This Source Code Form is subject to the terms of the Mozilla Public
33+ * License, v. 2.0. If a copy of the MPL was not distributed with this
44+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
55+ */
66+package com.example.util.simpletimetracker.feature_wear
77+88+import com.example.util.simpletimetracker.wear_api.WearCommunicationAPI
99+import dagger.Binds
1010+import dagger.Module
1111+import dagger.hilt.InstallIn
1212+import dagger.hilt.components.SingletonComponent
1313+1414+@Module
1515+@InstallIn(SingletonComponent::class)
1616+interface WearModule {
1717+1818+ @Binds
1919+ fun WearCommunicationInteractor.bindWearCommunicationInteractor(): WearCommunicationAPI
2020+}
···11-/*
22- * This Source Code Form is subject to the terms of the Mozilla Public
33- * License, v. 2.0. If a copy of the MPL was not distributed with this
44- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
55- */
66-package com.example.util.simpletimetracker.feature_wear
77-88-import com.example.util.simpletimetracker.wear_api.WearCommunicationAPI
99-import dagger.Binds
1010-import dagger.Module
1111-import dagger.hilt.InstallIn
1212-import dagger.hilt.components.SingletonComponent
1313-1414-@Module
1515-@InstallIn(SingletonComponent::class)
1616-interface WidgetModule {
1717-1818- @Binds
1919- fun WearCommunicationInteractor.bindWearCommunicationInteractor(): WearCommunicationAPI
2020-}
···11+/*
22+ * This Source Code Form is subject to the terms of the Mozilla Public
33+ * License, v. 2.0. If a copy of the MPL was not distributed with this
44+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
55+ */
66+package com.example.util.simpletimetracker.presentation.di
77+88+import com.example.util.simpletimetracker.presentation.data.ContextMessenger
99+import com.example.util.simpletimetracker.presentation.data.Messenger
1010+import dagger.Binds
1111+import dagger.Module
1212+import dagger.hilt.InstallIn
1313+import dagger.hilt.components.SingletonComponent
1414+1515+@Module
1616+@InstallIn(SingletonComponent::class)
1717+interface WearModule {
1818+1919+ @Binds
2020+ fun ContextMessenger.bindMessenger(): Messenger
2121+}
···11-/*
22- * This Source Code Form is subject to the terms of the Mozilla Public
33- * License, v. 2.0. If a copy of the MPL was not distributed with this
44- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
55- */
66-package com.example.util.simpletimetracker.presentation.remember
77-88-import androidx.compose.runtime.Composable
99-import androidx.compose.runtime.LaunchedEffect
1010-import androidx.compose.runtime.getValue
1111-import androidx.compose.runtime.mutableIntStateOf
1212-import androidx.compose.runtime.mutableStateOf
1313-import androidx.compose.runtime.remember
1414-import androidx.compose.runtime.setValue
1515-import com.example.util.simpletimetracker.wear_api.WearActivity
1616-import kotlinx.coroutines.Dispatchers
1717-import kotlinx.coroutines.async
1818-1919-/**
2020- * Handles asynchronous retrieval of the available activities in Simple Time Tracker on the
2121- * connected phone.
2222- *
2323- * Usage:
2424- * ```
2525- * val (activities, refresh) = rememberActivities()
2626- * ```
2727- *
2828- * Initially, `activities` will be an empty array. Once the actual activities are received
2929- * from the phone, `activities` will *automatically* update to that array and the encapsulating
3030- * Composable will *automatically* re-render.
3131- *
3232- * `refresh` is a function you can call to forcibly re-request the array of available activities
3333- * from the phone.
3434- */
3535-@Composable
3636-fun rememberActivities(): Pair<List<WearActivity>, () -> Unit> {
3737- val rpc = rememberRPCClient()
3838- var activities: List<WearActivity> by remember { mutableStateOf(emptyList()) }
3939- var activitiesQueryCount by remember { mutableIntStateOf(0) }
4040- LaunchedEffect(activitiesQueryCount) {
4141- async(Dispatchers.Default) {
4242- activities = rpc.queryActivities()
4343- }
4444- }
4545- return Pair(activities) { activitiesQueryCount++ }
4646-}
···11-/*
22- * This Source Code Form is subject to the terms of the Mozilla Public
33- * License, v. 2.0. If a copy of the MPL was not distributed with this
44- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
55- */
66-package com.example.util.simpletimetracker.presentation.remember
77-88-import androidx.compose.runtime.Composable
99-import androidx.compose.runtime.LaunchedEffect
1010-import androidx.compose.runtime.getValue
1111-import androidx.compose.runtime.mutableIntStateOf
1212-import androidx.compose.runtime.mutableStateOf
1313-import androidx.compose.runtime.remember
1414-import androidx.compose.runtime.setValue
1515-import com.example.util.simpletimetracker.wear_api.WearCurrentActivity
1616-import kotlinx.coroutines.Dispatchers
1717-import kotlinx.coroutines.async
1818-1919-/**
2020- * Handles asynchronous retrieval of the currently running activities in Simple Time Tracker on the
2121- * connected phone.
2222- *
2323- * Usage:
2424- * ```
2525- * val (currents, setCurrents, refresh) = rememberCurrentActivities()
2626- * ```
2727- *
2828- * Initially, `currents` will be an empty array. Once the actual current activities are received
2929- * from the phone, `currents` will *automatically* update to that array and the encapsulating
3030- * Composable will *automatically* re-render.
3131- *
3232- * `setCurrents` is a function you can call to set the array of current activities on the phone.
3333- *
3434- * `refresh` is a function you can call to forcibly re-request the array of current activities
3535- * from the phone.
3636- */
3737-@Composable
3838-fun rememberCurrentActivities(): Pair<List<WearCurrentActivity>, () -> Unit> {
3939- val rpc = rememberRPCClient()
4040- var currentActivities: List<WearCurrentActivity> by remember { mutableStateOf(emptyList()) }
4141- var currentActivitiesQueryCount by remember { mutableIntStateOf(0) }
4242- val queryCurrentActivities = { currentActivitiesQueryCount++ }
4343- LaunchedEffect(currentActivitiesQueryCount) {
4444- async(Dispatchers.Default) {
4545- currentActivities = rpc.queryCurrentActivities()
4646- }
4747- }
4848- return currentActivities to { queryCurrentActivities() }
4949-}
···11-/*
22- * This Source Code Form is subject to the terms of the Mozilla Public
33- * License, v. 2.0. If a copy of the MPL was not distributed with this
44- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
55- */
66-package com.example.util.simpletimetracker.presentation.remember
77-88-import androidx.compose.runtime.Composable
99-import androidx.compose.runtime.LaunchedEffect
1010-import androidx.compose.runtime.getValue
1111-import androidx.compose.runtime.mutableIntStateOf
1212-import androidx.compose.runtime.mutableStateOf
1313-import androidx.compose.runtime.remember
1414-import androidx.compose.runtime.setValue
1515-import com.example.util.simpletimetracker.wear_api.WearSettings
1616-import kotlinx.coroutines.Dispatchers
1717-import kotlinx.coroutines.async
1818-1919-/**
2020- * Handles asynchronous retrieval of the settings for Simple Time Tracker on the connected phone.
2121- *
2222- * Usage:
2323- * ```
2424- * val (settings, refresh) = rememberSettings()
2525- * ```
2626- *
2727- * Initially, `settings` will be `null`. Once the actual settings are received
2828- * from the phone, `settings` will *automatically* update to the object and the encapsulating
2929- * Composable will *automatically* re-render.
3030- *
3131- * `refresh` is a function you can call to forcibly re-request the settings from the phone.
3232- */
3333-@Composable
3434-fun rememberSettings(): Pair<WearSettings?, () -> Unit> {
3535- var rpc = rememberRPCClient()
3636- var settings: WearSettings? by remember { mutableStateOf(null) }
3737- var settingsQueryCount by remember { mutableIntStateOf(0) }
3838- LaunchedEffect(settingsQueryCount) {
3939- async(Dispatchers.Default) {
4040- settings = rpc.querySettings()
4141- }
4242- }
4343- return Pair(settings) { settingsQueryCount++ }
4444-}
···11-/*
22- * This Source Code Form is subject to the terms of the Mozilla Public
33- * License, v. 2.0. If a copy of the MPL was not distributed with this
44- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
55- */
66-package com.example.util.simpletimetracker.presentation.remember
77-88-import androidx.compose.runtime.Composable
99-import androidx.compose.runtime.LaunchedEffect
1010-import androidx.compose.runtime.getValue
1111-import androidx.compose.runtime.mutableIntStateOf
1212-import androidx.compose.runtime.mutableStateOf
1313-import androidx.compose.runtime.remember
1414-import androidx.compose.runtime.setValue
1515-import com.example.util.simpletimetracker.wear_api.WearTag
1616-import kotlinx.coroutines.Dispatchers
1717-import kotlinx.coroutines.async
1818-1919-/**
2020- * Handles asynchronous retrieval of the available tags for a specific activity in
2121- * Simple Time Tracker on the connected phone.
2222- *
2323- * Usage:
2424- * ```
2525- * val activityId: Long = /* obtain the ID (e.g. as a parameter) */
2626- * val (tags, refresh) = rememberTags(activityId)
2727- * ```
2828- *
2929- * Initially, `tags` will be an empty array. Once the actual tags are received
3030- * from the phone, `tags` will *automatically* update to that array and the encapsulating
3131- * Composable will *automatically* re-render.
3232- *
3333- * `refresh` is a function you can call to forcibly re-request the array of available tags
3434- * from the phone.
3535- */
3636-@Composable
3737-fun rememberTags(activityId: Long): Pair<List<WearTag>, () -> Unit> {
3838- val rpc = rememberRPCClient()
3939- var tags: List<WearTag> by remember { mutableStateOf(emptyList()) }
4040- var tagsQueryCount by remember { mutableIntStateOf(0) }
4141- LaunchedEffect(tagsQueryCount) {
4242- async(Dispatchers.Default) {
4343- tags = rpc.queryTagsForActivity(activityId)
4444- }
4545- }
4646- return Pair(tags) { tagsQueryCount++ }
4747-}
···11+/*
22+ * This Source Code Form is subject to the terms of the Mozilla Public
33+ * License, v. 2.0. If a copy of the MPL was not distributed with this
44+ * file, You can obtain one at https://mozilla.org/MPL/2.0/.
55+ */
66+package com.example.util.simpletimetracker.presentation.utils
77+88+import android.annotation.SuppressLint
99+import androidx.compose.runtime.Composable
1010+import androidx.compose.runtime.LaunchedEffect
1111+import kotlinx.coroutines.flow.Flow
1212+import kotlinx.coroutines.flow.collect
1313+import kotlinx.coroutines.flow.onEach
1414+1515+@SuppressLint("ComposableNaming")
1616+@Composable
1717+fun <T> Flow<T>.collectEffects(
1818+ key: Any?,
1919+ action: (T) -> Unit,
2020+) {
2121+ LaunchedEffect(key) {
2222+ onEach { action(it) }.collect()
2323+ }
2424+}