database setup and insert/delete working

Signed-off-by: parneet-guraya <gurayaparneet@gmail.com>
This commit is contained in:
parneet-guraya 2024-12-15 22:42:58 +05:30
parent 0153cbe0ed
commit f908f71a7e
No known key found for this signature in database
GPG key ID: 63B807C4B2A9064B
10 changed files with 223 additions and 1 deletions

View file

@ -0,0 +1,26 @@
package fr.free.nrw.commons.bookmarks.category
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import fr.free.nrw.commons.bookmarks.models.BookmarksCategoryModal
import kotlinx.coroutines.flow.Flow
@Dao
interface BookmarkCategoriesDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(bookmarksCategoryModal: BookmarksCategoryModal)
@Delete
suspend fun delete(bookmarksCategoryModal: BookmarksCategoryModal)
@Query("SELECT EXISTS (SELECT 1 FROM bookmarks_categories WHERE categoryName = :categoryName)")
suspend fun doesExist(categoryName: String): Boolean
@Query("SELECT * FROM bookmarks_categories")
fun getAllCategories(): Flow<List<BookmarksCategoryModal>>
}

View file

@ -0,0 +1,26 @@
package fr.free.nrw.commons.bookmarks.category
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import dagger.android.support.DaggerFragment
import fr.free.nrw.commons.R
class BookmarkCategoriesFragment : DaggerFragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_bookmark_categories, container, false)
}
companion object {
@JvmStatic
fun newInstance(param1: String, param2: String) =
BookmarkCategoriesFragment()
}
}

View file

@ -0,0 +1,9 @@
package fr.free.nrw.commons.bookmarks.category
class BookmarkCategoriesViewModel(
) {
}

View file

@ -0,0 +1,9 @@
package fr.free.nrw.commons.bookmarks.models
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "bookmarks_categories")
data class BookmarksCategoryModal(
@PrimaryKey val categoryName: String
)

View file

