Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.update

class FakeNotesRepository : NotesRepository {
Expand All @@ -42,8 +41,8 @@ class FakeNotesRepository : NotesRepository {
.map { it.values.toList().sortedByDescending { note -> note.id } }
}

override fun getNoteStream(id: Long): Flow<Note> {
return notesFlow.asStateFlow().mapNotNull { it[id] }
override fun getNoteStream(id: Long): Flow<Note?> {
return notesFlow.asStateFlow().map { it[id] }
}

override suspend fun addNote(note: Note): Long {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class NoteDaoTest {
val updatedNote = Note(id = 1, title = "Updated Title")
noteDao.updateNote(updatedNote)
val retrievedNote = noteDao.getNote(1).first()
assertEquals(retrievedNote.title, "Updated Title")
assertEquals(retrievedNote?.title, "Updated Title")
}

@Test
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/example/cahier/data/NoteDao.kt
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ interface NoteDao {
fun getAllNotes(): Flow<List<Note>>

@Query("SELECT * FROM notes WHERE id = :id")
fun getNote(id: Long): Flow<Note>
fun getNote(id: Long): Flow<Note?>

@Insert(onConflict = OnConflictStrategy.IGNORE)
suspend fun addNote(note: Note): Long
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ interface NotesRepository {
fun getAllNotesStream(): Flow<List<Note>>

/**
* Retrieve an note from the given data source that matches with the [id].
* Retrieve a note from the given data source that matches with the [id].
*/
fun getNoteStream(id: Long): Flow<Note>
fun getNoteStream(id: Long): Flow<Note?>

/**
* Insert note in the data source
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class OfflineNotesRepository(

override fun getAllNotesStream(): Flow<List<Note>> = notesDao.getAllNotes()

override fun getNoteStream(id: Long): Flow<Note> = notesDao.getNote(id)
override fun getNoteStream(id: Long): Flow<Note?> = notesDao.getNote(id)

override suspend fun addNote(note: Note): Long {
return notesDao.addNote(note)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import com.example.cahier.data.NotesRepository
import com.example.cahier.ui.CahierUiState
import dagger.hilt.android.lifecycle.HiltViewModel
import javax.inject.Inject
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
Expand All @@ -51,6 +53,8 @@ class HomeScreenViewModel @Inject constructor(
private val _newWindowEvent = Channel<Pair<NoteType, Long>>()
val newWindowEvent = _newWindowEvent.receiveAsFlow()

private var selectNoteJob: Job? = null

/**
* Holds ui state for the list of notes on the home pane.
* The list of items are retrieved from [NotesRepository] and mapped to
Expand All @@ -65,7 +69,8 @@ class HomeScreenViewModel @Inject constructor(
)

fun selectNote(noteId: Long) {
viewModelScope.launch {
selectNoteJob?.cancel()
selectNoteJob = viewModelScope.launch {
_uiState.value = _uiState.value.copy(isLoading = true)
try {
noteRepository.getNoteStream(noteId)
Expand All @@ -79,6 +84,7 @@ class HomeScreenViewModel @Inject constructor(
_uiState.value = CahierUiState(note = note, strokes = strokes)
}
} catch (e: Exception) {
if (e is CancellationException) throw e
_uiState.value = _uiState.value.copy(
error = "Error retrieving note: ${e.message}",
isLoading = false
Expand Down Expand Up @@ -129,6 +135,9 @@ class HomeScreenViewModel @Inject constructor(
try {
viewModelScope.launch {
noteRepository.deleteNote(noteToDelete)
if (_uiState.value.note.id == noteToDelete.id) {
clearSelection()
}
}
} catch (e: Exception) {
Log.e(TAG, "Error deleting note: ${e.message}")
Expand All @@ -143,7 +152,9 @@ class HomeScreenViewModel @Inject constructor(
noteRepository.toggleFavorite(noteId)
if (_uiState.value.note.id == noteId) {
val updatedNote = noteRepository.getNoteStream(noteId).first()
_uiState.update { it.copy(note = updatedNote) }
updatedNote?.let { note ->
_uiState.update { it.copy(note = note) }
}
}
} catch (e: Exception) {
Log.e(TAG, "Error toggling favorite: ${e.message}")
Expand All @@ -152,6 +163,7 @@ class HomeScreenViewModel @Inject constructor(
}

fun clearSelection() {
selectNoteJob?.cancel()
_uiState.update { CahierUiState() }
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class FakeNotesRepository : NotesRepository {
.map { it.values.toList().sortedByDescending { note -> note.id } }
}

override fun getNoteStream(id: Long): Flow<Note> {
return notesFlow.asStateFlow().mapNotNull { it[id] }
override fun getNoteStream(id: Long): Flow<Note?> {
return notesFlow.asStateFlow().map { it[id] }
}

override suspend fun addNote(note: Note): Long {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ class CanvasScreenViewModelTest {
viewModel.updateNoteTitle(newTitle)

notesRepository.getNoteStream(noteId).test {
assertEquals(newTitle, awaitItem().title)
assertEquals(newTitle, awaitItem()!!.title)
cancelAndIgnoreRemainingEvents()
}
}
Expand All @@ -92,7 +92,7 @@ class CanvasScreenViewModelTest {
viewModel.updateNoteText(newText)

notesRepository.getNoteStream(noteId).test {
assertEquals(newText, awaitItem().text)
assertEquals(newText, awaitItem()!!.text)
cancelAndIgnoreRemainingEvents()
}
}
Expand All @@ -102,7 +102,7 @@ class CanvasScreenViewModelTest {
viewModel.toggleFavorite()

notesRepository.getNoteStream(noteId).test {
assertTrue(awaitItem().isFavorite)
assertTrue(awaitItem()!!.isFavorite)
cancelAndIgnoreRemainingEvents()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,10 @@ class HomeScreenViewModelTest {
fun toggleFavorite_toggles_favorite_status_in_repository() = runTest {
val noteId =
runBlocking { notesRepository.addNote(Note(title = "My Note", isFavorite = false)) }

viewModel.toggleFavorite(noteId)

notesRepository.getNoteStream(noteId).test {
assertTrue(awaitItem().isFavorite)
assertTrue(awaitItem()!!.isFavorite)
cancelAndIgnoreRemainingEvents()
}
}
Expand Down
Loading