diff --git a/base/notepad/.gitignore b/base/notepad/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/base/notepad/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/base/notepad/build.gradle b/base/notepad/build.gradle new file mode 100644 index 0000000..6d1c39d --- /dev/null +++ b/base/notepad/build.gradle @@ -0,0 +1,49 @@ +plugins { + id 'com.android.library' + id 'kotlin-android' + id 'kotlin-kapt' + id 'kotlin-android-extensions' +} + +apply from: rootProject.file('dependencies.gradle') +apply from: rootProject.file('versions.gradle') + +android { + compileSdkVersion versions.compileSdk + + defaultConfig { + minSdkVersion versions.minSdk + targetSdkVersion versions.targetSdk + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + // Because of error More than one file was found with OS independent path 'META-INF/notepad_debug.kotlin_module'. + freeCompilerArgs = ["-module-name", project.path.substring(1).replace(':', '-')] + jvmTarget = '1.8' + } + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + test.java.srcDirs += 'src/test/kotlin' + androidTest.java.srcDirs += 'src/androidTest/kotlin' + } + androidExtensions { + experimental = true + } +} + +dependencies { + implementation project(":core") + + implementation( + deps.kotlin.stdlib, + deps.dagger.dagger, + deps.material.material, + deps.constraint.constraint + ) + kapt( + deps.dagger.processor + ) +} \ No newline at end of file diff --git a/base/notepad/proguard-rules.pro b/base/notepad/proguard-rules.pro new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/base/notepad/proguard-rules.pro @@ -0,0 +1 @@ + diff --git a/base/notepad/src/main/AndroidManifest.xml b/base/notepad/src/main/AndroidManifest.xml new file mode 100644 index 0000000..01b96fa --- /dev/null +++ b/base/notepad/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/data/mapper/note/NoteDataMapper.kt b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/data/mapper/note/NoteDataMapper.kt similarity index 90% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/data/mapper/note/NoteDataMapper.kt rename to base/notepad/src/main/kotlin/com/dvinc/base/notepad/data/mapper/note/NoteDataMapper.kt index 96096ec..b882d28 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/data/mapper/note/NoteDataMapper.kt +++ b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/data/mapper/note/NoteDataMapper.kt @@ -3,10 +3,10 @@ * All rights reserved. */ -package com.dvinc.notepad.data.mapper.note +package com.dvinc.base.notepad.data.mapper.note import com.dvinc.core.database.entity.note.NoteEntity -import com.dvinc.notepad.domain.model.note.Note +import com.dvinc.base.notepad.domain.model.Note import javax.inject.Inject class NoteDataMapper @Inject constructor() { diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/model/note/Note.kt b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/domain/model/Note.kt similarity index 83% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/domain/model/note/Note.kt rename to base/notepad/src/main/kotlin/com/dvinc/base/notepad/domain/model/Note.kt index b4e1ac3..96cb33e 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/model/note/Note.kt +++ b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/domain/model/Note.kt @@ -5,7 +5,7 @@ * All rights reserved. */ -package com.dvinc.notepad.domain.model.note +package com.dvinc.base.notepad.domain.model data class Note( val id: Long, diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NoteViewHolder.kt b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NoteViewHolder.kt similarity index 87% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NoteViewHolder.kt rename to base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NoteViewHolder.kt index ca5416a..6b942a3 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NoteViewHolder.kt +++ b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NoteViewHolder.kt @@ -3,11 +3,11 @@ * All rights reserved. */ -package com.dvinc.notepad.presentation.adapter.notepad +package com.dvinc.base.notepad.presentation.adapter.notepad import android.view.View import com.dvinc.core.ui.BaseViewHolder -import com.dvinc.notepad.presentation.model.NoteUi +import com.dvinc.base.notepad.presentation.model.NoteUi import kotlinx.android.synthetic.main.item_note.item_note_content as content import kotlinx.android.synthetic.main.item_note.item_note_name as name import kotlinx.android.synthetic.main.item_note.item_note_updating_time as updateTime diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NotepadAdapter.kt b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadAdapter.kt similarity index 90% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NotepadAdapter.kt rename to base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadAdapter.kt index 5ff2338..7677fc6 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NotepadAdapter.kt +++ b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadAdapter.kt @@ -3,14 +3,14 @@ * All rights reserved. */ -package com.dvinc.notepad.presentation.adapter.notepad +package com.dvinc.base.notepad.presentation.adapter.notepad import android.view.LayoutInflater import android.view.ViewGroup import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView -import com.dvinc.notepad.R -import com.dvinc.notepad.presentation.model.NoteUi +import com.dvinc.base.notepad.R +import com.dvinc.base.notepad.presentation.model.NoteUi class NotepadAdapter : RecyclerView.Adapter() { diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NotepadDiffUtilsCallback.kt b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadDiffUtilsCallback.kt similarity index 87% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NotepadDiffUtilsCallback.kt rename to base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadDiffUtilsCallback.kt index a9d8f93..c1f66b3 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NotepadDiffUtilsCallback.kt +++ b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadDiffUtilsCallback.kt @@ -3,10 +3,10 @@ * All rights reserved. */ -package com.dvinc.notepad.presentation.adapter.notepad +package com.dvinc.base.notepad.presentation.adapter.notepad import androidx.recyclerview.widget.DiffUtil -import com.dvinc.notepad.presentation.model.NoteUi +import com.dvinc.base.notepad.presentation.model.NoteUi class NotepadDiffUtilsCallback( private val oldNotesList: List, diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NotepadSwipeToDeleteCallback.kt b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadSwipeCallback.kt similarity index 77% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NotepadSwipeToDeleteCallback.kt rename to base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadSwipeCallback.kt index 8655c16..d6649d4 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/adapter/notepad/NotepadSwipeToDeleteCallback.kt +++ b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadSwipeCallback.kt @@ -3,19 +3,19 @@ * All rights reserved. */ -package com.dvinc.notepad.presentation.adapter.notepad +package com.dvinc.base.notepad.presentation.adapter.notepad import android.graphics.Canvas import android.graphics.Color import android.graphics.drawable.ColorDrawable import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView -import com.dvinc.notepad.R -import com.dvinc.notepad.presentation.model.NoteUi +import com.dvinc.base.notepad.R +import com.dvinc.base.notepad.presentation.model.NoteUi -class NotepadSwipeToDeleteCallback( +class NotepadSwipeCallback( private val notesAdapter: NotepadAdapter, - private val onItemSwipedListener: (note: NoteUi) -> Unit + private val onItemSwipedListener: (note: NoteUi, swipeDirection: NotepadSwipeDirection) -> Unit ) : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) { companion object { @@ -24,6 +24,8 @@ class NotepadSwipeToDeleteCallback( private val deletedItemBackground = ColorDrawable(Color.RED) + private val archiveItemBackground = ColorDrawable(Color.GREEN) + override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, @@ -35,7 +37,12 @@ class NotepadSwipeToDeleteCallback( override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { val position = viewHolder.adapterPosition val swipedNote = notesAdapter.getItem(position) - onItemSwipedListener.invoke(swipedNote) + // (!) Be careful about directions + if (direction == ItemTouchHelper.RIGHT) { + onItemSwipedListener.invoke(swipedNote, NotepadSwipeDirection.LEFT) + } else if (direction == ItemTouchHelper.LEFT) { + onItemSwipedListener.invoke(swipedNote, NotepadSwipeDirection.RIGHT) + } } override fun onChildDraw( @@ -56,7 +63,7 @@ class NotepadSwipeToDeleteCallback( when { dX > 0 -> { - deletedItemBackground.setBounds( + archiveItemBackground.setBounds( itemView.left, itemView.top, itemView.left + (dX.toInt() + BACKGROUND_CORNER_OFFSET), @@ -80,9 +87,11 @@ class NotepadSwipeToDeleteCallback( } else -> { deletedItemBackground.setBounds(0, 0, 0, 0) + archiveItemBackground.setBounds(0, 0, 0, 0) } } deletedItemBackground.draw(c) + archiveItemBackground.draw(c) deleteIcon.draw(c) } } diff --git a/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadSwipeDirection.kt b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadSwipeDirection.kt new file mode 100644 index 0000000..b33aa13 --- /dev/null +++ b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/adapter/notepad/NotepadSwipeDirection.kt @@ -0,0 +1,8 @@ +package com.dvinc.base.notepad.presentation.adapter.notepad + +enum class NotepadSwipeDirection { + + LEFT, + + RIGHT +} diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/mapper/NotePresentationMapper.kt b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/mapper/NotePresentationMapper.kt similarity index 92% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/mapper/NotePresentationMapper.kt rename to base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/mapper/NotePresentationMapper.kt index c7bd847..8a17810 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/mapper/NotePresentationMapper.kt +++ b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/mapper/NotePresentationMapper.kt @@ -3,10 +3,10 @@ * All rights reserved. */ -package com.dvinc.notepad.presentation.mapper +package com.dvinc.base.notepad.presentation.mapper -import com.dvinc.notepad.domain.model.note.Note -import com.dvinc.notepad.presentation.model.NoteUi +import com.dvinc.base.notepad.domain.model.Note +import com.dvinc.base.notepad.presentation.model.NoteUi import java.text.SimpleDateFormat import java.util.Calendar import java.util.Date diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/model/NoteUi.kt b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/model/NoteUi.kt similarity index 80% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/model/NoteUi.kt rename to base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/model/NoteUi.kt index b967cdc..d759f50 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/model/NoteUi.kt +++ b/base/notepad/src/main/kotlin/com/dvinc/base/notepad/presentation/model/NoteUi.kt @@ -3,7 +3,7 @@ * All rights reserved. */ -package com.dvinc.notepad.presentation.model +package com.dvinc.base.notepad.presentation.model data class NoteUi( val id: Long, diff --git a/features/notepad/src/main/res/drawable/bg_item_note.xml b/base/notepad/src/main/res/drawable/bg_item_note.xml similarity index 84% rename from features/notepad/src/main/res/drawable/bg_item_note.xml rename to base/notepad/src/main/res/drawable/bg_item_note.xml index b453ba7..0990a11 100644 --- a/features/notepad/src/main/res/drawable/bg_item_note.xml +++ b/base/notepad/src/main/res/drawable/bg_item_note.xml @@ -3,7 +3,7 @@ - + diff --git a/features/notepad/src/main/res/drawable/ic_delete.xml b/base/notepad/src/main/res/drawable/ic_delete.xml similarity index 100% rename from features/notepad/src/main/res/drawable/ic_delete.xml rename to base/notepad/src/main/res/drawable/ic_delete.xml diff --git a/features/notepad/src/main/res/layout/item_note.xml b/base/notepad/src/main/res/layout/item_note.xml similarity index 100% rename from features/notepad/src/main/res/layout/item_note.xml rename to base/notepad/src/main/res/layout/item_note.xml diff --git a/features/notepad/src/main/res/values-night/colors.xml b/base/notepad/src/main/res/values-night/colors.xml similarity index 89% rename from features/notepad/src/main/res/values-night/colors.xml rename to base/notepad/src/main/res/values-night/colors.xml index e5fe5d4..1e76b6b 100644 --- a/features/notepad/src/main/res/values-night/colors.xml +++ b/base/notepad/src/main/res/values-night/colors.xml @@ -1,6 +1,6 @@ - @color/darkItemBackgroundColor + @color/darkItemBackground @color/darkTextColor @color/darkTextColor - + \ No newline at end of file diff --git a/features/notepad/src/main/res/values/colors.xml b/base/notepad/src/main/res/values/colors.xml similarity index 80% rename from features/notepad/src/main/res/values/colors.xml rename to base/notepad/src/main/res/values/colors.xml index 6441a64..09fcb91 100644 --- a/features/notepad/src/main/res/values/colors.xml +++ b/base/notepad/src/main/res/values/colors.xml @@ -1,7 +1,5 @@ - #1F1A24 - @color/white @color/black @color/gray diff --git a/base/notepad/src/main/res/values/strings.xml b/base/notepad/src/main/res/values/strings.xml new file mode 100644 index 0000000..6dbbdca --- /dev/null +++ b/base/notepad/src/main/res/values/strings.xml @@ -0,0 +1,8 @@ + + + An error has occurred while loading from database + An error has occurred while deleting note + Cannot load note from database + Cannot add note + An error has occurred while archiving note + diff --git a/features/notepad/src/main/res/values/styles.xml b/base/notepad/src/main/res/values/styles.xml similarity index 99% rename from features/notepad/src/main/res/values/styles.xml rename to base/notepad/src/main/res/values/styles.xml index 0b8ee82..2dad6f7 100644 --- a/features/notepad/src/main/res/values/styles.xml +++ b/base/notepad/src/main/res/values/styles.xml @@ -1,6 +1,5 @@ - - diff --git a/core/src/main/kotlin/com/dvinc/core/database/NotepadDatabase.kt b/core/src/main/kotlin/com/dvinc/core/database/NotepadDatabase.kt index f13d27d..a29e2ea 100644 --- a/core/src/main/kotlin/com/dvinc/core/database/NotepadDatabase.kt +++ b/core/src/main/kotlin/com/dvinc/core/database/NotepadDatabase.kt @@ -7,11 +7,19 @@ package com.dvinc.core.database import androidx.room.Database import androidx.room.RoomDatabase +import com.dvinc.core.database.dao.archive.ArchiveDao import com.dvinc.core.database.dao.note.NoteDao import com.dvinc.core.database.entity.note.NoteEntity -@Database(entities = [NoteEntity::class], version = 1) +@Database( + entities = [ + NoteEntity::class + ], + version = 1 +) abstract class NotepadDatabase : RoomDatabase() { abstract fun notesDao(): NoteDao + + abstract fun archiveDao(): ArchiveDao } diff --git a/core/src/main/kotlin/com/dvinc/core/database/dao/archive/ArchiveDao.kt b/core/src/main/kotlin/com/dvinc/core/database/dao/archive/ArchiveDao.kt new file mode 100644 index 0000000..64bad2a --- /dev/null +++ b/core/src/main/kotlin/com/dvinc/core/database/dao/archive/ArchiveDao.kt @@ -0,0 +1,16 @@ +package com.dvinc.core.database.dao.archive + +import androidx.room.Dao +import androidx.room.Query +import com.dvinc.core.database.entity.note.NoteEntity +import kotlinx.coroutines.flow.Flow + +@Dao +interface ArchiveDao { + + @Query("UPDATE Notes SET is_archived = 1 WHERE id =:noteId") + suspend fun markNoteAsArchived(noteId: Long) + + @Query("SELECT * FROM Notes WHERE is_archived = 1 ORDER BY id DESC") + fun getArchive(): Flow> +} diff --git a/core/src/main/kotlin/com/dvinc/core/database/dao/note/NoteDao.kt b/core/src/main/kotlin/com/dvinc/core/database/dao/note/NoteDao.kt index b6f9a40..dc84ffd 100644 --- a/core/src/main/kotlin/com/dvinc/core/database/dao/note/NoteDao.kt +++ b/core/src/main/kotlin/com/dvinc/core/database/dao/note/NoteDao.kt @@ -18,7 +18,7 @@ interface NoteDao { @Insert(onConflict = OnConflictStrategy.REPLACE) suspend fun addNote(note: NoteEntity) - @Query("SELECT * FROM Notes ORDER BY id DESC") + @Query("SELECT * FROM Notes WHERE is_archived = 0 ORDER BY id DESC") fun getNotes(): Flow> @Query("DELETE FROM Notes WHERE id = :id") diff --git a/core/src/main/kotlin/com/dvinc/core/database/entity/note/NoteEntity.kt b/core/src/main/kotlin/com/dvinc/core/database/entity/note/NoteEntity.kt index d1f0a4c..5ca0088 100644 --- a/core/src/main/kotlin/com/dvinc/core/database/entity/note/NoteEntity.kt +++ b/core/src/main/kotlin/com/dvinc/core/database/entity/note/NoteEntity.kt @@ -22,5 +22,8 @@ data class NoteEntity( val content: String, @ColumnInfo(name = "update_time") - val updateTime: Long + val updateTime: Long, + + @ColumnInfo(name = "is_archived") + val isArchived: Boolean = false ) diff --git a/core/src/main/kotlin/com/dvinc/core/ui/BaseViewModel.kt b/core/src/main/kotlin/com/dvinc/core/ui/BaseViewModel.kt index d7352a4..99ad93f 100644 --- a/core/src/main/kotlin/com/dvinc/core/ui/BaseViewModel.kt +++ b/core/src/main/kotlin/com/dvinc/core/ui/BaseViewModel.kt @@ -1,13 +1,20 @@ package com.dvinc.core.ui import androidx.annotation.StringRes +import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.navigation.NavDirections -abstract class BaseViewModel : ViewModel() { +abstract class BaseViewModel(initialViewState: State? = null) : ViewModel() { + + val viewState = MutableLiveData() val viewCommands = CommandsLiveData() + init { + setInitialViewState(initialViewState) + } + protected fun showMessage(@StringRes messageResId: Int) { val showMessageCommand = ShowMessage(messageResId) viewCommands.onNext(showMessageCommand) @@ -26,4 +33,10 @@ abstract class BaseViewModel : ViewModel() { protected fun navigateBack() { viewCommands.onNext(NavigateUp) } + + private fun setInitialViewState(initialViewState: State?) { + initialViewState?.let { + viewState.value = it + } + } } diff --git a/core/src/main/kotlin/com/dvinc/core/ui/ViewState.kt b/core/src/main/kotlin/com/dvinc/core/ui/ViewState.kt new file mode 100644 index 0000000..eae24b5 --- /dev/null +++ b/core/src/main/kotlin/com/dvinc/core/ui/ViewState.kt @@ -0,0 +1,3 @@ +package com.dvinc.core.ui + +interface ViewState diff --git a/core/src/main/res/values/colors.xml b/core/src/main/res/values/colors.xml index 805fa90..8cc87c4 100644 --- a/core/src/main/res/values/colors.xml +++ b/core/src/main/res/values/colors.xml @@ -14,6 +14,7 @@ #121212 #888888 #AAAAAA + #1F1A24 @color/white @color/black diff --git a/features/archive/.gitignore b/features/archive/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/features/archive/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/features/archive/build.gradle b/features/archive/build.gradle new file mode 100644 index 0000000..b4f0bb3 --- /dev/null +++ b/features/archive/build.gradle @@ -0,0 +1,71 @@ +apply plugin: 'com.android.library' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-kapt' +apply plugin: "androidx.navigation.safeargs.kotlin" + +apply from: rootProject.file('dependencies.gradle') +apply from: rootProject.file('versions.gradle') + +android { + compileSdkVersion versions.compileSdk + + defaultConfig { + minSdkVersion versions.minSdk + targetSdkVersion versions.targetSdk + } + + buildTypes { + debug { + testCoverageEnabled true + } + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + test.java.srcDirs += 'src/test/kotlin' + androidTest.java.srcDirs += 'src/androidTest/kotlin' + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = "1.8" + } + + androidExtensions { + experimental = true + } +} + +dependencies { + implementation project(":core") + implementation project(":base:notepad") + + implementation( + deps.kotlin.stdlib, + deps.kotlin.coroutines, + + deps.dagger.dagger, + deps.dagger.assisted_inject, + + deps.constraint.constraint, + + deps.material.material, + deps.lifecycle.view_model, + deps.lifecycle.extensions, + + deps.room.room, + deps.room.coroutines, + + deps.tools.timber + ) + + kapt( + deps.dagger.processor, + deps.dagger.assisted_inject_processor, + ) +} diff --git a/features/archive/proguard-rules.pro b/features/archive/proguard-rules.pro new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/features/archive/proguard-rules.pro @@ -0,0 +1 @@ + diff --git a/features/archive/src/main/AndroidManifest.xml b/features/archive/src/main/AndroidManifest.xml new file mode 100644 index 0000000..cb2e36b --- /dev/null +++ b/features/archive/src/main/AndroidManifest.xml @@ -0,0 +1 @@ + diff --git a/features/archive/src/main/kotlin/com/dvinc/archive/data/repository/archive/ArchiveDataRepository.kt b/features/archive/src/main/kotlin/com/dvinc/archive/data/repository/archive/ArchiveDataRepository.kt new file mode 100644 index 0000000..9d92612 --- /dev/null +++ b/features/archive/src/main/kotlin/com/dvinc/archive/data/repository/archive/ArchiveDataRepository.kt @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2020 by Denis Verentsov (decsent@yandex.ru) + * All rights reserved. + */ + +package com.dvinc.archive.data.repository.archive + +import com.dvinc.archive.domain.repository.ArchiveRepository +import com.dvinc.base.notepad.data.mapper.note.NoteDataMapper +import com.dvinc.base.notepad.domain.model.Note +import com.dvinc.core.database.dao.archive.ArchiveDao +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map +import javax.inject.Inject + +class ArchiveDataRepository @Inject constructor( + private val archiveDao: ArchiveDao, + private val noteMapper: NoteDataMapper +) : ArchiveRepository { + + override suspend fun archiveNoteById(id: Long) { + archiveDao.markNoteAsArchived(id) + } + + override fun getArchivedNotes(): Flow> { + return archiveDao.getArchive() + .map { noteMapper.fromEntityToDomain(it) } + } +} diff --git a/features/archive/src/main/kotlin/com/dvinc/archive/di/component/ArchiveComponent.kt b/features/archive/src/main/kotlin/com/dvinc/archive/di/component/ArchiveComponent.kt new file mode 100644 index 0000000..b706933 --- /dev/null +++ b/features/archive/src/main/kotlin/com/dvinc/archive/di/component/ArchiveComponent.kt @@ -0,0 +1,24 @@ +package com.dvinc.archive.di.component + +import com.dvinc.archive.di.module.ArchiveModule +import com.dvinc.core.di.provider.ApplicationProvider +import com.dvinc.archive.ui.archive.ArchiveFragment +import dagger.Component + +@Component( + modules = [ + ArchiveModule::class + ], + dependencies = [ + ApplicationProvider::class + ] +) +interface ArchiveComponent { + + fun inject(target: ArchiveFragment) + + @Component.Factory + interface Factory { + fun create(applicationProvider: ApplicationProvider): ArchiveComponent + } +} diff --git a/features/archive/src/main/kotlin/com/dvinc/archive/di/module/ArchiveModule.kt b/features/archive/src/main/kotlin/com/dvinc/archive/di/module/ArchiveModule.kt new file mode 100644 index 0000000..4b418a3 --- /dev/null +++ b/features/archive/src/main/kotlin/com/dvinc/archive/di/module/ArchiveModule.kt @@ -0,0 +1,26 @@ +package com.dvinc.archive.di.module + +import com.dvinc.archive.data.repository.archive.ArchiveDataRepository +import com.dvinc.archive.domain.repository.ArchiveRepository +import com.dvinc.base.notepad.data.mapper.note.NoteDataMapper +import com.dvinc.core.database.NotepadDatabase +import com.dvinc.core.database.dao.archive.ArchiveDao +import dagger.Module +import dagger.Provides + +@Module +class ArchiveModule { + + @Provides + fun provideArchiveDao(notepadDatabase: NotepadDatabase): ArchiveDao { + return notepadDatabase.archiveDao() + } + + @Provides + fun provideArchiveRepository( + archiveDao: ArchiveDao, + noteDataMapper: NoteDataMapper + ): ArchiveRepository { + return ArchiveDataRepository(archiveDao, noteDataMapper) + } +} diff --git a/features/archive/src/main/kotlin/com/dvinc/archive/domain/repository/ArchiveRepository.kt b/features/archive/src/main/kotlin/com/dvinc/archive/domain/repository/ArchiveRepository.kt new file mode 100644 index 0000000..1ce371e --- /dev/null +++ b/features/archive/src/main/kotlin/com/dvinc/archive/domain/repository/ArchiveRepository.kt @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2020 by Denis Verentsov (decsent@yandex.ru) + * All rights reserved. + */ + +package com.dvinc.archive.domain.repository + +import com.dvinc.base.notepad.domain.model.Note +import kotlinx.coroutines.flow.Flow + +interface ArchiveRepository { + + suspend fun archiveNoteById(id: Long) + + fun getArchivedNotes(): Flow> +} diff --git a/features/archive/src/main/kotlin/com/dvinc/archive/domain/usecase/archive/ArchiveUseCase.kt b/features/archive/src/main/kotlin/com/dvinc/archive/domain/usecase/archive/ArchiveUseCase.kt new file mode 100644 index 0000000..6fa4279 --- /dev/null +++ b/features/archive/src/main/kotlin/com/dvinc/archive/domain/usecase/archive/ArchiveUseCase.kt @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2020 by Denis Verentsov (decsent@yandex.ru) + * All rights reserved. + */ + +package com.dvinc.archive.domain.usecase.archive + +import com.dvinc.archive.domain.repository.ArchiveRepository +import com.dvinc.base.notepad.domain.model.Note +import kotlinx.coroutines.flow.Flow +import javax.inject.Inject + +class ArchiveUseCase @Inject constructor( + private val archiveRepository: ArchiveRepository +) { + + fun getArchivedNotes(): Flow> { + return archiveRepository.getArchivedNotes() + } +} diff --git a/features/archive/src/main/kotlin/com/dvinc/archive/ui/archive/ArchiveFragment.kt b/features/archive/src/main/kotlin/com/dvinc/archive/ui/archive/ArchiveFragment.kt new file mode 100644 index 0000000..d71a6c6 --- /dev/null +++ b/features/archive/src/main/kotlin/com/dvinc/archive/ui/archive/ArchiveFragment.kt @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2020 by Denis Verentsov (decsent@yandex.ru) + * All rights reserved. + */ + +package com.dvinc.archive.ui.archive + +import android.os.Bundle +import android.view.View +import androidx.recyclerview.widget.LinearLayoutManager +import com.dvinc.archive.R +import com.dvinc.archive.di.component.DaggerArchiveComponent +import com.dvinc.base.notepad.presentation.adapter.notepad.NotepadAdapter +import com.dvinc.core.extension.observe +import com.dvinc.core.extension.toggleGone +import com.dvinc.core.extension.viewModels +import com.dvinc.core.recycler.SpaceItemDecorator +import com.dvinc.core.ui.BaseFragment +import javax.inject.Inject +import javax.inject.Provider +import kotlinx.android.synthetic.main.fragment_archive.fragment_archive_recycler as archiveRecycle +import kotlinx.android.synthetic.main.fragment_archive.fragment_archive_stub_text as stubContainer + +class ArchiveFragment : BaseFragment(layoutResId = R.layout.fragment_archive) { + + @Inject + lateinit var viewModelProvider: Provider + + private val viewModel by viewModels { viewModelProvider.get() } + + private val notesAdapter: NotepadAdapter by lazy { NotepadAdapter() } + + override fun injectDependencies() { + DaggerArchiveComponent.factory() + .create(appComponent) + .inject(this) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + observerViewModel() + initViews() + } + + private fun observerViewModel() { + observe(viewModel.viewState, ::handleViewState) + observe(viewModel.viewCommands, ::handleViewCommand) + } + + private fun initViews() { + with(archiveRecycle) { + layoutManager = LinearLayoutManager(requireContext()) + adapter = notesAdapter + addItemDecoration(SpaceItemDecorator()) + } + } + + private fun handleViewState(viewState: ArchiveViewState) { + notesAdapter.updateNotes(viewState.archivedNotes) + stubContainer.toggleGone(viewState.isStubViewVisible) + } +} diff --git a/features/archive/src/main/kotlin/com/dvinc/archive/ui/archive/ArchiveViewModel.kt b/features/archive/src/main/kotlin/com/dvinc/archive/ui/archive/ArchiveViewModel.kt new file mode 100644 index 0000000..d4f546d --- /dev/null +++ b/features/archive/src/main/kotlin/com/dvinc/archive/ui/archive/ArchiveViewModel.kt @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2020 by Denis Verentsov (decsent@yandex.ru) + * All rights reserved. + */ + +package com.dvinc.archive.ui.archive + +import androidx.lifecycle.viewModelScope +import com.dvinc.archive.R +import com.dvinc.archive.domain.usecase.archive.ArchiveUseCase +import com.dvinc.core.extension.update +import com.dvinc.core.ui.BaseViewModel +import com.dvinc.base.notepad.presentation.mapper.NotePresentationMapper +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import timber.log.Timber +import javax.inject.Inject + +class ArchiveViewModel @Inject constructor( + private val archiveUseCase: ArchiveUseCase, + private val noteMapper: NotePresentationMapper +) : BaseViewModel(initialViewState = ArchiveViewState()) { + + init { + loadArchive() + } + + private fun loadArchive() { + archiveUseCase.getArchivedNotes() + .onEach { + val notes = noteMapper.fromDomainToUi(it) + viewState.update { state -> + state.copy( + archivedNotes = notes, + isStubViewVisible = notes.isEmpty() + ) + } + } + .catch { + showErrorMessage(R.string.error_while_load_data_from_db) + Timber.e(it) + } + .launchIn(viewModelScope) + } +} diff --git a/features/archive/src/main/kotlin/com/dvinc/archive/ui/archive/ArchiveViewState.kt b/features/archive/src/main/kotlin/com/dvinc/archive/ui/archive/ArchiveViewState.kt new file mode 100644 index 0000000..acb0250 --- /dev/null +++ b/features/archive/src/main/kotlin/com/dvinc/archive/ui/archive/ArchiveViewState.kt @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2020 by Denis Verentsov (decsent@yandex.ru) + * All rights reserved. + */ + +package com.dvinc.archive.ui.archive + +import com.dvinc.core.ui.ViewState +import com.dvinc.base.notepad.presentation.model.NoteUi + +data class ArchiveViewState( + val archivedNotes: List = emptyList(), + val isStubViewVisible: Boolean = false +) : ViewState diff --git a/features/archive/src/main/res/layout/fragment_archive.xml b/features/archive/src/main/res/layout/fragment_archive.xml new file mode 100644 index 0000000..dc04add --- /dev/null +++ b/features/archive/src/main/res/layout/fragment_archive.xml @@ -0,0 +1,33 @@ + + + + + + + + diff --git a/features/archive/src/main/res/values/strings.xml b/features/archive/src/main/res/values/strings.xml new file mode 100644 index 0000000..b17db3f --- /dev/null +++ b/features/archive/src/main/res/values/strings.xml @@ -0,0 +1,4 @@ + + + Your archive is empty + diff --git a/features/notepad/build.gradle b/features/notepad/build.gradle index 04ad018..a044748 100644 --- a/features/notepad/build.gradle +++ b/features/notepad/build.gradle @@ -43,6 +43,7 @@ android { dependencies { implementation project(":core") + implementation project(":base:notepad") implementation( deps.kotlin.stdlib, @@ -67,7 +68,7 @@ dependencies { deps.lifecycle.view_model, deps.lifecycle.extensions, - deps.tools.timber, + deps.tools.timber ) kapt( diff --git a/features/notepad/src/main/AndroidManifest.xml b/features/notepad/src/main/AndroidManifest.xml index 822f00b..5f62fa3 100644 --- a/features/notepad/src/main/AndroidManifest.xml +++ b/features/notepad/src/main/AndroidManifest.xml @@ -1 +1 @@ - + diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/data/repository/note/NoteDataRepository.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/data/repository/notepad/NotepadDataRepository.kt similarity index 63% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/data/repository/note/NoteDataRepository.kt rename to features/notepad/src/main/kotlin/com/dvinc/notepad/data/repository/notepad/NotepadDataRepository.kt index 86c85fe..31e1300 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/data/repository/note/NoteDataRepository.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/data/repository/notepad/NotepadDataRepository.kt @@ -3,20 +3,22 @@ * All rights reserved. */ -package com.dvinc.notepad.data.repository.note +package com.dvinc.notepad.data.repository.notepad import com.dvinc.core.database.dao.note.NoteDao -import com.dvinc.notepad.data.mapper.note.NoteDataMapper -import com.dvinc.notepad.domain.model.note.Note -import com.dvinc.notepad.domain.repository.note.NoteRepository +import com.dvinc.base.notepad.data.mapper.note.NoteDataMapper +import com.dvinc.base.notepad.domain.model.Note +import com.dvinc.core.database.dao.archive.ArchiveDao +import com.dvinc.notepad.domain.repository.notepad.NotepadRepository import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map import javax.inject.Inject -class NoteDataRepository @Inject constructor( +class NotepadDataRepository @Inject constructor( private val noteDao: NoteDao, + private val archiveDao: ArchiveDao, private val noteMapper: NoteDataMapper -) : NoteRepository { +) : NotepadRepository { override fun getNotes(): Flow> { return noteDao.getNotes() @@ -36,4 +38,8 @@ class NoteDataRepository @Inject constructor( val noteEntity = noteDao.getNoteById(id) return noteMapper.fromEntityToDomain(noteEntity) } + + override suspend fun archiveNoteById(id: Long) { + archiveDao.markNoteAsArchived(id) + } } diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/di/component/NotepadComponent.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/di/component/NotepadComponent.kt index 5d2d03f..24fac72 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/di/component/NotepadComponent.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/di/component/NotepadComponent.kt @@ -8,17 +8,17 @@ package com.dvinc.notepad.di.component import com.dvinc.core.di.provider.ApplicationProvider import com.dvinc.notepad.di.module.AssistedInjectModule import com.dvinc.notepad.di.module.NotepadModule -import com.dvinc.notepad.presentation.ui.note.NoteFragment -import com.dvinc.notepad.presentation.ui.notepad.NotepadFragment +import com.dvinc.notepad.ui.note.NoteFragment +import com.dvinc.notepad.ui.notepad.NotepadFragment import dagger.Component @Component( - dependencies = [ - ApplicationProvider::class - ], modules = [ NotepadModule::class, AssistedInjectModule::class + ], + dependencies = [ + ApplicationProvider::class ] ) interface NotepadComponent { diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/di/module/NotepadModule.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/di/module/NotepadModule.kt index 2b78d35..46e8dd1 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/di/module/NotepadModule.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/di/module/NotepadModule.kt @@ -7,9 +7,10 @@ package com.dvinc.notepad.di.module import com.dvinc.core.database.NotepadDatabase import com.dvinc.core.database.dao.note.NoteDao -import com.dvinc.notepad.data.mapper.note.NoteDataMapper -import com.dvinc.notepad.data.repository.note.NoteDataRepository -import com.dvinc.notepad.domain.repository.note.NoteRepository +import com.dvinc.base.notepad.data.mapper.note.NoteDataMapper +import com.dvinc.core.database.dao.archive.ArchiveDao +import com.dvinc.notepad.data.repository.notepad.NotepadDataRepository +import com.dvinc.notepad.domain.repository.notepad.NotepadRepository import dagger.Module import dagger.Provides @@ -21,11 +22,17 @@ class NotepadModule { return notepadDatabase.notesDao() } + @Provides + fun provideArchiveDao(notepadDatabase: NotepadDatabase): ArchiveDao { + return notepadDatabase.archiveDao() + } + @Provides fun provideNoteRepository( noteDao: NoteDao, + archiveDao: ArchiveDao, noteDataMapper: NoteDataMapper - ): NoteRepository { - return NoteDataRepository(noteDao, noteDataMapper) + ): NotepadRepository { + return NotepadDataRepository(noteDao, archiveDao, noteDataMapper) } } diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/repository/note/NoteRepository.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/repository/notepad/NotepadRepository.kt similarity index 64% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/domain/repository/note/NoteRepository.kt rename to features/notepad/src/main/kotlin/com/dvinc/notepad/domain/repository/notepad/NotepadRepository.kt index faa2721..5ff8f6d 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/repository/note/NoteRepository.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/repository/notepad/NotepadRepository.kt @@ -5,12 +5,12 @@ * All rights reserved. */ -package com.dvinc.notepad.domain.repository.note +package com.dvinc.notepad.domain.repository.notepad -import com.dvinc.notepad.domain.model.note.Note +import com.dvinc.base.notepad.domain.model.Note import kotlinx.coroutines.flow.Flow -interface NoteRepository { +interface NotepadRepository { fun getNotes(): Flow> @@ -19,4 +19,6 @@ interface NoteRepository { suspend fun deleteNoteById(id: Long) suspend fun getNoteById(id: Long): Note + + suspend fun archiveNoteById(id: Long) } diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/usecase/note/NoteUseCase.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/usecase/note/NoteUseCase.kt index c2d6f7a..b6d6ae3 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/usecase/note/NoteUseCase.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/usecase/note/NoteUseCase.kt @@ -7,19 +7,19 @@ package com.dvinc.notepad.domain.usecase.note -import com.dvinc.notepad.domain.model.note.Note -import com.dvinc.notepad.domain.repository.note.NoteRepository +import com.dvinc.base.notepad.domain.model.Note +import com.dvinc.notepad.domain.repository.notepad.NotepadRepository import javax.inject.Inject class NoteUseCase @Inject constructor( - private val noteRepository: NoteRepository + private val notepadRepository: NotepadRepository ) { suspend fun getNoteById(id: Long): Note { - return noteRepository.getNoteById(id) + return notepadRepository.getNoteById(id) } suspend fun saveNote(note: Note) { - noteRepository.addNote(note) + notepadRepository.addNote(note) } } diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/usecase/notepad/NotepadUseCase.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/usecase/notepad/NotepadUseCase.kt index 949c4cb..114dbe9 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/usecase/notepad/NotepadUseCase.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/domain/usecase/notepad/NotepadUseCase.kt @@ -7,20 +7,24 @@ package com.dvinc.notepad.domain.usecase.notepad -import com.dvinc.notepad.domain.model.note.Note -import com.dvinc.notepad.domain.repository.note.NoteRepository +import com.dvinc.base.notepad.domain.model.Note +import com.dvinc.notepad.domain.repository.notepad.NotepadRepository import kotlinx.coroutines.flow.Flow import javax.inject.Inject class NotepadUseCase @Inject constructor( - private val noteRepository: NoteRepository + private val notepadRepository: NotepadRepository ) { fun getNotes(): Flow> { - return noteRepository.getNotes() + return notepadRepository.getNotes() } suspend fun deleteNote(noteId: Long) { - noteRepository.deleteNoteById(noteId) + notepadRepository.deleteNoteById(noteId) + } + + suspend fun archiveNote(noteId: Long) { + notepadRepository.archiveNoteById(noteId) } } diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/note/NoteFragment.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/note/NoteFragment.kt similarity index 93% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/note/NoteFragment.kt rename to features/notepad/src/main/kotlin/com/dvinc/notepad/ui/note/NoteFragment.kt index 6ae2d5e..a58c48e 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/note/NoteFragment.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/note/NoteFragment.kt @@ -3,7 +3,7 @@ * All rights reserved. */ -package com.dvinc.notepad.presentation.ui.note +package com.dvinc.notepad.ui.note import android.os.Bundle import android.view.View @@ -15,8 +15,8 @@ import com.dvinc.core.ui.ShowErrorMessage import com.dvinc.core.ui.ViewCommand import com.dvinc.notepad.R import com.dvinc.notepad.di.component.DaggerNotepadComponent -import com.dvinc.notepad.presentation.ui.note.NoteViewState.ExistingNoteViewState -import com.dvinc.notepad.presentation.ui.note.NoteViewState.NewNoteViewState +import com.dvinc.notepad.ui.note.NoteViewState.ExistingNoteViewState +import com.dvinc.notepad.ui.note.NoteViewState.NewNoteViewState import javax.inject.Inject import kotlinx.android.synthetic.main.fragment_note.fragment_note_content as noteContent import kotlinx.android.synthetic.main.fragment_note.fragment_note_name as noteName diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/note/NoteViewModel.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/note/NoteViewModel.kt similarity index 84% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/note/NoteViewModel.kt rename to features/notepad/src/main/kotlin/com/dvinc/notepad/ui/note/NoteViewModel.kt index 96fd819..8cf2ccb 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/note/NoteViewModel.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/note/NoteViewModel.kt @@ -3,9 +3,8 @@ * All rights reserved. */ -package com.dvinc.notepad.presentation.ui.note +package com.dvinc.notepad.ui.note -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.dvinc.core.extension.onNext import com.dvinc.core.extension.safeLaunch @@ -13,9 +12,9 @@ import com.dvinc.core.ui.BaseViewModel import com.dvinc.notepad.R import com.dvinc.notepad.common.DEFAULT_NOTE_ID import com.dvinc.notepad.domain.usecase.note.NoteUseCase -import com.dvinc.notepad.presentation.mapper.NotePresentationMapper -import com.dvinc.notepad.presentation.ui.note.NoteViewState.ExistingNoteViewState -import com.dvinc.notepad.presentation.ui.note.NoteViewState.NewNoteViewState +import com.dvinc.base.notepad.presentation.mapper.NotePresentationMapper +import com.dvinc.notepad.ui.note.NoteViewState.ExistingNoteViewState +import com.dvinc.notepad.ui.note.NoteViewState.NewNoteViewState import com.squareup.inject.assisted.Assisted import com.squareup.inject.assisted.AssistedInject import timber.log.Timber @@ -24,14 +23,12 @@ class NoteViewModel @AssistedInject constructor( @Assisted private val noteId: Long, private val noteUseCase: NoteUseCase, private val noteMapper: NotePresentationMapper -) : BaseViewModel() { +) : BaseViewModel() { companion object { private const val TAG = "NoteViewModel" } - val viewState = MutableLiveData() - init { initNote(noteId) } diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/note/NoteViewState.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/note/NoteViewState.kt similarity index 59% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/note/NoteViewState.kt rename to features/notepad/src/main/kotlin/com/dvinc/notepad/ui/note/NoteViewState.kt index 2298c41..fb00850 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/note/NoteViewState.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/note/NoteViewState.kt @@ -3,11 +3,12 @@ * All rights reserved. */ -package com.dvinc.notepad.presentation.ui.note +package com.dvinc.notepad.ui.note -import com.dvinc.notepad.domain.model.note.Note +import com.dvinc.core.ui.ViewState +import com.dvinc.base.notepad.domain.model.Note -sealed class NoteViewState { +sealed class NoteViewState : ViewState { object NewNoteViewState : NoteViewState() diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadFragment.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/notepad/NotepadFragment.kt similarity index 83% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadFragment.kt rename to features/notepad/src/main/kotlin/com/dvinc/notepad/ui/notepad/NotepadFragment.kt index 57ff44e..2ba9216 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadFragment.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/notepad/NotepadFragment.kt @@ -3,7 +3,7 @@ * All rights reserved. */ -package com.dvinc.notepad.presentation.ui.notepad +package com.dvinc.notepad.ui.notepad import android.os.Bundle import android.view.View @@ -18,15 +18,16 @@ import com.dvinc.core.ui.ShowMessage import com.dvinc.core.ui.ViewCommand import com.dvinc.notepad.R import com.dvinc.notepad.di.component.DaggerNotepadComponent -import com.dvinc.notepad.presentation.adapter.notepad.NotepadAdapter -import com.dvinc.notepad.presentation.adapter.notepad.NotepadSwipeToDeleteCallback -import com.dvinc.notepad.presentation.model.NoteUi +import com.dvinc.base.notepad.presentation.adapter.notepad.NotepadAdapter +import com.dvinc.base.notepad.presentation.adapter.notepad.NotepadSwipeCallback +import com.dvinc.base.notepad.presentation.adapter.notepad.NotepadSwipeDirection +import com.dvinc.base.notepad.presentation.model.NoteUi import javax.inject.Inject import javax.inject.Provider import kotlinx.android.synthetic.main.fragment_notepad.fragment_notepad_bottom_app_bar as bottomBar import kotlinx.android.synthetic.main.fragment_notepad.fragment_notepad_fab as bottomBarFab import kotlinx.android.synthetic.main.fragment_notepad.fragment_notepad_recycler as notesRecycler -import kotlinx.android.synthetic.main.fragment_notepad.fragment_notepad_stub_container as stubContainer +import kotlinx.android.synthetic.main.fragment_notepad.fragment_notepad_stub_text as stubContainer class NotepadFragment : BaseFragment(layoutResId = R.layout.fragment_notepad) { @@ -35,7 +36,7 @@ class NotepadFragment : BaseFragment(layoutResId = R.layout.fragment_notepad) { private val viewModel: NotepadViewModel by viewModels { viewModelFactory.get() } - private val notesAdapter: NotepadAdapter = NotepadAdapter() + private val notesAdapter: NotepadAdapter by lazy { NotepadAdapter() } private val noteItemClickListener = object : NotepadAdapter.ItemClickListener { override fun onItemClick(note: NoteUi) { @@ -43,9 +44,10 @@ class NotepadFragment : BaseFragment(layoutResId = R.layout.fragment_notepad) { } } - private val noteItemSwipeListener: (note: NoteUi) -> Unit = { - viewModel.onNoteDelete(it.id) - } + private val noteItemSwipeListener: (note: NoteUi, swipeDirection: NotepadSwipeDirection) -> Unit = + { note, direction -> + viewModel.onNoteSwipe(note.id, direction) + } override fun injectDependencies() { DaggerNotepadComponent.factory() @@ -78,7 +80,7 @@ class NotepadFragment : BaseFragment(layoutResId = R.layout.fragment_notepad) { adapter = notesAdapter addItemDecoration(SpaceItemDecorator()) } - val notepadTouchCallback = NotepadSwipeToDeleteCallback(notesAdapter, noteItemSwipeListener) + val notepadTouchCallback = NotepadSwipeCallback(notesAdapter, noteItemSwipeListener) val swipeToDeleteTouchHelper = ItemTouchHelper(notepadTouchCallback) swipeToDeleteTouchHelper.attachToRecyclerView(notesRecycler) } @@ -98,7 +100,7 @@ class NotepadFragment : BaseFragment(layoutResId = R.layout.fragment_notepad) { bottomBar.setOnMenuItemClickListener { when (it.itemId) { R.id.fragment_notepad_filter_menu_item -> { - // TODO(dv): handle filter click + viewModel.onArchiveClick() } } true diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadViewModel.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/notepad/NotepadViewModel.kt similarity index 63% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadViewModel.kt rename to features/notepad/src/main/kotlin/com/dvinc/notepad/ui/notepad/NotepadViewModel.kt index 54e7ad1..8dc1973 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadViewModel.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/notepad/NotepadViewModel.kt @@ -1,6 +1,5 @@ -package com.dvinc.notepad.presentation.ui.notepad +package com.dvinc.notepad.ui.notepad -import androidx.lifecycle.MutableLiveData import androidx.lifecycle.viewModelScope import com.dvinc.core.extension.safeLaunch import com.dvinc.core.extension.update @@ -8,7 +7,8 @@ import com.dvinc.core.ui.BaseViewModel import com.dvinc.notepad.R import com.dvinc.notepad.common.DEFAULT_NOTE_ID import com.dvinc.notepad.domain.usecase.notepad.NotepadUseCase -import com.dvinc.notepad.presentation.mapper.NotePresentationMapper +import com.dvinc.base.notepad.presentation.adapter.notepad.NotepadSwipeDirection +import com.dvinc.base.notepad.presentation.mapper.NotePresentationMapper import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -18,14 +18,12 @@ import javax.inject.Inject class NotepadViewModel @Inject constructor( private val notepadUseCase: NotepadUseCase, private val noteMapper: NotePresentationMapper -) : BaseViewModel() { +) : BaseViewModel(initialViewState = NotepadViewState()) { companion object { private const val TAG = "NotepadViewModel" } - val viewState = MutableLiveData(NotepadViewState()) - init { loadNotes() } @@ -41,7 +39,19 @@ class NotepadViewModel @Inject constructor( navigateTo(noteNavDirection) } - fun onNoteDelete(noteId: Long) { + fun onNoteSwipe(noteId: Long, swipeDirection: NotepadSwipeDirection) { + when (swipeDirection) { + NotepadSwipeDirection.LEFT -> onNoteArchive(noteId) + NotepadSwipeDirection.RIGHT -> onNoteDelete(noteId) + } + } + + fun onArchiveClick() { + val archiveNavDirection = NotepadFragmentDirections.actionNotepadFragmentToArchiveFragment() + navigateTo(archiveNavDirection) + } + + private fun onNoteDelete(noteId: Long) { viewModelScope.safeLaunch( launchBlock = { notepadUseCase.deleteNote(noteId) @@ -56,6 +66,21 @@ class NotepadViewModel @Inject constructor( ) } + private fun onNoteArchive(noteId: Long) { + viewModelScope.safeLaunch( + launchBlock = { + notepadUseCase.archiveNote(noteId) + }, + onSuccess = { + showMessage(R.string.note_successfully_archived) + }, + onError = { + showErrorMessage(R.string.error_while_archiving_note) + Timber.tag(TAG).e(it) + } + ) + } + private fun loadNotes() { notepadUseCase.getNotes() .onEach { diff --git a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadViewState.kt b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/notepad/NotepadViewState.kt similarity index 59% rename from features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadViewState.kt rename to features/notepad/src/main/kotlin/com/dvinc/notepad/ui/notepad/NotepadViewState.kt index e93083d..c97dced 100644 --- a/features/notepad/src/main/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadViewState.kt +++ b/features/notepad/src/main/kotlin/com/dvinc/notepad/ui/notepad/NotepadViewState.kt @@ -3,11 +3,12 @@ * All rights reserved. */ -package com.dvinc.notepad.presentation.ui.notepad +package com.dvinc.notepad.ui.notepad -import com.dvinc.notepad.presentation.model.NoteUi +import com.dvinc.core.ui.ViewState +import com.dvinc.base.notepad.presentation.model.NoteUi data class NotepadViewState( val notes: List = emptyList(), val isStubViewVisible: Boolean = false -) +) : ViewState diff --git a/features/notepad/src/main/res/layout/fragment_notepad.xml b/features/notepad/src/main/res/layout/fragment_notepad.xml index 1a69815..115a1f5 100644 --- a/features/notepad/src/main/res/layout/fragment_notepad.xml +++ b/features/notepad/src/main/res/layout/fragment_notepad.xml @@ -6,20 +6,15 @@ android:layout_height="match_parent" android:fitsSystemWindows="true"> - - - - + android:text="@string/fragment_notepad_stub_text" + android:textColor="@color/black" + android:textSize="20sp" + android:visibility="gone" /> + @@ -29,4 +32,11 @@ android:defaultValue="0L" app:argType="long" /> + + + diff --git a/features/notepad/src/main/res/values/strings.xml b/features/notepad/src/main/res/values/strings.xml index b9e50ce..1eb415c 100644 --- a/features/notepad/src/main/res/values/strings.xml +++ b/features/notepad/src/main/res/values/strings.xml @@ -6,11 +6,7 @@ Note Note deleted - - An error has occurred while loading from database - An error has occurred while deleting note - Cannot load note from database - Cannot add note + Note archived Filter icon diff --git a/features/notepad/src/test/kotlin/com/dvinc/notepad/data/mapper/NoteDataMapperTest.kt b/features/notepad/src/test/kotlin/com/dvinc/notepad/data/mapper/NoteDataMapperTest.kt index ced4bd3..180d993 100644 --- a/features/notepad/src/test/kotlin/com/dvinc/notepad/data/mapper/NoteDataMapperTest.kt +++ b/features/notepad/src/test/kotlin/com/dvinc/notepad/data/mapper/NoteDataMapperTest.kt @@ -1,8 +1,8 @@ package com.dvinc.notepad.data.mapper import com.dvinc.core.database.entity.note.NoteEntity -import com.dvinc.notepad.data.mapper.note.NoteDataMapper -import com.dvinc.notepad.domain.model.note.Note +import com.dvinc.base.notepad.data.mapper.note.NoteDataMapper +import com.dvinc.base.notepad.domain.model.Note import org.junit.Before import org.junit.Test diff --git a/features/notepad/src/test/kotlin/com/dvinc/notepad/data/repository/NoteDataRepositoryTest.kt b/features/notepad/src/test/kotlin/com/dvinc/notepad/data/repository/NotepadDataRepositoryTest.kt similarity index 74% rename from features/notepad/src/test/kotlin/com/dvinc/notepad/data/repository/NoteDataRepositoryTest.kt rename to features/notepad/src/test/kotlin/com/dvinc/notepad/data/repository/NotepadDataRepositoryTest.kt index e8435cb..9dd96f4 100644 --- a/features/notepad/src/test/kotlin/com/dvinc/notepad/data/repository/NoteDataRepositoryTest.kt +++ b/features/notepad/src/test/kotlin/com/dvinc/notepad/data/repository/NotepadDataRepositoryTest.kt @@ -3,9 +3,10 @@ package com.dvinc.notepad.data.repository import com.dvinc.core.database.dao.note.NoteDao import com.dvinc.core.database.entity.note.NoteEntity import com.dvinc.notepad.BaseTest -import com.dvinc.notepad.data.mapper.note.NoteDataMapper -import com.dvinc.notepad.data.repository.note.NoteDataRepository -import com.dvinc.notepad.domain.model.note.Note +import com.dvinc.base.notepad.data.mapper.note.NoteDataMapper +import com.dvinc.notepad.data.repository.notepad.NotepadDataRepository +import com.dvinc.base.notepad.domain.model.Note +import com.dvinc.core.database.dao.archive.ArchiveDao import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.verify import com.nhaarman.mockitokotlin2.whenever @@ -15,9 +16,9 @@ import kotlinx.coroutines.runBlocking import org.junit.Before import org.junit.Test -class NoteDataRepositoryTest : BaseTest() { +class NotepadDataRepositoryTest : BaseTest() { - private lateinit var noteRepository: NoteDataRepository + private lateinit var notepadRepository: NotepadDataRepository private var noteEntity: NoteEntity = mock() @@ -31,9 +32,11 @@ class NoteDataRepositoryTest : BaseTest() { private var noteMapper: NoteDataMapper = mock() + private var archiveDao: ArchiveDao = mock() + @Before fun setUp() { - noteRepository = NoteDataRepository(noteDao, noteMapper) + notepadRepository = NotepadDataRepository(noteDao, archiveDao, noteMapper) } @Test @@ -43,7 +46,7 @@ class NoteDataRepositoryTest : BaseTest() { whenever(noteMapper.fromEntityToDomain(entityList)).thenReturn(noteList) // When - val flow = noteRepository.getNotes() + val flow = notepadRepository.getNotes() // Then flow.collect { flowEmit -> @@ -57,7 +60,7 @@ class NoteDataRepositoryTest : BaseTest() { whenever(noteMapper.fromDomainToEntity(note)).thenReturn(noteEntity) // When - noteRepository.addNote(note) + notepadRepository.addNote(note) // Then verify(noteDao).addNote(noteEntity) @@ -69,7 +72,7 @@ class NoteDataRepositoryTest : BaseTest() { val noteId = 10L // When - noteRepository.deleteNoteById(noteId) + notepadRepository.deleteNoteById(noteId) // Then verify(noteDao).deleteNoteById(noteId) @@ -83,7 +86,7 @@ class NoteDataRepositoryTest : BaseTest() { whenever(noteMapper.fromEntityToDomain(noteEntity)).thenReturn(note) // When - val resultNote = noteRepository.getNoteById(noteId) + val resultNote = notepadRepository.getNoteById(noteId) // Then assert(resultNote == note) diff --git a/features/notepad/src/test/kotlin/com/dvinc/notepad/domain/usecase/NoteUseCaseTest.kt b/features/notepad/src/test/kotlin/com/dvinc/notepad/domain/usecase/NoteUseCaseTest.kt index 7134751..a046f0f 100644 --- a/features/notepad/src/test/kotlin/com/dvinc/notepad/domain/usecase/NoteUseCaseTest.kt +++ b/features/notepad/src/test/kotlin/com/dvinc/notepad/domain/usecase/NoteUseCaseTest.kt @@ -1,8 +1,8 @@ package com.dvinc.notepad.domain.usecase import com.dvinc.notepad.BaseTest -import com.dvinc.notepad.domain.model.note.Note -import com.dvinc.notepad.domain.repository.note.NoteRepository +import com.dvinc.base.notepad.domain.model.Note +import com.dvinc.notepad.domain.repository.notepad.NotepadRepository import com.dvinc.notepad.domain.usecase.note.NoteUseCase import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.verify @@ -18,24 +18,24 @@ class NoteUseCaseTest : BaseTest() { private var note: Note = mock() - private var noteRepository: NoteRepository = mock() + private var notepadRepository: NotepadRepository = mock() @Before fun setUp() { - noteUseCase = NoteUseCase(noteRepository) + noteUseCase = NoteUseCase(notepadRepository) } @Test fun `getNoteById test`() = runBlocking { // Given val noteId = 10L - whenever(noteRepository.getNoteById(noteId)).thenReturn(note) + whenever(notepadRepository.getNoteById(noteId)).thenReturn(note) // When noteUseCase.getNoteById(noteId) // Then - val resultNote = noteRepository.getNoteById(noteId) + val resultNote = notepadRepository.getNoteById(noteId) assertEquals(resultNote, note) } @@ -47,6 +47,6 @@ class NoteUseCaseTest : BaseTest() { noteUseCase.saveNote(note) // Then - verify(noteRepository).addNote(note) + verify(notepadRepository).addNote(note) } } diff --git a/features/notepad/src/test/kotlin/com/dvinc/notepad/domain/usecase/NotepadUseCaseTest.kt b/features/notepad/src/test/kotlin/com/dvinc/notepad/domain/usecase/NotepadUseCaseTest.kt index b0e7cf4..cdb1e6a 100644 --- a/features/notepad/src/test/kotlin/com/dvinc/notepad/domain/usecase/NotepadUseCaseTest.kt +++ b/features/notepad/src/test/kotlin/com/dvinc/notepad/domain/usecase/NotepadUseCaseTest.kt @@ -1,8 +1,7 @@ package com.dvinc.notepad.domain.usecase import com.dvinc.notepad.BaseTest -import com.dvinc.notepad.domain.model.note.Note -import com.dvinc.notepad.domain.repository.note.NoteRepository +import com.dvinc.notepad.domain.repository.notepad.NotepadRepository import com.dvinc.notepad.domain.usecase.notepad.NotepadUseCase import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.verify @@ -14,13 +13,11 @@ class NotepadUseCaseTest : BaseTest() { private lateinit var notepadUseCase: NotepadUseCase - private var note: Note = mock() - - private var noteRepository: NoteRepository = mock() + private var notepadRepository: NotepadRepository = mock() @Before fun setUp() { - notepadUseCase = NotepadUseCase(noteRepository) + notepadUseCase = NotepadUseCase(notepadRepository) } @Test @@ -31,7 +28,7 @@ class NotepadUseCaseTest : BaseTest() { notepadUseCase.getNotes() // Then - verify(noteRepository).getNotes() + verify(notepadRepository).getNotes() } @Test @@ -43,6 +40,6 @@ class NotepadUseCaseTest : BaseTest() { notepadUseCase.deleteNote(noteId) // Then - verify(noteRepository).deleteNoteById(noteId) + verify(notepadRepository).deleteNoteById(noteId) } } diff --git a/features/notepad/src/test/kotlin/com/dvinc/notepad/presentation/ui/note/NoteViewModelTest.kt b/features/notepad/src/test/kotlin/com/dvinc/notepad/presentation/ui/note/NoteViewModelTest.kt index 5b01723..3b697bb 100644 --- a/features/notepad/src/test/kotlin/com/dvinc/notepad/presentation/ui/note/NoteViewModelTest.kt +++ b/features/notepad/src/test/kotlin/com/dvinc/notepad/presentation/ui/note/NoteViewModelTest.kt @@ -10,10 +10,12 @@ import com.dvinc.core.ui.NavigateUp import com.dvinc.core.ui.ShowErrorMessage import com.dvinc.notepad.BaseTest import com.dvinc.notepad.R -import com.dvinc.notepad.domain.model.note.Note +import com.dvinc.base.notepad.domain.model.Note import com.dvinc.notepad.domain.usecase.note.NoteUseCase -import com.dvinc.notepad.presentation.mapper.NotePresentationMapper +import com.dvinc.base.notepad.presentation.mapper.NotePresentationMapper import com.dvinc.notepad.presentation.ui.ViewCommandUtil +import com.dvinc.notepad.ui.note.NoteViewModel +import com.dvinc.notepad.ui.note.NoteViewState import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.whenever import kotlinx.coroutines.runBlocking diff --git a/features/notepad/src/test/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadViewModelTest.kt b/features/notepad/src/test/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadViewModelTest.kt index 4e3a56e..3608d2b 100644 --- a/features/notepad/src/test/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadViewModelTest.kt +++ b/features/notepad/src/test/kotlin/com/dvinc/notepad/presentation/ui/notepad/NotepadViewModelTest.kt @@ -10,12 +10,16 @@ import com.dvinc.core.ui.NavigateTo import com.dvinc.core.ui.ShowErrorMessage import com.dvinc.core.ui.ShowMessage import com.dvinc.notepad.BaseTest -import com.dvinc.notepad.R -import com.dvinc.notepad.domain.model.note.Note +import com.dvinc.base.notepad.domain.model.Note import com.dvinc.notepad.domain.usecase.notepad.NotepadUseCase -import com.dvinc.notepad.presentation.mapper.NotePresentationMapper -import com.dvinc.notepad.presentation.model.NoteUi +import com.dvinc.base.notepad.presentation.adapter.notepad.NotepadSwipeDirection +import com.dvinc.base.notepad.presentation.mapper.NotePresentationMapper +import com.dvinc.base.notepad.presentation.model.NoteUi +import com.dvinc.notepad.R import com.dvinc.notepad.presentation.ui.ViewCommandUtil +import com.dvinc.notepad.ui.notepad.NotepadFragmentDirections +import com.dvinc.notepad.ui.notepad.NotepadViewModel +import com.dvinc.notepad.ui.notepad.NotepadViewState import com.nhaarman.mockitokotlin2.doReturn import com.nhaarman.mockitokotlin2.mock import com.nhaarman.mockitokotlin2.whenever @@ -34,7 +38,7 @@ class NotepadViewModelTest : BaseTest() { } private var notepadUseCase: NotepadUseCase = mock { - on { getNotes() } doReturn flow { emit(emptyList()) } + on { getNotes() } doReturn flow { emit(emptyList()) } } @Before @@ -45,7 +49,7 @@ class NotepadViewModelTest : BaseTest() { @Test fun `verify that Content state has empty list when empty notes list returned from repository`() = runBlocking { // Given - whenever(notepadUseCase.getNotes()).thenReturn(flow { emit(emptyList()) }) + whenever(notepadUseCase.getNotes()).thenReturn(flow { emit(emptyList()) }) val notepadViewModel = NotepadViewModel(notepadUseCase, noteMapper) // When @@ -94,7 +98,7 @@ class NotepadViewModelTest : BaseTest() { val notepadViewModel = NotepadViewModel(notepadUseCase, noteMapper) // When - notepadViewModel.onNoteDelete(10L) + notepadViewModel.onNoteSwipe(10L, NotepadSwipeDirection.RIGHT) // Then val resultViewCommandList = notepadViewModel.viewCommands.getOrAwaitValue() @@ -111,7 +115,7 @@ class NotepadViewModelTest : BaseTest() { whenever(notepadUseCase.deleteNote(noteUi.id)).thenThrow(IllegalStateException()) // When - notepadViewModel.onNoteDelete(noteUi.id) + notepadViewModel.onNoteSwipe(noteUi.id, NotepadSwipeDirection.RIGHT) // Then val resultViewCommandList = notepadViewModel.viewCommands.getOrAwaitValue() diff --git a/settings.gradle b/settings.gradle index 4150700..8c65964 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,5 @@ include ':app', ':core', - ':features:notepad' + ':base:notepad', + ':features:notepad', + ':features:archive'