mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 12:23:58 +01:00
Refactor: Migrate to Room Database for Bookmark Locations
This commit migrates the bookmark locations functionality from a custom content provider to Room database.
Key changes:
* **Removal of `BookmarkLocationsContentProvider`:** This class, which previously handled data storage, has been removed.
* **Introduction of `BookmarksLocations`:** This data class now represents a bookmarked location, serving as the Room entity.
* **Creation of `BookmarkLocationsDao`:** This Room DAO handles database interactions for bookmark locations, including:
* Adding, deleting, and querying bookmarked locations.
* Checking if a location is already bookmarked.
* Updating the bookmark status of a location.
* Retrieving all bookmarked locations as `Place` objects.
* **`BookmarkLocationsViewModel`:** Added to manage the data layer for bookmark locations
* **`NearbyUtil`:** Created a Util class for Nearby to manage the bookmark locations.
* **Updates in `PlaceAdapter` and `PlaceAdapterDelegate`:** These classes have been modified to work with the new Room-based data layer.
* **Updates in `AppDatabase`:** The database now includes `BookmarksLocations` as an entity and exposes the `bookmarkLocationsDao`.
* **Updates in `FragmentBuilderModule` and `CommonsApplicationModule`**: for DI
* **Removal of `DBOpenHelper` upgrade for locations**: as it is no longer needed
* **Updates in `NearbyParentFragmentPresenter`**: refactored the logic to use the dao functions
* **Updates in `NearbyParentFragment`**: refactored the logic to use the util and dao functions
* **Update in `BookmarkLocationsController`**: removed as its no longer needed
* **Add `toPlace` and `toBookmarksLocations`**: extension functions to map between data class and entities
* **Update in `CommonsApplication`**: to remove old db table.
This commit is contained in:
parent
f32c59034d
commit
7894f4a026
17 changed files with 199 additions and 425 deletions
|
|
@ -253,7 +253,6 @@ class CommonsApplication : MultiDexApplication() {
|
||||||
Timber.e(e)
|
Timber.e(e)
|
||||||
}
|
}
|
||||||
BookmarkPicturesDao.Table.onDelete(db)
|
BookmarkPicturesDao.Table.onDelete(db)
|
||||||
BookmarkLocationsDao.Table.onDelete(db)
|
|
||||||
BookmarkItemsDao.Table.onDelete(db)
|
BookmarkItemsDao.Table.onDelete(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,126 +0,0 @@
|
||||||
package fr.free.nrw.commons.bookmarks.locations
|
|
||||||
|
|
||||||
// We can get uri using java.Net.Uri, but android implementation is faster
|
|
||||||
// (but it's forgiving with handling exceptions though)
|
|
||||||
import android.content.ContentValues
|
|
||||||
import android.database.Cursor
|
|
||||||
import android.database.sqlite.SQLiteQueryBuilder
|
|
||||||
import android.net.Uri
|
|
||||||
import fr.free.nrw.commons.BuildConfig
|
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao.Table.COLUMN_NAME
|
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao.Table.TABLE_NAME
|
|
||||||
import fr.free.nrw.commons.data.DBOpenHelper
|
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerContentProvider
|
|
||||||
import timber.log.Timber
|
|
||||||
import javax.inject.Inject
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles private storage for Bookmark locations
|
|
||||||
*/
|
|
||||||
class BookmarkLocationsContentProvider : CommonsDaggerContentProvider() {
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val BASE_PATH = "bookmarksLocations"
|
|
||||||
val BASE_URI: Uri =
|
|
||||||
Uri.parse("content://${BuildConfig.BOOKMARK_LOCATIONS_AUTHORITY}/$BASE_PATH")
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Append bookmark locations name to the base URI.
|
|
||||||
*/
|
|
||||||
fun uriForName(name: String): Uri {
|
|
||||||
return Uri.parse("$BASE_URI/$name")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
lateinit var dbOpenHelper: DBOpenHelper
|
|
||||||
|
|
||||||
override fun getType(uri: Uri): String? = null
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Queries the SQLite database for the bookmark locations.
|
|
||||||
*/
|
|
||||||
override fun query(
|
|
||||||
uri: Uri,
|
|
||||||
projection: Array<String>?,
|
|
||||||
selection: String?,
|
|
||||||
selectionArgs: Array<String>?,
|
|
||||||
sortOrder: String?
|
|
||||||
): Cursor {
|
|
||||||
val queryBuilder = SQLiteQueryBuilder().apply {
|
|
||||||
tables = TABLE_NAME
|
|
||||||
}
|
|
||||||
|
|
||||||
val db = dbOpenHelper.readableDatabase
|
|
||||||
val cursor = queryBuilder.query(
|
|
||||||
db,
|
|
||||||
projection,
|
|
||||||
selection,
|
|
||||||
selectionArgs,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
sortOrder
|
|
||||||
)
|
|
||||||
cursor.setNotificationUri(context?.contentResolver, uri)
|
|
||||||
return cursor
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the update query of local SQLite database.
|
|
||||||
*/
|
|
||||||
override fun update(
|
|
||||||
uri: Uri,
|
|
||||||
contentValues: ContentValues?,
|
|
||||||
selection: String?,
|
|
||||||
selectionArgs: Array<String>?
|
|
||||||
): Int {
|
|
||||||
val db = dbOpenHelper.writableDatabase
|
|
||||||
val rowsUpdated: Int
|
|
||||||
|
|
||||||
if (selection.isNullOrEmpty()) {
|
|
||||||
val id = uri.lastPathSegment?.toIntOrNull()
|
|
||||||
?: throw IllegalArgumentException("Invalid ID in URI")
|
|
||||||
rowsUpdated = db.update(
|
|
||||||
TABLE_NAME,
|
|
||||||
contentValues,
|
|
||||||
"$COLUMN_NAME = ?",
|
|
||||||
arrayOf(id.toString())
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
throw IllegalArgumentException(
|
|
||||||
"Parameter `selection` should be empty when updating an ID"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
context?.contentResolver?.notifyChange(uri, null)
|
|
||||||
return rowsUpdated
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the insertion of a new bookmark locations record to the local SQLite database.
|
|
||||||
*/
|
|
||||||
override fun insert(uri: Uri, contentValues: ContentValues?): Uri {
|
|
||||||
val db = dbOpenHelper.writableDatabase
|
|
||||||
val id = db.insert(TABLE_NAME, null, contentValues)
|
|
||||||
context?.contentResolver?.notifyChange(uri, null)
|
|
||||||
return Uri.parse("$BASE_URI/$id")
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the deletion of bookmark locations from the local SQLite database.
|
|
||||||
*/
|
|
||||||
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
|
|
||||||
val db = dbOpenHelper.readableDatabase
|
|
||||||
Timber.d("Deleting bookmark name %s", uri.lastPathSegment)
|
|
||||||
|
|
||||||
val rows = db.delete(
|
|
||||||
TABLE_NAME,
|
|
||||||
"location_name = ?",
|
|
||||||
arrayOf(uri.lastPathSegment)
|
|
||||||
)
|
|
||||||
|
|
||||||
context?.contentResolver?.notifyChange(uri, null)
|
|
||||||
return rows
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -13,5 +13,5 @@ class BookmarkLocationsController @Inject constructor(
|
||||||
* Load bookmarked locations from the database.
|
* Load bookmarked locations from the database.
|
||||||
* @return a list of Place objects.
|
* @return a list of Place objects.
|
||||||
*/
|
*/
|
||||||
fun loadFavoritesLocations(): List<Place> = bookmarkLocationDao.getAllBookmarksLocations()
|
fun loadFavoritesLocations(): List<Place> = listOf()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,286 +1,49 @@
|
||||||
package fr.free.nrw.commons.bookmarks.locations
|
package fr.free.nrw.commons.bookmarks.locations
|
||||||
|
|
||||||
|
import androidx.room.Dao
|
||||||
import android.annotation.SuppressLint
|
import androidx.room.Delete
|
||||||
import android.content.ContentProviderClient
|
import androidx.room.Insert
|
||||||
import android.content.ContentValues
|
import androidx.room.OnConflictStrategy
|
||||||
import android.database.Cursor
|
import androidx.room.Query
|
||||||
import android.database.sqlite.SQLiteDatabase
|
|
||||||
import android.database.sqlite.SQLiteException
|
|
||||||
import android.os.RemoteException
|
|
||||||
import androidx.annotation.NonNull
|
|
||||||
import fr.free.nrw.commons.location.LatLng
|
|
||||||
import fr.free.nrw.commons.nearby.Label
|
|
||||||
import fr.free.nrw.commons.nearby.NearbyController
|
import fr.free.nrw.commons.nearby.NearbyController
|
||||||
import fr.free.nrw.commons.nearby.Place
|
import fr.free.nrw.commons.nearby.Place
|
||||||
import fr.free.nrw.commons.nearby.Sitelinks
|
import kotlinx.coroutines.flow.Flow
|
||||||
import timber.log.Timber
|
import kotlinx.coroutines.flow.flow
|
||||||
import javax.inject.Inject
|
|
||||||
import javax.inject.Named
|
|
||||||
import javax.inject.Provider
|
|
||||||
|
|
||||||
|
@Dao
|
||||||
|
abstract class BookmarkLocationsDao {
|
||||||
|
|
||||||
class BookmarkLocationsDao @Inject constructor(
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
@Named("bookmarksLocation") private val clientProvider: Provider<ContentProviderClient>
|
abstract suspend fun addBookmarkLocation(bookmarkLocation: BookmarksLocations)
|
||||||
) {
|
|
||||||
|
|
||||||
/**
|
@Query("SELECT * FROM bookmarks_locations")
|
||||||
* Find all persisted location bookmarks in the database
|
abstract suspend fun getAllBookmarksLocations(): List<BookmarksLocations>
|
||||||
* @return list of Place
|
|
||||||
*/
|
@Query("SELECT EXISTS (SELECT 1 FROM bookmarks_locations WHERE location_name = :name)")
|
||||||
fun getAllBookmarksLocations(): List<Place> {
|
abstract suspend fun findBookmarkLocation(name: String): Boolean
|
||||||
val items = mutableListOf<Place>()
|
|
||||||
var cursor: Cursor? = null
|
@Delete
|
||||||
val db = clientProvider.get()
|
abstract suspend fun deleteBookmarkLocation(bookmarkLocation: BookmarksLocations)
|
||||||
try {
|
|
||||||
cursor = db.query(
|
suspend fun updateBookmarkLocation(bookmarkLocation: Place): Boolean {
|
||||||
BookmarkLocationsContentProvider.BASE_URI,
|
val bookmarkLocationExists = findBookmarkLocation(bookmarkLocation.name)
|
||||||
Table.ALL_FIELDS,
|
|
||||||
null,
|
if(bookmarkLocationExists) {
|
||||||
emptyArray(),
|
deleteBookmarkLocation(
|
||||||
null
|
bookmarkLocation.toBookmarksLocations()
|
||||||
)
|
)
|
||||||
cursor?.let {
|
|
||||||
while (it.moveToNext()) {
|
|
||||||
items.add(fromCursor(it))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: RemoteException) {
|
|
||||||
throw RuntimeException(e)
|
|
||||||
} finally {
|
|
||||||
cursor?.close()
|
|
||||||
db.release()
|
|
||||||
}
|
|
||||||
return items
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Look for a place in bookmarks table in order to insert or delete it
|
|
||||||
* @param bookmarkLocation : Place object
|
|
||||||
* @return boolean : is Place now fav ?
|
|
||||||
*/
|
|
||||||
fun updateBookmarkLocation(bookmarkLocation: Place): Boolean {
|
|
||||||
val bookmarkExists = findBookmarkLocation(bookmarkLocation)
|
|
||||||
if (bookmarkExists) {
|
|
||||||
deleteBookmarkLocation(bookmarkLocation)
|
|
||||||
NearbyController.updateMarkerLabelListBookmark(bookmarkLocation, false)
|
NearbyController.updateMarkerLabelListBookmark(bookmarkLocation, false)
|
||||||
} else {
|
} else {
|
||||||
addBookmarkLocation(bookmarkLocation)
|
addBookmarkLocation(
|
||||||
|
bookmarkLocation.toBookmarksLocations()
|
||||||
|
)
|
||||||
NearbyController.updateMarkerLabelListBookmark(bookmarkLocation, true)
|
NearbyController.updateMarkerLabelListBookmark(bookmarkLocation, true)
|
||||||
}
|
}
|
||||||
return !bookmarkExists
|
|
||||||
|
return !bookmarkLocationExists
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun getAllBookmarksLocationsPlace(): Flow<List<Place>> {
|
||||||
* Add a Place to bookmarks table
|
return flow { getAllBookmarksLocations().map { it.toPlace() } }
|
||||||
* @param bookmarkLocation : Place to add
|
|
||||||
*/
|
|
||||||
private fun addBookmarkLocation(bookmarkLocation: Place) {
|
|
||||||
val db = clientProvider.get()
|
|
||||||
try {
|
|
||||||
db.insert(BookmarkLocationsContentProvider.BASE_URI, toContentValues(bookmarkLocation))
|
|
||||||
} catch (e: RemoteException) {
|
|
||||||
throw RuntimeException(e)
|
|
||||||
} finally {
|
|
||||||
db.release()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete a Place from bookmarks table
|
|
||||||
* @param bookmarkLocation : Place to delete
|
|
||||||
*/
|
|
||||||
private fun deleteBookmarkLocation(bookmarkLocation: Place) {
|
|
||||||
val db = clientProvider.get()
|
|
||||||
try {
|
|
||||||
db.delete(
|
|
||||||
BookmarkLocationsContentProvider.uriForName(bookmarkLocation.name),
|
|
||||||
null,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
} catch (e: RemoteException) {
|
|
||||||
throw RuntimeException(e)
|
|
||||||
} finally {
|
|
||||||
db.release()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Find a Place from database based on its name
|
|
||||||
* @param bookmarkLocation : Place to find
|
|
||||||
* @return boolean : is Place in database ?
|
|
||||||
*/
|
|
||||||
fun findBookmarkLocation(bookmarkLocation: Place): Boolean {
|
|
||||||
var cursor: Cursor? = null
|
|
||||||
val db = clientProvider.get()
|
|
||||||
try {
|
|
||||||
cursor = db.query(
|
|
||||||
BookmarkLocationsContentProvider.BASE_URI,
|
|
||||||
Table.ALL_FIELDS,
|
|
||||||
"${Table.COLUMN_NAME}=?",
|
|
||||||
arrayOf(bookmarkLocation.name),
|
|
||||||
null
|
|
||||||
)
|
|
||||||
return cursor?.moveToFirst() == true
|
|
||||||
} catch (e: RemoteException) {
|
|
||||||
throw RuntimeException(e)
|
|
||||||
} finally {
|
|
||||||
cursor?.close()
|
|
||||||
db.release()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("Range")
|
|
||||||
@NonNull
|
|
||||||
fun fromCursor(cursor: Cursor): Place {
|
|
||||||
val location = LatLng(
|
|
||||||
cursor.getDouble(cursor.getColumnIndex(Table.COLUMN_LAT)),
|
|
||||||
cursor.getDouble(cursor.getColumnIndex(Table.COLUMN_LONG)),
|
|
||||||
1F
|
|
||||||
)
|
|
||||||
|
|
||||||
val builder = Sitelinks.Builder().apply {
|
|
||||||
setWikipediaLink(cursor.getString(cursor.getColumnIndex(Table.COLUMN_WIKIPEDIA_LINK)))
|
|
||||||
setWikidataLink(cursor.getString(cursor.getColumnIndex(Table.COLUMN_WIKIDATA_LINK)))
|
|
||||||
setCommonsLink(cursor.getString(cursor.getColumnIndex(Table.COLUMN_COMMONS_LINK)))
|
|
||||||
}
|
|
||||||
|
|
||||||
return Place(
|
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_LANGUAGE)),
|
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_NAME)),
|
|
||||||
Label.fromText(cursor.getString(cursor.getColumnIndex(Table.COLUMN_LABEL_TEXT))),
|
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_DESCRIPTION)),
|
|
||||||
location,
|
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_CATEGORY)),
|
|
||||||
builder.build(),
|
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_PIC)),
|
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_EXISTS))?.toBoolean() ?: false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun toContentValues(bookmarkLocation: Place): ContentValues {
|
|
||||||
return ContentValues().apply {
|
|
||||||
put(Table.COLUMN_NAME, bookmarkLocation.name)
|
|
||||||
put(Table.COLUMN_LANGUAGE, bookmarkLocation.language)
|
|
||||||
put(Table.COLUMN_DESCRIPTION, bookmarkLocation.longDescription)
|
|
||||||
put(Table.COLUMN_CATEGORY, bookmarkLocation.category)
|
|
||||||
put(Table.COLUMN_LABEL_TEXT, bookmarkLocation.label?.text ?: "")
|
|
||||||
put(Table.COLUMN_LABEL_ICON, bookmarkLocation.label?.icon)
|
|
||||||
put(Table.COLUMN_WIKIPEDIA_LINK, bookmarkLocation.siteLinks.wikipediaLink.toString())
|
|
||||||
put(Table.COLUMN_WIKIDATA_LINK, bookmarkLocation.siteLinks.wikidataLink.toString())
|
|
||||||
put(Table.COLUMN_COMMONS_LINK, bookmarkLocation.siteLinks.commonsLink.toString())
|
|
||||||
put(Table.COLUMN_LAT, bookmarkLocation.location.latitude)
|
|
||||||
put(Table.COLUMN_LONG, bookmarkLocation.location.longitude)
|
|
||||||
put(Table.COLUMN_PIC, bookmarkLocation.pic)
|
|
||||||
put(Table.COLUMN_EXISTS, bookmarkLocation.exists.toString())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object Table {
|
|
||||||
const val TABLE_NAME = "bookmarksLocations"
|
|
||||||
|
|
||||||
const val COLUMN_NAME = "location_name"
|
|
||||||
const val COLUMN_LANGUAGE = "location_language"
|
|
||||||
const val COLUMN_DESCRIPTION = "location_description"
|
|
||||||
const val COLUMN_LAT = "location_lat"
|
|
||||||
const val COLUMN_LONG = "location_long"
|
|
||||||
const val COLUMN_CATEGORY = "location_category"
|
|
||||||
const val COLUMN_LABEL_TEXT = "location_label_text"
|
|
||||||
const val COLUMN_LABEL_ICON = "location_label_icon"
|
|
||||||
const val COLUMN_IMAGE_URL = "location_image_url"
|
|
||||||
const val COLUMN_WIKIPEDIA_LINK = "location_wikipedia_link"
|
|
||||||
const val COLUMN_WIKIDATA_LINK = "location_wikidata_link"
|
|
||||||
const val COLUMN_COMMONS_LINK = "location_commons_link"
|
|
||||||
const val COLUMN_PIC = "location_pic"
|
|
||||||
const val COLUMN_EXISTS = "location_exists"
|
|
||||||
|
|
||||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
|
||||||
val ALL_FIELDS = arrayOf(
|
|
||||||
COLUMN_NAME, COLUMN_LANGUAGE, COLUMN_DESCRIPTION, COLUMN_CATEGORY, COLUMN_LABEL_TEXT, COLUMN_LABEL_ICON,
|
|
||||||
COLUMN_LAT, COLUMN_LONG, COLUMN_IMAGE_URL, COLUMN_WIKIPEDIA_LINK, COLUMN_WIKIDATA_LINK, COLUMN_COMMONS_LINK,
|
|
||||||
COLUMN_PIC, COLUMN_EXISTS
|
|
||||||
)
|
|
||||||
|
|
||||||
const val DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS $TABLE_NAME"
|
|
||||||
|
|
||||||
const val CREATE_TABLE_STATEMENT = """
|
|
||||||
CREATE TABLE $TABLE_NAME (
|
|
||||||
$COLUMN_NAME STRING PRIMARY KEY,
|
|
||||||
$COLUMN_LANGUAGE STRING,
|
|
||||||
$COLUMN_DESCRIPTION STRING,
|
|
||||||
$COLUMN_CATEGORY STRING,
|
|
||||||
$COLUMN_LABEL_TEXT STRING,
|
|
||||||
$COLUMN_LABEL_ICON INTEGER,
|
|
||||||
$COLUMN_LAT DOUBLE,
|
|
||||||
$COLUMN_LONG DOUBLE,
|
|
||||||
$COLUMN_IMAGE_URL STRING,
|
|
||||||
$COLUMN_WIKIPEDIA_LINK STRING,
|
|
||||||
$COLUMN_WIKIDATA_LINK STRING,
|
|
||||||
$COLUMN_COMMONS_LINK STRING,
|
|
||||||
$COLUMN_PIC STRING,
|
|
||||||
$COLUMN_EXISTS STRING
|
|
||||||
);
|
|
||||||
"""
|
|
||||||
|
|
||||||
fun onCreate(db: SQLiteDatabase) {
|
|
||||||
db.execSQL(CREATE_TABLE_STATEMENT)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun onDelete(db: SQLiteDatabase) {
|
|
||||||
db.execSQL(DROP_TABLE_STATEMENT)
|
|
||||||
onCreate(db)
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressLint("SQLiteString")
|
|
||||||
fun onUpdate(db: SQLiteDatabase, from: Int, to: Int) {
|
|
||||||
Timber.d("bookmarksLocations db is updated from:$from, to:$to")
|
|
||||||
var currFrom = from
|
|
||||||
|
|
||||||
if (from == to) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (from < 7) {
|
|
||||||
onUpdate(db, ++currFrom, to)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (from == 7) {
|
|
||||||
onCreate(db)
|
|
||||||
onUpdate(db, ++currFrom, to)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (from < 10) {
|
|
||||||
onUpdate(db, ++currFrom, to)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (from == 10) {
|
|
||||||
try {
|
|
||||||
db.execSQL("ALTER TABLE $TABLE_NAME ADD COLUMN location_pic STRING;")
|
|
||||||
} catch (exception: SQLiteException) {
|
|
||||||
Timber.e(exception)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (from >= 12) {
|
|
||||||
try {
|
|
||||||
db.execSQL("ALTER TABLE $TABLE_NAME ADD COLUMN location_destroyed STRING;")
|
|
||||||
} catch (exception: SQLiteException) {
|
|
||||||
Timber.e(exception)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (from >= 13) {
|
|
||||||
try {
|
|
||||||
db.execSQL("ALTER TABLE $TABLE_NAME ADD COLUMN location_language STRING;")
|
|
||||||
} catch (exception: SQLiteException) {
|
|
||||||
Timber.e(exception)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (from >= 14) {
|
|
||||||
try {
|
|
||||||
db.execSQL("ALTER TABLE $TABLE_NAME ADD COLUMN location_exists STRING;")
|
|
||||||
} catch (exception: SQLiteException) {
|
|
||||||
Timber.e(exception)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ import android.view.ViewGroup
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
|
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
|
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import dagger.android.support.DaggerFragment
|
import dagger.android.support.DaggerFragment
|
||||||
import fr.free.nrw.commons.R
|
import fr.free.nrw.commons.R
|
||||||
|
|
@ -108,6 +109,7 @@ class BookmarkLocationsFragment : DaggerFragment() {
|
||||||
|
|
||||||
adapter = PlaceAdapter(
|
adapter = PlaceAdapter(
|
||||||
bookmarkLocationDao,
|
bookmarkLocationDao,
|
||||||
|
scope = lifecycleScope,
|
||||||
{ },
|
{ },
|
||||||
{ place, _ ->
|
{ place, _ ->
|
||||||
adapter.remove(place)
|
adapter.remove(place)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
package fr.free.nrw.commons.bookmarks.locations
|
||||||
|
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import fr.free.nrw.commons.nearby.Place
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
|
class BookmarkLocationsViewModel(
|
||||||
|
private val bookmarkLocationsDao: BookmarkLocationsDao
|
||||||
|
): ViewModel() {
|
||||||
|
|
||||||
|
fun getAllBookmarkLocations(): Flow<List<Place>> {
|
||||||
|
return bookmarkLocationsDao.getAllBookmarksLocationsPlace()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
package fr.free.nrw.commons.bookmarks.locations
|
||||||
|
|
||||||
|
import androidx.room.ColumnInfo
|
||||||
|
import androidx.room.Entity
|
||||||
|
import androidx.room.PrimaryKey
|
||||||
|
import fr.free.nrw.commons.location.LatLng
|
||||||
|
import fr.free.nrw.commons.nearby.Label
|
||||||
|
import fr.free.nrw.commons.nearby.Place
|
||||||
|
import fr.free.nrw.commons.nearby.Sitelinks
|
||||||
|
|
||||||
|
@Entity(tableName = "bookmarks_locations")
|
||||||
|
data class BookmarksLocations(
|
||||||
|
@PrimaryKey @ColumnInfo(name = "location_name") val locationName: String,
|
||||||
|
@ColumnInfo(name = "location_language") val locationLanguage: String,
|
||||||
|
@ColumnInfo(name = "location_description") val locationDescription: String,
|
||||||
|
@ColumnInfo(name = "location_lat") val locationLat: Double,
|
||||||
|
@ColumnInfo(name = "location_long") val locationLong: Double,
|
||||||
|
@ColumnInfo(name = "location_category") val locationCategory: String,
|
||||||
|
@ColumnInfo(name = "location_label_text") val locationLabelText: String,
|
||||||
|
@ColumnInfo(name = "location_label_icon") val locationLabelIcon: Int?,
|
||||||
|
@ColumnInfo(name = "location_image_url") val locationImageUrl: String,
|
||||||
|
@ColumnInfo(name = "location_wikipedia_link") val locationWikipediaLink: String,
|
||||||
|
@ColumnInfo(name = "location_wikidata_link") val locationWikidataLink: String,
|
||||||
|
@ColumnInfo(name = "location_commons_link") val locationCommonsLink: String,
|
||||||
|
@ColumnInfo(name = "location_pic") val locationPic: String,
|
||||||
|
@ColumnInfo(name = "location_exists") val locationExists: Boolean
|
||||||
|
)
|
||||||
|
|
||||||
|
fun BookmarksLocations.toPlace(): Place {
|
||||||
|
val location = LatLng(
|
||||||
|
locationLat,
|
||||||
|
locationLong,
|
||||||
|
1F
|
||||||
|
)
|
||||||
|
|
||||||
|
val builder = Sitelinks.Builder().apply {
|
||||||
|
setWikipediaLink(locationWikipediaLink)
|
||||||
|
setWikidataLink(locationWikidataLink)
|
||||||
|
setCommonsLink(locationCommonsLink)
|
||||||
|
}
|
||||||
|
|
||||||
|
return Place(
|
||||||
|
locationLanguage,
|
||||||
|
locationName,
|
||||||
|
Label.fromText(locationLabelText),
|
||||||
|
locationDescription,
|
||||||
|
location,
|
||||||
|
locationCategory,
|
||||||
|
builder.build(),
|
||||||
|
locationPic,
|
||||||
|
locationExists
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Place.toBookmarksLocations(): BookmarksLocations {
|
||||||
|
return BookmarksLocations(
|
||||||
|
locationName = name,
|
||||||
|
locationLanguage = language,
|
||||||
|
locationDescription = longDescription,
|
||||||
|
locationCategory = category,
|
||||||
|
locationLat = location.latitude,
|
||||||
|
locationLong = location.longitude,
|
||||||
|
locationLabelText = label?.text ?: "",
|
||||||
|
locationLabelIcon = label?.icon,
|
||||||
|
locationImageUrl = pic,
|
||||||
|
locationWikipediaLink = siteLinks.wikipediaLink.toString(),
|
||||||
|
locationWikidataLink = siteLinks.wikidataLink.toString(),
|
||||||
|
locationCommonsLink = siteLinks.commonsLink.toString(),
|
||||||
|
locationPic = pic,
|
||||||
|
locationExists = exists
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
@ -30,7 +30,6 @@ class DBOpenHelper(
|
||||||
override fun onCreate(db: SQLiteDatabase) {
|
override fun onCreate(db: SQLiteDatabase) {
|
||||||
CategoryDao.Table.onCreate(db)
|
CategoryDao.Table.onCreate(db)
|
||||||
BookmarkPicturesDao.Table.onCreate(db)
|
BookmarkPicturesDao.Table.onCreate(db)
|
||||||
BookmarkLocationsDao.Table.onCreate(db)
|
|
||||||
BookmarkItemsDao.Table.onCreate(db)
|
BookmarkItemsDao.Table.onCreate(db)
|
||||||
RecentSearchesDao.Table.onCreate(db)
|
RecentSearchesDao.Table.onCreate(db)
|
||||||
RecentLanguagesDao.Table.onCreate(db)
|
RecentLanguagesDao.Table.onCreate(db)
|
||||||
|
|
@ -39,7 +38,6 @@ class DBOpenHelper(
|
||||||
override fun onUpgrade(db: SQLiteDatabase, from: Int, to: Int) {
|
override fun onUpgrade(db: SQLiteDatabase, from: Int, to: Int) {
|
||||||
CategoryDao.Table.onUpdate(db, from, to)
|
CategoryDao.Table.onUpdate(db, from, to)
|
||||||
BookmarkPicturesDao.Table.onUpdate(db, from, to)
|
BookmarkPicturesDao.Table.onUpdate(db, from, to)
|
||||||
BookmarkLocationsDao.Table.onUpdate(db, from, to)
|
|
||||||
BookmarkItemsDao.Table.onUpdate(db, from, to)
|
BookmarkItemsDao.Table.onUpdate(db, from, to)
|
||||||
RecentSearchesDao.Table.onUpdate(db, from, to)
|
RecentSearchesDao.Table.onUpdate(db, from, to)
|
||||||
RecentLanguagesDao.Table.onUpdate(db, from, to)
|
RecentLanguagesDao.Table.onUpdate(db, from, to)
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,8 @@ import androidx.room.RoomDatabase
|
||||||
import androidx.room.TypeConverters
|
import androidx.room.TypeConverters
|
||||||
import fr.free.nrw.commons.bookmarks.category.BookmarkCategoriesDao
|
import fr.free.nrw.commons.bookmarks.category.BookmarkCategoriesDao
|
||||||
import fr.free.nrw.commons.bookmarks.category.BookmarksCategoryModal
|
import fr.free.nrw.commons.bookmarks.category.BookmarksCategoryModal
|
||||||
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao
|
||||||
|
import fr.free.nrw.commons.bookmarks.locations.BookmarksLocations
|
||||||
import fr.free.nrw.commons.contributions.Contribution
|
import fr.free.nrw.commons.contributions.Contribution
|
||||||
import fr.free.nrw.commons.contributions.ContributionDao
|
import fr.free.nrw.commons.contributions.ContributionDao
|
||||||
import fr.free.nrw.commons.customselector.database.NotForUploadStatus
|
import fr.free.nrw.commons.customselector.database.NotForUploadStatus
|
||||||
|
|
@ -23,7 +25,7 @@ import fr.free.nrw.commons.upload.depicts.DepictsDao
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Database(
|
@Database(
|
||||||
entities = [Contribution::class, Depicts::class, UploadedStatus::class, NotForUploadStatus::class, ReviewEntity::class, Place::class, BookmarksCategoryModal::class],
|
entities = [Contribution::class, Depicts::class, UploadedStatus::class, NotForUploadStatus::class, ReviewEntity::class, Place::class, BookmarksCategoryModal::class, BookmarksLocations::class],
|
||||||
version = 19,
|
version = 19,
|
||||||
exportSchema = false,
|
exportSchema = false,
|
||||||
)
|
)
|
||||||
|
|
@ -42,4 +44,6 @@ abstract class AppDatabase : RoomDatabase() {
|
||||||
abstract fun ReviewDao(): ReviewDao
|
abstract fun ReviewDao(): ReviewDao
|
||||||
|
|
||||||
abstract fun bookmarkCategoriesDao(): BookmarkCategoriesDao
|
abstract fun bookmarkCategoriesDao(): BookmarkCategoriesDao
|
||||||
|
|
||||||
|
abstract fun bookmarkLocationsDao(): BookmarkLocationsDao
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import fr.free.nrw.commons.BuildConfig
|
||||||
import fr.free.nrw.commons.R
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.auth.SessionManager
|
import fr.free.nrw.commons.auth.SessionManager
|
||||||
import fr.free.nrw.commons.bookmarks.category.BookmarkCategoriesDao
|
import fr.free.nrw.commons.bookmarks.category.BookmarkCategoriesDao
|
||||||
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao
|
||||||
import fr.free.nrw.commons.contributions.ContributionDao
|
import fr.free.nrw.commons.contributions.ContributionDao
|
||||||
import fr.free.nrw.commons.customselector.database.NotForUploadStatusDao
|
import fr.free.nrw.commons.customselector.database.NotForUploadStatusDao
|
||||||
import fr.free.nrw.commons.customselector.database.UploadedStatusDao
|
import fr.free.nrw.commons.customselector.database.UploadedStatusDao
|
||||||
|
|
@ -206,6 +207,10 @@ open class CommonsApplicationModule(private val applicationContext: Context) {
|
||||||
fun providesPlaceDao(appDatabase: AppDatabase): PlaceDao =
|
fun providesPlaceDao(appDatabase: AppDatabase): PlaceDao =
|
||||||
appDatabase.PlaceDao()
|
appDatabase.PlaceDao()
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
fun providesBookmarkLocationsDao(appDatabase: AppDatabase): BookmarkLocationsDao =
|
||||||
|
appDatabase.bookmarkLocationsDao()
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
fun providesDepictDao(appDatabase: AppDatabase): DepictsDao =
|
fun providesDepictDao(appDatabase: AppDatabase): DepictsDao =
|
||||||
appDatabase.DepictsDao()
|
appDatabase.DepictsDao()
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package fr.free.nrw.commons.di
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.android.ContributesAndroidInjector
|
import dagger.android.ContributesAndroidInjector
|
||||||
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsContentProvider
|
import fr.free.nrw.commons.bookmarks.items.BookmarkItemsContentProvider
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsContentProvider
|
|
||||||
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesContentProvider
|
import fr.free.nrw.commons.bookmarks.pictures.BookmarkPicturesContentProvider
|
||||||
import fr.free.nrw.commons.category.CategoryContentProvider
|
import fr.free.nrw.commons.category.CategoryContentProvider
|
||||||
import fr.free.nrw.commons.explore.recentsearches.RecentSearchesContentProvider
|
import fr.free.nrw.commons.explore.recentsearches.RecentSearchesContentProvider
|
||||||
|
|
@ -26,9 +25,6 @@ abstract class ContentProviderBuilderModule {
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindBookmarkContentProvider(): BookmarkPicturesContentProvider
|
abstract fun bindBookmarkContentProvider(): BookmarkPicturesContentProvider
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
|
||||||
abstract fun bindBookmarkLocationContentProvider(): BookmarkLocationsContentProvider
|
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindBookmarkItemContentProvider(): BookmarkItemsContentProvider
|
abstract fun bindBookmarkItemContentProvider(): BookmarkItemsContentProvider
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -101,6 +101,9 @@ abstract class FragmentBuilderModule {
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindBookmarkCategoriesListFragment(): BookmarkCategoriesFragment
|
abstract fun bindBookmarkCategoriesListFragment(): BookmarkCategoriesFragment
|
||||||
|
|
||||||
|
@ContributesAndroidInjector
|
||||||
|
abstract fun bindBookmarkLocationsListFragment(): BookmarkLocationsFragment
|
||||||
|
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun bindReviewOutOfContextFragment(): ReviewImageFragment
|
abstract fun bindReviewOutOfContextFragment(): ReviewImageFragment
|
||||||
|
|
||||||
|
|
|
||||||
22
app/src/main/java/fr/free/nrw/commons/nearby/NearbyUtil.kt
Normal file
22
app/src/main/java/fr/free/nrw/commons/nearby/NearbyUtil.kt
Normal file
|
|
@ -0,0 +1,22 @@
|
||||||
|
package fr.free.nrw.commons.nearby
|
||||||
|
|
||||||
|
import androidx.lifecycle.LifecycleCoroutineScope
|
||||||
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao
|
||||||
|
import fr.free.nrw.commons.bookmarks.locations.BookmarksLocations
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
object NearbyUtil {
|
||||||
|
|
||||||
|
fun getBookmarkLocationExists(
|
||||||
|
bookmarksLocationsDao: BookmarkLocationsDao,
|
||||||
|
name: String,
|
||||||
|
scope: LifecycleCoroutineScope?
|
||||||
|
): Boolean {
|
||||||
|
var isBookmarked = false
|
||||||
|
scope?.launch {
|
||||||
|
isBookmarked = bookmarksLocationsDao.findBookmarkLocation(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return isBookmarked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@ import android.view.View.INVISIBLE
|
||||||
import android.view.View.VISIBLE
|
import android.view.View.VISIBLE
|
||||||
import android.widget.RelativeLayout
|
import android.widget.RelativeLayout
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import androidx.lifecycle.LifecycleCoroutineScope
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import androidx.transition.TransitionManager
|
import androidx.transition.TransitionManager
|
||||||
|
|
@ -16,9 +17,11 @@ import com.hannesdorfmann.adapterdelegates4.dsl.adapterDelegateViewBinding
|
||||||
import fr.free.nrw.commons.R
|
import fr.free.nrw.commons.R
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao
|
||||||
import fr.free.nrw.commons.databinding.ItemPlaceBinding
|
import fr.free.nrw.commons.databinding.ItemPlaceBinding
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
fun placeAdapterDelegate(
|
fun placeAdapterDelegate(
|
||||||
bookmarkLocationDao: BookmarkLocationsDao,
|
bookmarkLocationDao: BookmarkLocationsDao,
|
||||||
|
scope: LifecycleCoroutineScope?,
|
||||||
onItemClick: ((Place) -> Unit)? = null,
|
onItemClick: ((Place) -> Unit)? = null,
|
||||||
onCameraClicked: (Place, ActivityResultLauncher<Array<String>>, ActivityResultLauncher<Intent>) -> Unit,
|
onCameraClicked: (Place, ActivityResultLauncher<Array<String>>, ActivityResultLauncher<Intent>) -> Unit,
|
||||||
onCameraLongPressed: () -> Boolean,
|
onCameraLongPressed: () -> Boolean,
|
||||||
|
|
@ -61,7 +64,10 @@ fun placeAdapterDelegate(
|
||||||
nearbyButtonLayout.galleryButton.setOnClickListener { onGalleryClicked(item, galleryPickLauncherForResult) }
|
nearbyButtonLayout.galleryButton.setOnClickListener { onGalleryClicked(item, galleryPickLauncherForResult) }
|
||||||
nearbyButtonLayout.galleryButton.setOnLongClickListener { onGalleryLongPressed() }
|
nearbyButtonLayout.galleryButton.setOnLongClickListener { onGalleryLongPressed() }
|
||||||
bookmarkButtonImage.setOnClickListener {
|
bookmarkButtonImage.setOnClickListener {
|
||||||
val isBookmarked = bookmarkLocationDao.updateBookmarkLocation(item)
|
var isBookmarked = false
|
||||||
|
scope?.launch {
|
||||||
|
isBookmarked = bookmarkLocationDao.updateBookmarkLocation(item)
|
||||||
|
}
|
||||||
bookmarkButtonImage.setImageResource(
|
bookmarkButtonImage.setImageResource(
|
||||||
if (isBookmarked) R.drawable.ic_round_star_filled_24px else R.drawable.ic_round_star_border_24px,
|
if (isBookmarked) R.drawable.ic_round_star_filled_24px else R.drawable.ic_round_star_border_24px,
|
||||||
)
|
)
|
||||||
|
|
@ -93,14 +99,16 @@ fun placeAdapterDelegate(
|
||||||
GONE
|
GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scope?.launch {
|
||||||
bookmarkButtonImage.setImageResource(
|
bookmarkButtonImage.setImageResource(
|
||||||
if (bookmarkLocationDao.findBookmarkLocation(item)) {
|
if (bookmarkLocationDao.findBookmarkLocation(item.name)) {
|
||||||
R.drawable.ic_round_star_filled_24px
|
R.drawable.ic_round_star_filled_24px
|
||||||
} else {
|
} else {
|
||||||
R.drawable.ic_round_star_border_24px
|
R.drawable.ic_round_star_border_24px
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
nearbyButtonLayout.directionsButton.setOnLongClickListener { onDirectionsLongPressed() }
|
nearbyButtonLayout.directionsButton.setOnLongClickListener { onDirectionsLongPressed() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -134,7 +134,7 @@ public interface NearbyParentFragmentContract {
|
||||||
|
|
||||||
void setAdvancedQuery(String query);
|
void setAdvancedQuery(String query);
|
||||||
|
|
||||||
void toggleBookmarkedStatus(Place place);
|
void toggleBookmarkedStatus(Place place, LifecycleCoroutineScope scope);
|
||||||
|
|
||||||
void handleMapScrolled(LifecycleCoroutineScope scope, boolean isNetworkAvailable);
|
void handleMapScrolled(LifecycleCoroutineScope scope, boolean isNetworkAvailable);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package fr.free.nrw.commons.nearby.fragments
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
|
import androidx.lifecycle.LifecycleCoroutineScope
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao
|
||||||
import fr.free.nrw.commons.nearby.Place
|
import fr.free.nrw.commons.nearby.Place
|
||||||
import fr.free.nrw.commons.nearby.placeAdapterDelegate
|
import fr.free.nrw.commons.nearby.placeAdapterDelegate
|
||||||
|
|
@ -9,6 +10,7 @@ import fr.free.nrw.commons.upload.categories.BaseDelegateAdapter
|
||||||
|
|
||||||
class PlaceAdapter(
|
class PlaceAdapter(
|
||||||
bookmarkLocationsDao: BookmarkLocationsDao,
|
bookmarkLocationsDao: BookmarkLocationsDao,
|
||||||
|
scope: LifecycleCoroutineScope? = null,
|
||||||
onPlaceClicked: ((Place) -> Unit)? = null,
|
onPlaceClicked: ((Place) -> Unit)? = null,
|
||||||
onBookmarkClicked: (Place, Boolean) -> Unit,
|
onBookmarkClicked: (Place, Boolean) -> Unit,
|
||||||
commonPlaceClickActions: CommonPlaceClickActions,
|
commonPlaceClickActions: CommonPlaceClickActions,
|
||||||
|
|
@ -18,6 +20,7 @@ class PlaceAdapter(
|
||||||
) : BaseDelegateAdapter<Place>(
|
) : BaseDelegateAdapter<Place>(
|
||||||
placeAdapterDelegate(
|
placeAdapterDelegate(
|
||||||
bookmarkLocationsDao,
|
bookmarkLocationsDao,
|
||||||
|
scope,
|
||||||
onPlaceClicked,
|
onPlaceClicked,
|
||||||
commonPlaceClickActions.onCameraClicked(),
|
commonPlaceClickActions.onCameraClicked(),
|
||||||
commonPlaceClickActions.onCameraLongPressed(),
|
commonPlaceClickActions.onCameraLongPressed(),
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.ensureActive
|
import kotlinx.coroutines.ensureActive
|
||||||
import kotlinx.coroutines.job
|
import kotlinx.coroutines.job
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import okhttp3.internal.wait
|
import okhttp3.internal.wait
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
@ -136,16 +137,25 @@ class NearbyParentFragmentPresenter
|
||||||
* @param place The place whose bookmarked status is to be toggled. If the place is `null`,
|
* @param place The place whose bookmarked status is to be toggled. If the place is `null`,
|
||||||
* the operation is skipped.
|
* the operation is skipped.
|
||||||
*/
|
*/
|
||||||
override fun toggleBookmarkedStatus(place: Place?) {
|
override fun toggleBookmarkedStatus(
|
||||||
|
place: Place?,
|
||||||
|
scope: LifecycleCoroutineScope?
|
||||||
|
) {
|
||||||
if (place == null) return
|
if (place == null) return
|
||||||
val nowBookmarked = bookmarkLocationDao.updateBookmarkLocation(place)
|
var nowBookmarked: Boolean? = null
|
||||||
|
scope?.launch {
|
||||||
|
nowBookmarked = bookmarkLocationDao.updateBookmarkLocation(place)
|
||||||
|
|
||||||
|
}
|
||||||
bookmarkChangedPlaces.add(place)
|
bookmarkChangedPlaces.add(place)
|
||||||
val placeIndex =
|
val placeIndex =
|
||||||
NearbyController.markerLabelList.indexOfFirst { it.place.location == place.location }
|
NearbyController.markerLabelList.indexOfFirst { it.place.location == place.location }
|
||||||
NearbyController.markerLabelList[placeIndex] = MarkerPlaceGroup(
|
NearbyController.markerLabelList[placeIndex] = nowBookmarked?.let {
|
||||||
nowBookmarked,
|
MarkerPlaceGroup(
|
||||||
|
it,
|
||||||
NearbyController.markerLabelList[placeIndex].place
|
NearbyController.markerLabelList[placeIndex].place
|
||||||
)
|
)
|
||||||
|
}
|
||||||
nearbyParentFragmentView.setFilterState()
|
nearbyParentFragmentView.setFilterState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -337,7 +347,7 @@ class NearbyParentFragmentPresenter
|
||||||
for (i in 0..updatedGroups.lastIndex) {
|
for (i in 0..updatedGroups.lastIndex) {
|
||||||
val repoPlace = placesRepository.fetchPlace(updatedGroups[i].place.entityID)
|
val repoPlace = placesRepository.fetchPlace(updatedGroups[i].place.entityID)
|
||||||
if (repoPlace != null && repoPlace.name != null && repoPlace.name != ""){
|
if (repoPlace != null && repoPlace.name != null && repoPlace.name != ""){
|
||||||
updatedGroups[i].isBookmarked = bookmarkLocationDao.findBookmarkLocation(repoPlace)
|
updatedGroups[i].isBookmarked = bookmarkLocationDao.findBookmarkLocation(repoPlace.name)
|
||||||
updatedGroups[i].place.apply {
|
updatedGroups[i].place.apply {
|
||||||
name = repoPlace.name
|
name = repoPlace.name
|
||||||
isMonument = repoPlace.isMonument
|
isMonument = repoPlace.isMonument
|
||||||
|
|
@ -375,7 +385,7 @@ class NearbyParentFragmentPresenter
|
||||||
collectResults.send(
|
collectResults.send(
|
||||||
fetchedPlaces.mapIndexed { index, place ->
|
fetchedPlaces.mapIndexed { index, place ->
|
||||||
Pair(indices[index], MarkerPlaceGroup(
|
Pair(indices[index], MarkerPlaceGroup(
|
||||||
bookmarkLocationDao.findBookmarkLocation(place),
|
bookmarkLocationDao.findBookmarkLocation(place.name),
|
||||||
place
|
place
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
@ -457,7 +467,7 @@ class NearbyParentFragmentPresenter
|
||||||
if (bookmarkChangedPlacesBacklog.containsKey(group.place.location)) {
|
if (bookmarkChangedPlacesBacklog.containsKey(group.place.location)) {
|
||||||
updatedGroups[index] = MarkerPlaceGroup(
|
updatedGroups[index] = MarkerPlaceGroup(
|
||||||
bookmarkLocationDao
|
bookmarkLocationDao
|
||||||
.findBookmarkLocation(updatedGroups[index].place),
|
.findBookmarkLocation(updatedGroups[index].place.name),
|
||||||
updatedGroups[index].place
|
updatedGroups[index].place
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -565,7 +575,7 @@ class NearbyParentFragmentPresenter
|
||||||
).sortedBy { it.getDistanceInDouble(mapFocus) }.take(NearbyController.MAX_RESULTS)
|
).sortedBy { it.getDistanceInDouble(mapFocus) }.take(NearbyController.MAX_RESULTS)
|
||||||
.map {
|
.map {
|
||||||
MarkerPlaceGroup(
|
MarkerPlaceGroup(
|
||||||
bookmarkLocationDao.findBookmarkLocation(it), it
|
bookmarkLocationDao.findBookmarkLocation(it.name), it
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
ensureActive()
|
ensureActive()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue