|
|
|
@ -3,60 +3,70 @@ package org.tasks.presentation.screens
|
|
|
|
import android.app.Application
|
|
|
|
import android.app.Application
|
|
|
|
import androidx.lifecycle.AndroidViewModel
|
|
|
|
import androidx.lifecycle.AndroidViewModel
|
|
|
|
import androidx.lifecycle.viewModelScope
|
|
|
|
import androidx.lifecycle.viewModelScope
|
|
|
|
|
|
|
|
import androidx.paging.Pager
|
|
|
|
|
|
|
|
import androidx.paging.PagingConfig
|
|
|
|
|
|
|
|
import androidx.paging.PagingData
|
|
|
|
import com.google.android.horologist.annotations.ExperimentalHorologistApi
|
|
|
|
import com.google.android.horologist.annotations.ExperimentalHorologistApi
|
|
|
|
import com.google.android.horologist.data.ProtoDataStoreHelper.protoFlow
|
|
|
|
import com.google.android.horologist.data.ProtoDataStoreHelper.protoFlow
|
|
|
|
import com.google.android.horologist.data.TargetNodeId
|
|
|
|
import com.google.android.horologist.data.TargetNodeId
|
|
|
|
import com.google.android.horologist.data.WearDataLayerRegistry
|
|
|
|
import com.google.android.horologist.data.WearDataLayerRegistry
|
|
|
|
import com.google.android.horologist.datalayer.grpc.GrpcExtensions.grpcClient
|
|
|
|
import com.google.android.horologist.datalayer.grpc.GrpcExtensions.grpcClient
|
|
|
|
import kotlinx.coroutines.CoroutineScope
|
|
|
|
|
|
|
|
import kotlinx.coroutines.Dispatchers
|
|
|
|
|
|
|
|
import kotlinx.coroutines.flow.Flow
|
|
|
|
import kotlinx.coroutines.flow.Flow
|
|
|
|
import kotlinx.coroutines.flow.MutableStateFlow
|
|
|
|
|
|
|
|
import kotlinx.coroutines.flow.launchIn
|
|
|
|
import kotlinx.coroutines.flow.launchIn
|
|
|
|
import kotlinx.coroutines.flow.onEach
|
|
|
|
import kotlinx.coroutines.flow.onEach
|
|
|
|
import kotlinx.coroutines.flow.update
|
|
|
|
|
|
|
|
import kotlinx.coroutines.launch
|
|
|
|
import kotlinx.coroutines.launch
|
|
|
|
import org.tasks.GrpcProto
|
|
|
|
import org.tasks.GrpcProto
|
|
|
|
import org.tasks.GrpcProto.LastUpdate
|
|
|
|
import org.tasks.GrpcProto.LastUpdate
|
|
|
|
import org.tasks.GrpcProto.Tasks
|
|
|
|
import org.tasks.GrpcProto.UiItem
|
|
|
|
import org.tasks.WearServiceGrpcKt
|
|
|
|
import org.tasks.WearServiceGrpcKt
|
|
|
|
|
|
|
|
import org.tasks.presentation.MyPagingSource
|
|
|
|
import org.tasks.wear.LastUpdateSerializer
|
|
|
|
import org.tasks.wear.LastUpdateSerializer
|
|
|
|
|
|
|
|
|
|
|
|
data class TaskListScreenState(
|
|
|
|
|
|
|
|
val error: String? = null,
|
|
|
|
|
|
|
|
val tasks: Tasks = Tasks.getDefaultInstance(),
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@OptIn(ExperimentalHorologistApi::class)
|
|
|
|
@OptIn(ExperimentalHorologistApi::class)
|
|
|
|
class TaskListViewModel(
|
|
|
|
class TaskListViewModel(
|
|
|
|
application: Application
|
|
|
|
application: Application
|
|
|
|
) : AndroidViewModel(application) {
|
|
|
|
) : AndroidViewModel(application) {
|
|
|
|
val uiState: MutableStateFlow<TaskListScreenState> = MutableStateFlow(TaskListScreenState())
|
|
|
|
private var pagingSource: MyPagingSource<UiItem>? = null
|
|
|
|
private val scope = CoroutineScope(Dispatchers.IO)
|
|
|
|
val uiItems: Flow<PagingData<UiItem>> = Pager(
|
|
|
|
|
|
|
|
config = PagingConfig(pageSize = 20),
|
|
|
|
|
|
|
|
pagingSourceFactory = {
|
|
|
|
|
|
|
|
MyPagingSource { position, limit ->
|
|
|
|
|
|
|
|
wearService
|
|
|
|
|
|
|
|
.getTasks(
|
|
|
|
|
|
|
|
GrpcProto
|
|
|
|
|
|
|
|
.GetTasksRequest
|
|
|
|
|
|
|
|
.newBuilder()
|
|
|
|
|
|
|
|
.setPosition(position)
|
|
|
|
|
|
|
|
.setLimit(limit)
|
|
|
|
|
|
|
|
.build()
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
.itemsList
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.also { pagingSource = it }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
.flow
|
|
|
|
private val wearDataLayerRegistry = WearDataLayerRegistry.fromContext(
|
|
|
|
private val wearDataLayerRegistry = WearDataLayerRegistry.fromContext(
|
|
|
|
application = application,
|
|
|
|
application = application,
|
|
|
|
coroutineScope = scope,
|
|
|
|
coroutineScope = viewModelScope,
|
|
|
|
).apply {
|
|
|
|
).apply {
|
|
|
|
registerSerializer(LastUpdateSerializer)
|
|
|
|
registerSerializer(LastUpdateSerializer)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private val wearService : WearServiceGrpcKt.WearServiceCoroutineStub = wearDataLayerRegistry.grpcClient(
|
|
|
|
private val wearService : WearServiceGrpcKt.WearServiceCoroutineStub = wearDataLayerRegistry.grpcClient(
|
|
|
|
nodeId = TargetNodeId.PairedPhone,
|
|
|
|
nodeId = TargetNodeId.PairedPhone,
|
|
|
|
coroutineScope = scope,
|
|
|
|
coroutineScope = viewModelScope,
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
WearServiceGrpcKt.WearServiceCoroutineStub(it)
|
|
|
|
WearServiceGrpcKt.WearServiceCoroutineStub(it)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private val lastUpdate: Flow<LastUpdate> = wearDataLayerRegistry.protoFlow(TargetNodeId.PairedPhone)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
init {
|
|
|
|
init {
|
|
|
|
lastUpdate
|
|
|
|
wearDataLayerRegistry
|
|
|
|
.onEach {
|
|
|
|
.protoFlow<LastUpdate>(TargetNodeId.PairedPhone)
|
|
|
|
val tasks = wearService.getTasks(GrpcProto.GetTasksRequest.getDefaultInstance())
|
|
|
|
.onEach { pagingSource?.invalidate() }
|
|
|
|
uiState.update { it.copy(tasks = tasks) }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
.launchIn(viewModelScope)
|
|
|
|
.launchIn(viewModelScope)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun completeTask(it: Long) = viewModelScope.launch {
|
|
|
|
fun completeTask(it: Long) = viewModelScope.launch {
|
|
|
|
wearService.completeTask(GrpcProto.CompleteTaskRequest.newBuilder().setId(it).setCompleted(true).build())
|
|
|
|
wearService.completeTask(GrpcProto.CompleteTaskRequest.newBuilder().setId(it).setCompleted(true).build())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|