Skip to content
Merged
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
3 changes: 3 additions & 0 deletions .idea/ChatHistory_schema_v2.xml

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions .idea/androidTestResultsUserPreferences.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions .idea/deploymentTargetSelector.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .pr_agent.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[config]
model="openrouter/qwen/qwen-2.5-coder-32b-instruct:free"
custom_model_max_tokens=9000
custom_model_max_tokens=4000
[github_action_config]
auto_review = true
auto_describe = true
Expand Down
1 change: 1 addition & 0 deletions core/domain/src/main/java/com/core/domain/model/Note.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ data class Note(
val done: Boolean,
val date: String,
val time: String,
val optionRevealed: Boolean = false,
)
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.lifecycle.SavedStateHandle
import app.cash.turbine.test
import com.core.domain.model.Note
import com.core.domain.model.TagWithNotes
import com.core.domain.usecase.UpdateNoteDeletedUseCase
import com.core.domain.usecase.UpdateNoteDoneUseCase
import com.feature.tags.domain.usecase.GetTagWithNotesUseCase
import com.feature.tags.domain.usecase.UpdateTagNameUseCase
Expand Down Expand Up @@ -33,6 +34,7 @@ class TagsViewModelTest {
private lateinit var getTagWithNotesUseCase: GetTagWithNotesUseCase
private lateinit var updateTagNameUseCase: UpdateTagNameUseCase
private lateinit var updateNoteDoneUseCase: UpdateNoteDoneUseCase
private lateinit var updateNoteDeletedUseCase: UpdateNoteDeletedUseCase
private lateinit var tagsViewModel: TagsViewModel
private val testDispatcher = StandardTestDispatcher()

Expand Down Expand Up @@ -70,6 +72,7 @@ class TagsViewModelTest {
getTagWithNotesUseCase = mockk()
updateTagNameUseCase = mockk()
updateNoteDoneUseCase = mockk()
updateNoteDeletedUseCase = mockk()
}

@Test
Expand All @@ -84,8 +87,9 @@ class TagsViewModelTest {
TagsViewModel(
savedStateHandle = savedStateHandle,
getTagWithNotesUseCase = getTagWithNotesUseCase,
updateTagNameUseCase = updateTagNameUseCase,
updateNoteDoneUseCase = updateNoteDoneUseCase,
updateTagNameUseCase = { updateTagNameUseCase },
updateNoteDoneUseCase = { updateNoteDoneUseCase },
updateNoteDeletedUseCase = { updateNoteDeletedUseCase },
)

// Assert
Expand All @@ -109,8 +113,9 @@ class TagsViewModelTest {
TagsViewModel(
savedStateHandle = savedStateHandle,
getTagWithNotesUseCase = getTagWithNotesUseCase,
updateTagNameUseCase = updateTagNameUseCase,
updateNoteDoneUseCase = updateNoteDoneUseCase,
updateTagNameUseCase = { updateTagNameUseCase },
updateNoteDoneUseCase = { updateNoteDoneUseCase },
updateNoteDeletedUseCase = { updateNoteDeletedUseCase },
)

// Assert
Expand All @@ -133,8 +138,9 @@ class TagsViewModelTest {
TagsViewModel(
savedStateHandle = savedStateHandle,
getTagWithNotesUseCase = getTagWithNotesUseCase,
updateTagNameUseCase = updateTagNameUseCase,
updateNoteDoneUseCase = updateNoteDoneUseCase,
updateTagNameUseCase = { updateTagNameUseCase },
updateNoteDoneUseCase = { updateNoteDoneUseCase },
updateNoteDeletedUseCase = { updateNoteDeletedUseCase },
)

// Act & Assert
Expand All @@ -161,8 +167,9 @@ class TagsViewModelTest {
TagsViewModel(
savedStateHandle = savedStateHandle,
getTagWithNotesUseCase = getTagWithNotesUseCase,
updateTagNameUseCase = updateTagNameUseCase,
updateNoteDoneUseCase = updateNoteDoneUseCase,
updateTagNameUseCase = { updateTagNameUseCase },
updateNoteDoneUseCase = { updateNoteDoneUseCase },
updateNoteDeletedUseCase = { updateNoteDeletedUseCase },
)

// Assert
Expand All @@ -185,7 +192,7 @@ class TagsViewModelTest {
}

@Test
fun markNoteAsDone_shouldMarkANoteAsDone() =
fun markNoteAsDone_shouldMarkNoteAsDone() =
runTest {
// Arrange
val note =
Expand All @@ -207,8 +214,9 @@ class TagsViewModelTest {
TagsViewModel(
savedStateHandle = savedStateHandle,
getTagWithNotesUseCase = getTagWithNotesUseCase,
updateTagNameUseCase = updateTagNameUseCase,
updateNoteDoneUseCase = updateNoteDoneUseCase,
updateTagNameUseCase = { updateTagNameUseCase },
updateNoteDoneUseCase = { updateNoteDoneUseCase },
updateNoteDeletedUseCase = { updateNoteDeletedUseCase },
)

// Assert
Expand All @@ -223,6 +231,46 @@ class TagsViewModelTest {
}
}

@Test
fun markNoteAsDeleted_shouldMarkNoteAsDeleted() =
runTest {
// Arrange
val note =
Note(
id = 1L,
content = "Test note 1",
timestamp = 123456789,
tagId = 1L,
done = false,
date = "2025-06-25",
time = "00:00:00",
)
every { getTagWithNotesUseCase(any()) } returns flowOf(tagWithNotes)
savedStateHandle = SavedStateHandle(mapOf("tagId" to 1L))
coEvery { updateNoteDeletedUseCase(any(), any()) } returns 1

// Act
tagsViewModel =
TagsViewModel(
savedStateHandle = savedStateHandle,
getTagWithNotesUseCase = getTagWithNotesUseCase,
updateTagNameUseCase = { updateTagNameUseCase },
updateNoteDoneUseCase = { updateNoteDoneUseCase },
updateNoteDeletedUseCase = { updateNoteDeletedUseCase },
)

// Assert
tagsViewModel.tagsUiState.test {
assertEquals(TagsUiState.Idle, awaitItem())
assertEquals(TagsUiState.Loading, awaitItem())
assertEquals(TagsUiState.TagLoaded(tagWithNotes), awaitItem())
tagsViewModel.markNoteAsDeleted(note = note)
advanceUntilIdle()
coVerify { updateNoteDeletedUseCase(note.id, true) }
cancelAndIgnoreRemainingEvents()
}
}

@After
fun tearDown() {
Dispatchers.resetMain()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ internal class InternalTagsFeatureApi
navHostController.navigate(AddEditNoteScreen(noteId = note.id))
},
onNoteDoneClick = tagsViewModel::markNoteAsDone,
onNoteDeleteClick = tagsViewModel::markNoteAsDeleted,
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ fun TagScreenUi(
onSaveTagNameClick: (Long, String) -> Unit,
onNoteClick: (Note) -> Unit,
onNoteDoneClick: (Note) -> Unit,
onNoteDeleteClick: (Note) -> Unit,
modifier: Modifier = Modifier,
) {
val state = tagsUiState
Expand Down Expand Up @@ -62,6 +63,7 @@ fun TagScreenUi(
onNoteClick = onNoteClick,
onEditTagClick = onEditTagClick,
onNoteDoneClick = onNoteDoneClick,
onNoteDeleteClick = onNoteDeleteClick,
)

if (state.tagsUiBottomSheet is TagsUiBottomSheet.RenameTagBottomSheet) {
Expand Down Expand Up @@ -93,6 +95,7 @@ private fun TagScreenPreview(
hideEditTagBottomSheet = {},
onNoteClick = {},
onNoteDoneClick = {},
onNoteDeleteClick = {},
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import androidx.lifecycle.viewModelScope
import androidx.navigation.toRoute
import com.core.common.navigation.TagScreen
import com.core.domain.model.Note
import com.core.domain.usecase.UpdateNoteDeletedUseCase
import com.core.domain.usecase.UpdateNoteDoneUseCase
import com.feature.tags.domain.usecase.GetTagWithNotesUseCase
import com.feature.tags.domain.usecase.UpdateTagNameUseCase
import dagger.Lazy
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
Expand All @@ -26,8 +28,9 @@ class TagsViewModel
constructor(
@Assisted private val savedStateHandle: SavedStateHandle,
private val getTagWithNotesUseCase: GetTagWithNotesUseCase,
private val updateTagNameUseCase: UpdateTagNameUseCase,
private val updateNoteDoneUseCase: UpdateNoteDoneUseCase,
private val updateTagNameUseCase: Lazy<UpdateTagNameUseCase>,
private val updateNoteDoneUseCase: Lazy<UpdateNoteDoneUseCase>,
private val updateNoteDeletedUseCase: Lazy<UpdateNoteDeletedUseCase>,
) : ViewModel() {
companion object {
private val TAG = TagsViewModel::class.simpleName
Expand Down Expand Up @@ -65,7 +68,7 @@ class TagsViewModel
@Suppress("TooGenericExceptionCaught")
viewModelScope.launch {
try {
updateTagNameUseCase(tagId = tagId, newName = newName)
updateTagNameUseCase.get()(tagId = tagId, newName = newName)
} catch (ex: Exception) {
Log.e(TAG, "Error updating tag name: ${ex.message}", ex)
}
Expand All @@ -84,7 +87,13 @@ class TagsViewModel

fun markNoteAsDone(note: Note) {
viewModelScope.launch {
updateNoteDoneUseCase(id = note.id, done = true)
updateNoteDoneUseCase.get()(id = note.id, done = true)
}
}

fun markNoteAsDeleted(note: Note) {
viewModelScope.launch {
updateNoteDeletedUseCase.get()(id = note.id, deleted = true)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
Expand All @@ -18,14 +19,19 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.core.common.theme.LightGray
import com.core.common.theme.Red
import com.core.common.theme.TaskerTheme
import com.core.common.ui.ActionIcon
import com.core.common.ui.SwipeableItemWithActions
import com.core.common.utils.toColorSafely
import com.core.domain.model.Note
import com.core.domain.model.TagWithNotes
Expand All @@ -39,6 +45,7 @@ fun TagContent(
onNoteClick: (Note) -> Unit,
onEditTagClick: (TagWithNotes) -> Unit,
onNoteDoneClick: (Note) -> Unit,
onNoteDeleteClick: (Note) -> Unit,
modifier: Modifier = Modifier,
) {
Box(modifier = modifier) {
Expand Down Expand Up @@ -96,12 +103,27 @@ fun TagContent(
.fillMaxSize(),
) {
items(tagsUiState.tag.notes, key = { it.id }) { note ->
TagNoteItem(
modifier = Modifier.fillMaxWidth(),
note = note,
onNoteClick = onNoteClick,
onNoteDoneClick = onNoteDoneClick,
)

SwipeableItemWithActions(
modifier = Modifier.animateItem(),
isRevealed = note.optionRevealed,
actions = {
ActionIcon(
onClick = { onNoteDeleteClick(note) },
backgroundColor = Red,
icon = ImageVector.vectorResource(id = com.core.common.R.drawable.ic_delete),
modifier = Modifier.fillMaxHeight(),
contentDescription = "Delete Icon",
)
},
) {
TagNoteItem(
modifier = Modifier.fillMaxWidth().background(tagsUiState.tag.color.toColorSafely()),
note = note,
onNoteClick = onNoteClick,
onNoteDoneClick = onNoteDoneClick,
)
}
HorizontalDivider(
modifier = Modifier.padding(start = 60.dp),
color = Color.White,
Expand All @@ -119,10 +141,15 @@ private fun TagContentPreview() {
TaskerTheme {
TagContent(
modifier = Modifier.fillMaxSize(),
tagsUiState = TagsUiState.TagLoaded(tag = tagWithNotes, tagsUiBottomSheet = TagsUiBottomSheet.None),
tagsUiState =
TagsUiState.TagLoaded(
tag = tagWithNotes,
tagsUiBottomSheet = TagsUiBottomSheet.None,
),
onEditTagClick = {},
onNoteClick = {},
onNoteDoneClick = {},
onNoteDeleteClick = {},
)
}
}
Loading