Skip to content

Commit

Permalink
refactor(schedule): use flow to fetch schedule details.
Browse files Browse the repository at this point in the history
  • Loading branch information
GerardPaligot committed Dec 22, 2023
1 parent 7e710f0 commit f3ba7b6
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 33 deletions.
Binary file not shown.
11 changes: 8 additions & 3 deletions iosApp/iosApp/screens/schedule/ScheduleDetailVM.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,17 @@ struct ScheduleDetailVM: View {
switch uiState {
case .success(let talkUi):
ScheduleDetail(talkUi: talkUi)
case .failure:
Text("textError")
case .loading:
Text("textLoading")
.onAppear {
viewModel.fetchScheduleDetails()
}
}
}
.onAppear {
viewModel.fetchScheduleDetails()
}
.onDisappear {
viewModel.stop()
}
}
}
20 changes: 18 additions & 2 deletions iosApp/iosApp/screens/schedule/ScheduleItemViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@

import Foundation
import shared
import KMPNativeCoroutinesAsync

enum ScheduleUiState {
case loading
case success(TalkUi)
case failure
}

@MainActor
Expand All @@ -25,9 +27,23 @@ class ScheduleItemViewModel: ObservableObject {
}

@Published var uiState: ScheduleUiState = .loading

private var scheduleTask: Task<(), Never>?

func fetchScheduleDetails() {
let talk = repository.scheduleItem(scheduleId: scheduleId)
self.uiState = .success(talk)
scheduleTask = Task {
do {
let stream = asyncStream(for: repository.scheduleItemNative(scheduleId: scheduleId))
for try await schedule in stream {
self.uiState = .success(schedule)
}
} catch {
self.uiState = .failure
}
}
}

func stop() {
scheduleTask?.cancel()
}
}
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
package org.gdglille.devfest.database

import app.cash.sqldelight.coroutines.asFlow
import app.cash.sqldelight.coroutines.mapToList
import app.cash.sqldelight.coroutines.mapToOne
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.IO
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.combine
import org.gdglille.devfest.Platform
import org.gdglille.devfest.database.mappers.convertTalkUi
import org.gdglille.devfest.db.Conferences4HallDatabase
import org.gdglille.devfest.models.ui.TalkUi

class TalkDao(private val db: Conferences4HallDatabase, private val platform: Platform) {
fun fetchTalk(eventId: String, talkId: String): TalkUi = db.transactionWithResult {
val talk = db.sessionQueries
.selectSessionByTalkId(eventId, talkId)
.executeAsOne()
talk.convertTalkUi(
platform::getString,
db.sessionQueries
fun fetchTalk(eventId: String, talkId: String): Flow<TalkUi> = db.transactionWithResult {
combine(
flow = db.sessionQueries
.selectSpeakersByTalkId(event_id = eventId, talk_id = talkId)
.executeAsList(),
db.eventQueries
.asFlow()
.mapToList(Dispatchers.IO),
flow2 = db.eventQueries
.selectOpenfeedbackProjectId(eventId)
.executeAsOne()
.asFlow()
.mapToOne(Dispatchers.IO),
flow3 = db.sessionQueries
.selectSessionByTalkId(eventId, talkId)
.asFlow()
.mapToOne(Dispatchers.IO),
transform = { speakers, openfeedback, talk ->
talk.convertTalkUi(platform::getString, speakers, openfeedback)
}
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ interface AgendaRepository {
fun coc(): Flow<CoCUi>
fun agenda(): Flow<ImmutableMap<String, AgendaUi>>
fun filters(): Flow<FiltersUi>
fun scheduleItem(scheduleId: String): Flow<TalkUi>
fun hasFilterApplied(): Flow<Boolean>
fun applyFavoriteFilter(selected: Boolean)
fun applyCategoryFilter(categoryUi: CategoryUi, selected: Boolean)
fun applyFormatFilter(formatUi: FormatUi, selected: Boolean)
fun speaker(speakerId: String): Flow<SpeakerUi>
fun markAsRead(sessionId: String, isFavorite: Boolean)
fun scheduleItem(scheduleId: String): TalkUi

@FlowPreview
@ExperimentalSettingsApi
Expand Down Expand Up @@ -181,7 +181,7 @@ class AgendaRepositoryImpl(
isFavorite = isFavorite
)

override fun scheduleItem(scheduleId: String): TalkUi = talkDao.fetchTalk(
override fun scheduleItem(scheduleId: String): Flow<TalkUi> = talkDao.fetchTalk(
eventId = eventDao.fetchEventId(),
talkId = scheduleId
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import org.gdglille.devfest.models.ui.TalkUi
import org.gdglille.devfest.repositories.AgendaRepository

Expand All @@ -17,20 +19,18 @@ sealed class ScheduleUiState {
}

class ScheduleDetailViewModel(
private val scheduleId: String,
private val repository: AgendaRepository,
scheduleId: String,
repository: AgendaRepository,
) : ViewModel() {
private val _uiState = MutableStateFlow<ScheduleUiState>(ScheduleUiState.Loading)
val uiState: StateFlow<ScheduleUiState> = _uiState

init {
viewModelScope.launch {
try {
_uiState.value = ScheduleUiState.Success(repository.scheduleItem(scheduleId))
} catch (error: Throwable) {
Firebase.crashlytics.recordException(error)
_uiState.value = ScheduleUiState.Failure(error)
}
val uiState: StateFlow<ScheduleUiState> = repository.scheduleItem(scheduleId)
.map { ScheduleUiState.Success(it) }
.catch {
Firebase.crashlytics.recordException(it)
ScheduleUiState.Failure(it)
}
}
.stateIn(
scope = viewModelScope,
initialValue = ScheduleUiState.Loading,
started = SharingStarted.WhileSubscribed()
)
}

0 comments on commit f3ba7b6

Please sign in to comment.