@ -7,8 +7,12 @@ import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import androidx.activity.viewModels
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import fr.free.nrw.commons.Media
import fr.free.nrw.commons.R
import fr.free.nrw.commons.Utils
@ -19,6 +23,8 @@ import fr.free.nrw.commons.explore.categories.parent.ParentCategoriesFragment
import fr.free.nrw.commons.explore.categories.sub.SubCategoriesFragment
import fr.free.nrw.commons.media.MediaDetailPagerFragment
import fr.free.nrw.commons.theme.BaseActivity
import kotlinx.coroutines.launch
import javax.inject.Inject
/**
@ -38,6 +44,11 @@ class CategoryDetailsActivity : BaseActivity(),
private lateinit var binding: ActivityCategoryDetailsBinding
@Inject
lateinit var categoryViewModelFactory: CategoryDetailsViewModel.ViewModelFactory
private val viewModel: CategoryDetailsViewModel by viewModels<CategoryDetailsViewModel> { categoryViewModelFactory }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -53,6 +64,15 @@ class CategoryDetailsActivity : BaseActivity(),
supportActionBar?.setDisplayHomeAsUpEnabled(true)
setTabs()
setPageTitle()
lifecycleScope.launch {
repeatOnLifecycle(Lifecycle.State.STARTED){
viewModel.bookmarkState.collect {
invalidateOptionsMenu()
}
}
}
}
/**
@ -73,6 +93,8 @@ class CategoryDetailsActivity : BaseActivity(),
categoriesMediaFragment.arguments = arguments
subCategoryListFragment.arguments = arguments
parentCategoriesFragment.arguments = arguments
viewModel.onCheckIfBookmarked(categoryName!!)
}
fragmentList.add(categoriesMediaFragment)
titleList.add("MEDIA")
@ -181,6 +203,15 @@ class CategoryDetailsActivity : BaseActivity(),
Utils.handleWebUrl(this, Uri.parse(title.canonicalUri))
true
}
R.id.menu_bookmark_current_category -> {
//TODO: most likely won't be null
categoryName?.let {
viewModel.onBookmarkClick(categoryName = it)
}
true
}
android.R.id.home -> {
onBackPressed()
true
@ -189,6 +220,20 @@ class CategoryDetailsActivity : BaseActivity(),
}
}
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
menu?.run {
val bookmarkMenuItem = findItem(R.id.menu_bookmark_current_category)
val icon = if(viewModel.bookmarkState.value){
R.drawable.menu_ic_round_star_filled_24px
} else {
R.drawable.menu_ic_round_star_border_24px
}
bookmarkMenuItem.setIcon(icon)
}
return super.onPrepareOptionsMenu(menu)
}
/**
* This method is called on backPressed of anyFragment in the activity.
* If condition is called when mediaDetailFragment is opened.

View file

@ -0,0 +1,77 @@
package fr.free.nrw.commons.category
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.viewModelScope
import fr.free.nrw.commons.bookmarks.category.BookmarkCategoriesDao
import fr.free.nrw.commons.bookmarks.models.BookmarksCategoryModal
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject
class CategoryDetailsViewModel(
private val bookmarkCategoriesDao: BookmarkCategoriesDao
) : ViewModel() {
private val _bookmarkState = MutableStateFlow(false)
val bookmarkState = _bookmarkState.asStateFlow()
fun onCheckIfBookmarked(categoryName: String) {
viewModelScope.launch {
val isBookmarked = bookmarkCategoriesDao.doesExist(categoryName)
_bookmarkState.update {
isBookmarked
}
}
}
fun onBookmarkClick(categoryName: String) {
if (_bookmarkState.value) {
deleteBookmark(categoryName)
_bookmarkState.update {
false
}
} else {
addBookmark(categoryName)
_bookmarkState.update {
true
}
}
}
private fun addBookmark(categoryName: String) {
viewModelScope.launch {
// TODO [Parry] view only knows about `name` see if we can have more data
val categoryItem = BookmarksCategoryModal(
categoryName = categoryName
)
bookmarkCategoriesDao.insert(categoryItem)
}
}
private fun deleteBookmark(categoryName: String) {
viewModelScope.launch {
bookmarkCategoriesDao.delete(
BookmarksCategoryModal(
categoryName = categoryName
)
)
}
}
class ViewModelFactory @Inject constructor(
private val bookmarkCategoriesDao: BookmarkCategoriesDao
) : ViewModelProvider.Factory {
@Suppress("UNCHECKED_CAST")
override fun <T : ViewModel> create(modelClass: Class<T>): T =
if (modelClass.isAssignableFrom(CategoryDetailsViewModel::class.java)) {
CategoryDetailsViewModel(bookmarkCategoriesDao) as T
} else {
throw IllegalArgumentException("Unknown class name")
}
}
}

View file

@ -3,6 +3,8 @@ package fr.free.nrw.commons.db
import androidx.room.Database
import androidx.room.RoomDatabase
import androidx.room.TypeConverters
import fr.free.nrw.commons.bookmarks.category.BookmarkCategoriesDao
import fr.free.nrw.commons.bookmarks.models.BookmarksCategoryModal
import fr.free.nrw.commons.contributions.Contribution
import fr.free.nrw.commons.contributions.ContributionDao
import fr.free.nrw.commons.customselector.database.NotForUploadStatus
@ -21,7 +23,7 @@ import fr.free.nrw.commons.upload.depicts.DepictsDao
*
*/
@Database(
entities = [Contribution::class, Depicts::class, UploadedStatus::class, NotForUploadStatus::class, ReviewEntity::class, Place::class],
entities = [Contribution::class, Depicts::class, UploadedStatus::class, NotForUploadStatus::class, ReviewEntity::class, Place::class, BookmarksCategoryModal::class],
version = 18,
exportSchema = false,
)
@ -38,4 +40,6 @@ abstract class AppDatabase : RoomDatabase() {
abstract fun NotForUploadStatusDao(): NotForUploadStatusDao
abstract fun ReviewDao(): ReviewDao
abstract fun bookmarkCategoriesDao(): BookmarkCategoriesDao
}

View file

@ -15,6 +15,7 @@ import dagger.Provides
import fr.free.nrw.commons.BuildConfig
import fr.free.nrw.commons.R
import fr.free.nrw.commons.auth.SessionManager
import fr.free.nrw.commons.bookmarks.category.BookmarkCategoriesDao
import fr.free.nrw.commons.contributions.ContributionDao
import fr.free.nrw.commons.customselector.database.NotForUploadStatusDao
import fr.free.nrw.commons.customselector.database.UploadedStatusDao
@ -221,6 +222,10 @@ open class CommonsApplicationModule(private val applicationContext: Context) {
fun providesReviewDao(appDatabase: AppDatabase): ReviewDao =
appDatabase.ReviewDao()
@Provides
fun providesBookmarkCategoriesDao (appDatabase: AppDatabase): BookmarkCategoriesDao =
appDatabase.bookmarkCategoriesDao()
@Provides
fun providesContentResolver(context: Context): ContentResolver =
context.contentResolver

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".bookmarks.category.BookmarkCategoriesFragment">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/hello_blank_fragment" />
</FrameLayout>

View file

@ -2,6 +2,13 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/menu_bookmark_current_category"
android:icon="@drawable/menu_icon_bookmark_selector"
android:title="@string/menu_bookmark"
app:showAsAction="ifRoom" />
<item
android:id="@+id/menu_browser_current_category"
android:title="@string/menu_view_category_page"