mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-26 20:33:53 +01:00
Refactor: Migrate bookmark location logic to Kotlin
This commit migrates the bookmark location logic to Kotlin, enhancing code maintainability and readability. - Removes the `BookmarkLocationsContentProvider`, `BookmarkLocationsController`, and `BookmarkLocationsDao` Java classes. - Creates `BookmarkLocationsDao.kt` and `BookmarkLocationsContentProvider.kt` in Kotlin. - Migrates the logic from `BookmarkLocationsFragment.java` to `BookmarkLocationsFragment.kt`. - Updates test files to reflect these changes. - Addresses associated code review comments.
This commit is contained in:
parent
f191dcf68f
commit
f32c59034d
7 changed files with 423 additions and 445 deletions
|
|
@ -1,119 +1,126 @@
|
||||||
package fr.free.nrw.commons.bookmarks.locations;
|
package fr.free.nrw.commons.bookmarks.locations
|
||||||
|
|
||||||
import android.content.ContentValues;
|
// We can get uri using java.Net.Uri, but android implementation is faster
|
||||||
import android.database.Cursor;
|
// (but it's forgiving with handling exceptions though)
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.content.ContentValues
|
||||||
import android.database.sqlite.SQLiteQueryBuilder;
|
import android.database.Cursor
|
||||||
// We can get uri using java.Net.Uri, but andoid implimentation is faster (but it's forgiving with handling exceptions though)
|
import android.database.sqlite.SQLiteQueryBuilder
|
||||||
import android.net.Uri;
|
import android.net.Uri
|
||||||
import android.text.TextUtils;
|
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
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.BuildConfig;
|
|
||||||
import fr.free.nrw.commons.data.DBOpenHelper;
|
|
||||||
import fr.free.nrw.commons.di.CommonsDaggerContentProvider;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
import static fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao.Table.COLUMN_NAME;
|
|
||||||
import static fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao.Table.TABLE_NAME;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles private storage for Bookmark locations
|
* Handles private storage for Bookmark locations
|
||||||
*/
|
*/
|
||||||
public class BookmarkLocationsContentProvider extends CommonsDaggerContentProvider {
|
class BookmarkLocationsContentProvider : CommonsDaggerContentProvider() {
|
||||||
|
|
||||||
private static final String BASE_PATH = "bookmarksLocations";
|
companion object {
|
||||||
public static final Uri BASE_URI = Uri.parse("content://" + BuildConfig.BOOKMARK_LOCATIONS_AUTHORITY + "/" + BASE_PATH);
|
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
|
* Append bookmark locations name to the base URI.
|
||||||
*/
|
*/
|
||||||
public static Uri uriForName(String name) {
|
fun uriForName(name: String): Uri {
|
||||||
return Uri.parse(BASE_URI.toString() + "/" + name);
|
return Uri.parse("$BASE_URI/$name")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject DBOpenHelper dbOpenHelper;
|
@Inject
|
||||||
|
lateinit var dbOpenHelper: DBOpenHelper
|
||||||
|
|
||||||
@Override
|
override fun getType(uri: Uri): String? = null
|
||||||
public String getType(@NonNull Uri uri) {
|
|
||||||
return 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
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Queries the SQLite database for the bookmark locations
|
* Handles the update query of local SQLite database.
|
||||||
* @param uri : contains the uri for bookmark locations
|
|
||||||
* @param projection
|
|
||||||
* @param selection : handles Where
|
|
||||||
* @param selectionArgs : the condition of Where clause
|
|
||||||
* @param sortOrder : ascending or descending
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("ConstantConditions")
|
override fun update(
|
||||||
@Override
|
uri: Uri,
|
||||||
public Cursor query(@NonNull Uri uri, String[] projection, String selection,
|
contentValues: ContentValues?,
|
||||||
String[] selectionArgs, String sortOrder) {
|
selection: String?,
|
||||||
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
|
selectionArgs: Array<String>?
|
||||||
queryBuilder.setTables(TABLE_NAME);
|
): Int {
|
||||||
|
val db = dbOpenHelper.writableDatabase
|
||||||
|
val rowsUpdated: Int
|
||||||
|
|
||||||
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
|
if (selection.isNullOrEmpty()) {
|
||||||
Cursor cursor = queryBuilder.query(db, projection, selection, selectionArgs, null, null, sortOrder);
|
val id = uri.lastPathSegment?.toIntOrNull()
|
||||||
cursor.setNotificationUri(getContext().getContentResolver(), uri);
|
?: throw IllegalArgumentException("Invalid ID in URI")
|
||||||
|
rowsUpdated = db.update(
|
||||||
return cursor;
|
TABLE_NAME,
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the update query of local SQLite Database
|
|
||||||
* @param uri : contains the uri for bookmark locations
|
|
||||||
* @param contentValues : new values to be entered to db
|
|
||||||
* @param selection : handles Where
|
|
||||||
* @param selectionArgs : the condition of Where clause
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
|
||||||
@Override
|
|
||||||
public int update(@NonNull Uri uri, ContentValues contentValues, String selection,
|
|
||||||
String[] selectionArgs) {
|
|
||||||
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
|
|
||||||
int rowsUpdated;
|
|
||||||
if (TextUtils.isEmpty(selection)) {
|
|
||||||
int id = Integer.valueOf(uri.getLastPathSegment());
|
|
||||||
rowsUpdated = sqlDB.update(TABLE_NAME,
|
|
||||||
contentValues,
|
contentValues,
|
||||||
COLUMN_NAME + " = ?",
|
"$COLUMN_NAME = ?",
|
||||||
new String[]{String.valueOf(id)});
|
arrayOf(id.toString())
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException(
|
throw IllegalArgumentException(
|
||||||
"Parameter `selection` should be empty when updating an ID");
|
"Parameter `selection` should be empty when updating an ID"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
getContext().getContentResolver().notifyChange(uri, null);
|
|
||||||
return rowsUpdated;
|
context?.contentResolver?.notifyChange(uri, null)
|
||||||
|
return rowsUpdated
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles the insertion of new bookmark locations record to local SQLite Database
|
* Handles the insertion of a new bookmark locations record to the local SQLite database.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("ConstantConditions")
|
override fun insert(uri: Uri, contentValues: ContentValues?): Uri {
|
||||||
@Override
|
val db = dbOpenHelper.writableDatabase
|
||||||
public Uri insert(@NonNull Uri uri, ContentValues contentValues) {
|
val id = db.insert(TABLE_NAME, null, contentValues)
|
||||||
SQLiteDatabase sqlDB = dbOpenHelper.getWritableDatabase();
|
context?.contentResolver?.notifyChange(uri, null)
|
||||||
long id = sqlDB.insert(BookmarkLocationsDao.Table.TABLE_NAME, null, contentValues);
|
return Uri.parse("$BASE_URI/$id")
|
||||||
getContext().getContentResolver().notifyChange(uri, null);
|
|
||||||
return Uri.parse(BASE_URI + "/" + id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("ConstantConditions")
|
/**
|
||||||
@Override
|
* Handles the deletion of bookmark locations from the local SQLite database.
|
||||||
public int delete(@NonNull Uri uri, String s, String[] strings) {
|
*/
|
||||||
int rows;
|
override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
|
||||||
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
|
val db = dbOpenHelper.readableDatabase
|
||||||
Timber.d("Deleting bookmark name %s", uri.getLastPathSegment());
|
Timber.d("Deleting bookmark name %s", uri.lastPathSegment)
|
||||||
rows = db.delete(TABLE_NAME,
|
|
||||||
|
val rows = db.delete(
|
||||||
|
TABLE_NAME,
|
||||||
"location_name = ?",
|
"location_name = ?",
|
||||||
new String[]{uri.getLastPathSegment()}
|
arrayOf(uri.lastPathSegment)
|
||||||
);
|
)
|
||||||
getContext().getContentResolver().notifyChange(uri, null);
|
|
||||||
return rows;
|
context?.contentResolver?.notifyChange(uri, null)
|
||||||
|
return rows
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,26 +1,17 @@
|
||||||
package fr.free.nrw.commons.bookmarks.locations;
|
package fr.free.nrw.commons.bookmarks.locations
|
||||||
|
|
||||||
import java.util.List;
|
import fr.free.nrw.commons.nearby.Place
|
||||||
|
import javax.inject.Inject
|
||||||
import javax.inject.Inject;
|
import javax.inject.Singleton
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import fr.free.nrw.commons.nearby.Place;
|
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
public class BookmarkLocationsController {
|
class BookmarkLocationsController @Inject constructor(
|
||||||
|
private val bookmarkLocationDao: BookmarkLocationsDao
|
||||||
@Inject
|
) {
|
||||||
BookmarkLocationsDao bookmarkLocationDao;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public BookmarkLocationsController() {}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load from DB the bookmarked locations
|
* Load bookmarked locations from the database.
|
||||||
* @return a list of Place objects.
|
* @return a list of Place objects.
|
||||||
*/
|
*/
|
||||||
public List<Place> loadFavoritesLocations() {
|
fun loadFavoritesLocations(): List<Place> = bookmarkLocationDao.getAllBookmarksLocations()
|
||||||
return bookmarkLocationDao.getAllBookmarksLocations();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,311 +1,284 @@
|
||||||
package fr.free.nrw.commons.bookmarks.locations;
|
package fr.free.nrw.commons.bookmarks.locations
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
|
||||||
import android.content.ContentProviderClient;
|
|
||||||
import android.content.ContentValues;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
|
||||||
import android.database.sqlite.SQLiteException;
|
|
||||||
import android.os.RemoteException;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.ContentProviderClient
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.database.Cursor
|
||||||
|
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.Place
|
||||||
|
import fr.free.nrw.commons.nearby.Sitelinks
|
||||||
|
import timber.log.Timber
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Named
|
||||||
|
import javax.inject.Provider
|
||||||
|
|
||||||
import fr.free.nrw.commons.nearby.NearbyController;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
class BookmarkLocationsDao @Inject constructor(
|
||||||
import javax.inject.Named;
|
@Named("bookmarksLocation") private val clientProvider: Provider<ContentProviderClient>
|
||||||
import javax.inject.Provider;
|
) {
|
||||||
|
|
||||||
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;
|
|
||||||
import timber.log.Timber;
|
|
||||||
|
|
||||||
import static fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsContentProvider.BASE_URI;
|
|
||||||
|
|
||||||
public class BookmarkLocationsDao {
|
|
||||||
|
|
||||||
private final Provider<ContentProviderClient> clientProvider;
|
|
||||||
|
|
||||||
@Inject
|
|
||||||
public BookmarkLocationsDao(@Named("bookmarksLocation") Provider<ContentProviderClient> clientProvider) {
|
|
||||||
this.clientProvider = clientProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all persisted locations bookmarks on database
|
* Find all persisted location bookmarks in the database
|
||||||
*
|
|
||||||
* @return list of Place
|
* @return list of Place
|
||||||
*/
|
*/
|
||||||
@NonNull
|
fun getAllBookmarksLocations(): List<Place> {
|
||||||
public List<Place> getAllBookmarksLocations() {
|
val items = mutableListOf<Place>()
|
||||||
List<Place> items = new ArrayList<>();
|
var cursor: Cursor? = null
|
||||||
Cursor cursor = null;
|
val db = clientProvider.get()
|
||||||
ContentProviderClient db = clientProvider.get();
|
|
||||||
try {
|
try {
|
||||||
cursor = db.query(
|
cursor = db.query(
|
||||||
BookmarkLocationsContentProvider.BASE_URI,
|
BookmarkLocationsContentProvider.BASE_URI,
|
||||||
Table.ALL_FIELDS,
|
Table.ALL_FIELDS,
|
||||||
null,
|
null,
|
||||||
new String[]{},
|
emptyArray(),
|
||||||
null);
|
null
|
||||||
while (cursor != null && cursor.moveToNext()) {
|
)
|
||||||
items.add(fromCursor(cursor));
|
cursor?.let {
|
||||||
|
while (it.moveToNext()) {
|
||||||
|
items.add(fromCursor(it))
|
||||||
}
|
}
|
||||||
} catch (RemoteException e) {
|
}
|
||||||
throw new RuntimeException(e);
|
} catch (e: RemoteException) {
|
||||||
|
throw RuntimeException(e)
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null) {
|
cursor?.close()
|
||||||
cursor.close();
|
db.release()
|
||||||
}
|
}
|
||||||
db.release();
|
return items
|
||||||
}
|
|
||||||
return items;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look for a place in bookmarks table in order to insert or delete it
|
* Look for a place in bookmarks table in order to insert or delete it
|
||||||
*
|
|
||||||
* @param bookmarkLocation : Place object
|
* @param bookmarkLocation : Place object
|
||||||
* @return is Place now fav ?
|
* @return boolean : is Place now fav ?
|
||||||
*/
|
*/
|
||||||
public boolean updateBookmarkLocation(Place bookmarkLocation) {
|
fun updateBookmarkLocation(bookmarkLocation: Place): Boolean {
|
||||||
boolean bookmarkExists = findBookmarkLocation(bookmarkLocation);
|
val bookmarkExists = findBookmarkLocation(bookmarkLocation)
|
||||||
if (bookmarkExists) {
|
if (bookmarkExists) {
|
||||||
deleteBookmarkLocation(bookmarkLocation);
|
deleteBookmarkLocation(bookmarkLocation)
|
||||||
NearbyController.updateMarkerLabelListBookmark(bookmarkLocation, false);
|
NearbyController.updateMarkerLabelListBookmark(bookmarkLocation, false)
|
||||||
} else {
|
} else {
|
||||||
addBookmarkLocation(bookmarkLocation);
|
addBookmarkLocation(bookmarkLocation)
|
||||||
NearbyController.updateMarkerLabelListBookmark(bookmarkLocation, true);
|
NearbyController.updateMarkerLabelListBookmark(bookmarkLocation, true)
|
||||||
}
|
}
|
||||||
return !bookmarkExists;
|
return !bookmarkExists
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a Place to bookmarks table
|
* Add a Place to bookmarks table
|
||||||
*
|
|
||||||
* @param bookmarkLocation : Place to add
|
* @param bookmarkLocation : Place to add
|
||||||
*/
|
*/
|
||||||
private void addBookmarkLocation(Place bookmarkLocation) {
|
private fun addBookmarkLocation(bookmarkLocation: Place) {
|
||||||
ContentProviderClient db = clientProvider.get();
|
val db = clientProvider.get()
|
||||||
try {
|
try {
|
||||||
db.insert(BASE_URI, toContentValues(bookmarkLocation));
|
db.insert(BookmarkLocationsContentProvider.BASE_URI, toContentValues(bookmarkLocation))
|
||||||
} catch (RemoteException e) {
|
} catch (e: RemoteException) {
|
||||||
throw new RuntimeException(e);
|
throw RuntimeException(e)
|
||||||
} finally {
|
} finally {
|
||||||
db.release();
|
db.release()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete a Place from bookmarks table
|
* Delete a Place from bookmarks table
|
||||||
*
|
|
||||||
* @param bookmarkLocation : Place to delete
|
* @param bookmarkLocation : Place to delete
|
||||||
*/
|
*/
|
||||||
private void deleteBookmarkLocation(Place bookmarkLocation) {
|
private fun deleteBookmarkLocation(bookmarkLocation: Place) {
|
||||||
ContentProviderClient db = clientProvider.get();
|
val db = clientProvider.get()
|
||||||
try {
|
try {
|
||||||
db.delete(BookmarkLocationsContentProvider.uriForName(bookmarkLocation.name), null, null);
|
db.delete(
|
||||||
} catch (RemoteException e) {
|
BookmarkLocationsContentProvider.uriForName(bookmarkLocation.name),
|
||||||
throw new RuntimeException(e);
|
null,
|
||||||
|
null
|
||||||
|
)
|
||||||
|
} catch (e: RemoteException) {
|
||||||
|
throw RuntimeException(e)
|
||||||
} finally {
|
} finally {
|
||||||
db.release();
|
db.release()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a Place from database based on its name
|
* Find a Place from database based on its name
|
||||||
*
|
|
||||||
* @param bookmarkLocation : Place to find
|
* @param bookmarkLocation : Place to find
|
||||||
* @return boolean : is Place in database ?
|
* @return boolean : is Place in database ?
|
||||||
*/
|
*/
|
||||||
public boolean findBookmarkLocation(Place bookmarkLocation) {
|
fun findBookmarkLocation(bookmarkLocation: Place): Boolean {
|
||||||
Cursor cursor = null;
|
var cursor: Cursor? = null
|
||||||
ContentProviderClient db = clientProvider.get();
|
val db = clientProvider.get()
|
||||||
try {
|
try {
|
||||||
cursor = db.query(
|
cursor = db.query(
|
||||||
BookmarkLocationsContentProvider.BASE_URI,
|
BookmarkLocationsContentProvider.BASE_URI,
|
||||||
Table.ALL_FIELDS,
|
Table.ALL_FIELDS,
|
||||||
Table.COLUMN_NAME + "=?",
|
"${Table.COLUMN_NAME}=?",
|
||||||
new String[]{bookmarkLocation.name},
|
arrayOf(bookmarkLocation.name),
|
||||||
null);
|
null
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
)
|
||||||
return true;
|
return cursor?.moveToFirst() == true
|
||||||
}
|
} catch (e: RemoteException) {
|
||||||
} catch (RemoteException e) {
|
throw RuntimeException(e)
|
||||||
// This feels lazy, but to hell with checked exceptions. :)
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null) {
|
cursor?.close()
|
||||||
cursor.close();
|
db.release()
|
||||||
}
|
}
|
||||||
db.release();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("Range")
|
@SuppressLint("Range")
|
||||||
@NonNull
|
@NonNull
|
||||||
Place fromCursor(final Cursor cursor) {
|
fun fromCursor(cursor: Cursor): Place {
|
||||||
final LatLng location = new LatLng(cursor.getDouble(cursor.getColumnIndex(Table.COLUMN_LAT)),
|
val location = LatLng(
|
||||||
cursor.getDouble(cursor.getColumnIndex(Table.COLUMN_LONG)), 1F);
|
cursor.getDouble(cursor.getColumnIndex(Table.COLUMN_LAT)),
|
||||||
|
cursor.getDouble(cursor.getColumnIndex(Table.COLUMN_LONG)),
|
||||||
|
1F
|
||||||
|
)
|
||||||
|
|
||||||
final Sitelinks.Builder builder = new Sitelinks.Builder();
|
val builder = Sitelinks.Builder().apply {
|
||||||
builder.setWikipediaLink(cursor.getString(cursor.getColumnIndex(Table.COLUMN_WIKIPEDIA_LINK)));
|
setWikipediaLink(cursor.getString(cursor.getColumnIndex(Table.COLUMN_WIKIPEDIA_LINK)))
|
||||||
builder.setWikidataLink(cursor.getString(cursor.getColumnIndex(Table.COLUMN_WIKIDATA_LINK)));
|
setWikidataLink(cursor.getString(cursor.getColumnIndex(Table.COLUMN_WIKIDATA_LINK)))
|
||||||
builder.setCommonsLink(cursor.getString(cursor.getColumnIndex(Table.COLUMN_COMMONS_LINK)));
|
setCommonsLink(cursor.getString(cursor.getColumnIndex(Table.COLUMN_COMMONS_LINK)))
|
||||||
|
}
|
||||||
|
|
||||||
return new Place(
|
return Place(
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_LANGUAGE)),
|
cursor.getString(cursor.getColumnIndex(Table.COLUMN_LANGUAGE)),
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_NAME)),
|
cursor.getString(cursor.getColumnIndex(Table.COLUMN_NAME)),
|
||||||
Label.fromText((cursor.getString(cursor.getColumnIndex(Table.COLUMN_LABEL_TEXT)))),
|
Label.fromText(cursor.getString(cursor.getColumnIndex(Table.COLUMN_LABEL_TEXT))),
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_DESCRIPTION)),
|
cursor.getString(cursor.getColumnIndex(Table.COLUMN_DESCRIPTION)),
|
||||||
location,
|
location,
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_CATEGORY)),
|
cursor.getString(cursor.getColumnIndex(Table.COLUMN_CATEGORY)),
|
||||||
builder.build(),
|
builder.build(),
|
||||||
cursor.getString(cursor.getColumnIndex(Table.COLUMN_PIC)),
|
cursor.getString(cursor.getColumnIndex(Table.COLUMN_PIC)),
|
||||||
Boolean.parseBoolean(cursor.getString(cursor.getColumnIndex(Table.COLUMN_EXISTS)))
|
cursor.getString(cursor.getColumnIndex(Table.COLUMN_EXISTS))?.toBoolean() ?: false
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private ContentValues toContentValues(Place bookmarkLocation) {
|
private fun toContentValues(bookmarkLocation: Place): ContentValues {
|
||||||
ContentValues cv = new ContentValues();
|
return ContentValues().apply {
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_NAME, bookmarkLocation.getName());
|
put(Table.COLUMN_NAME, bookmarkLocation.name)
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_LANGUAGE, bookmarkLocation.getLanguage());
|
put(Table.COLUMN_LANGUAGE, bookmarkLocation.language)
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_DESCRIPTION, bookmarkLocation.getLongDescription());
|
put(Table.COLUMN_DESCRIPTION, bookmarkLocation.longDescription)
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_CATEGORY, bookmarkLocation.getCategory());
|
put(Table.COLUMN_CATEGORY, bookmarkLocation.category)
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_LABEL_TEXT, bookmarkLocation.getLabel()!=null ? bookmarkLocation.getLabel().getText() : "");
|
put(Table.COLUMN_LABEL_TEXT, bookmarkLocation.label?.text ?: "")
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_LABEL_ICON, bookmarkLocation.getLabel()!=null ? bookmarkLocation.getLabel().getIcon() : null);
|
put(Table.COLUMN_LABEL_ICON, bookmarkLocation.label?.icon)
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_WIKIPEDIA_LINK, bookmarkLocation.siteLinks.getWikipediaLink().toString());
|
put(Table.COLUMN_WIKIPEDIA_LINK, bookmarkLocation.siteLinks.wikipediaLink.toString())
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_WIKIDATA_LINK, bookmarkLocation.siteLinks.getWikidataLink().toString());
|
put(Table.COLUMN_WIKIDATA_LINK, bookmarkLocation.siteLinks.wikidataLink.toString())
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_COMMONS_LINK, bookmarkLocation.siteLinks.getCommonsLink().toString());
|
put(Table.COLUMN_COMMONS_LINK, bookmarkLocation.siteLinks.commonsLink.toString())
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_LAT, bookmarkLocation.location.getLatitude());
|
put(Table.COLUMN_LAT, bookmarkLocation.location.latitude)
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_LONG, bookmarkLocation.location.getLongitude());
|
put(Table.COLUMN_LONG, bookmarkLocation.location.longitude)
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_PIC, bookmarkLocation.pic);
|
put(Table.COLUMN_PIC, bookmarkLocation.pic)
|
||||||
cv.put(BookmarkLocationsDao.Table.COLUMN_EXISTS, bookmarkLocation.exists.toString());
|
put(Table.COLUMN_EXISTS, bookmarkLocation.exists.toString())
|
||||||
return cv;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Table {
|
object Table {
|
||||||
public static final String TABLE_NAME = "bookmarksLocations";
|
const val TABLE_NAME = "bookmarksLocations"
|
||||||
|
|
||||||
static final String COLUMN_NAME = "location_name";
|
const val COLUMN_NAME = "location_name"
|
||||||
static final String COLUMN_LANGUAGE = "location_language";
|
const val COLUMN_LANGUAGE = "location_language"
|
||||||
static final String COLUMN_DESCRIPTION = "location_description";
|
const val COLUMN_DESCRIPTION = "location_description"
|
||||||
static final String COLUMN_LAT = "location_lat";
|
const val COLUMN_LAT = "location_lat"
|
||||||
static final String COLUMN_LONG = "location_long";
|
const val COLUMN_LONG = "location_long"
|
||||||
static final String COLUMN_CATEGORY = "location_category";
|
const val COLUMN_CATEGORY = "location_category"
|
||||||
static final String COLUMN_LABEL_TEXT = "location_label_text";
|
const val COLUMN_LABEL_TEXT = "location_label_text"
|
||||||
static final String COLUMN_LABEL_ICON = "location_label_icon";
|
const val COLUMN_LABEL_ICON = "location_label_icon"
|
||||||
static final String COLUMN_IMAGE_URL = "location_image_url";
|
const val COLUMN_IMAGE_URL = "location_image_url"
|
||||||
static final String COLUMN_WIKIPEDIA_LINK = "location_wikipedia_link";
|
const val COLUMN_WIKIPEDIA_LINK = "location_wikipedia_link"
|
||||||
static final String COLUMN_WIKIDATA_LINK = "location_wikidata_link";
|
const val COLUMN_WIKIDATA_LINK = "location_wikidata_link"
|
||||||
static final String COLUMN_COMMONS_LINK = "location_commons_link";
|
const val COLUMN_COMMONS_LINK = "location_commons_link"
|
||||||
static final String COLUMN_PIC = "location_pic";
|
const val COLUMN_PIC = "location_pic"
|
||||||
static final String COLUMN_EXISTS = "location_exists";
|
const val COLUMN_EXISTS = "location_exists"
|
||||||
|
|
||||||
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
// NOTE! KEEP IN SAME ORDER AS THEY ARE DEFINED UP THERE. HELPS HARD CODE COLUMN INDICES.
|
||||||
public static final String[] ALL_FIELDS = {
|
val ALL_FIELDS = arrayOf(
|
||||||
COLUMN_NAME,
|
COLUMN_NAME, COLUMN_LANGUAGE, COLUMN_DESCRIPTION, COLUMN_CATEGORY, COLUMN_LABEL_TEXT, COLUMN_LABEL_ICON,
|
||||||
COLUMN_LANGUAGE,
|
COLUMN_LAT, COLUMN_LONG, COLUMN_IMAGE_URL, COLUMN_WIKIPEDIA_LINK, COLUMN_WIKIDATA_LINK, COLUMN_COMMONS_LINK,
|
||||||
COLUMN_DESCRIPTION,
|
COLUMN_PIC, COLUMN_EXISTS
|
||||||
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,
|
|
||||||
};
|
|
||||||
|
|
||||||
static final String DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS " + TABLE_NAME;
|
const val DROP_TABLE_STATEMENT = "DROP TABLE IF EXISTS $TABLE_NAME"
|
||||||
|
|
||||||
static final String CREATE_TABLE_STATEMENT = "CREATE TABLE " + TABLE_NAME + " ("
|
const val CREATE_TABLE_STATEMENT = """
|
||||||
+ COLUMN_NAME + " STRING PRIMARY KEY,"
|
CREATE TABLE $TABLE_NAME (
|
||||||
+ COLUMN_LANGUAGE + " STRING,"
|
$COLUMN_NAME STRING PRIMARY KEY,
|
||||||
+ COLUMN_DESCRIPTION + " STRING,"
|
$COLUMN_LANGUAGE STRING,
|
||||||
+ COLUMN_CATEGORY + " STRING,"
|
$COLUMN_DESCRIPTION STRING,
|
||||||
+ COLUMN_LABEL_TEXT + " STRING,"
|
$COLUMN_CATEGORY STRING,
|
||||||
+ COLUMN_LABEL_ICON + " INTEGER,"
|
$COLUMN_LABEL_TEXT STRING,
|
||||||
+ COLUMN_LAT + " DOUBLE,"
|
$COLUMN_LABEL_ICON INTEGER,
|
||||||
+ COLUMN_LONG + " DOUBLE,"
|
$COLUMN_LAT DOUBLE,
|
||||||
+ COLUMN_IMAGE_URL + " STRING,"
|
$COLUMN_LONG DOUBLE,
|
||||||
+ COLUMN_WIKIPEDIA_LINK + " STRING,"
|
$COLUMN_IMAGE_URL STRING,
|
||||||
+ COLUMN_WIKIDATA_LINK + " STRING,"
|
$COLUMN_WIKIPEDIA_LINK STRING,
|
||||||
+ COLUMN_COMMONS_LINK + " STRING,"
|
$COLUMN_WIKIDATA_LINK STRING,
|
||||||
+ COLUMN_PIC + " STRING,"
|
$COLUMN_COMMONS_LINK STRING,
|
||||||
+ COLUMN_EXISTS + " STRING"
|
$COLUMN_PIC STRING,
|
||||||
+ ");";
|
$COLUMN_EXISTS STRING
|
||||||
|
);
|
||||||
|
"""
|
||||||
|
|
||||||
public static void onCreate(SQLiteDatabase db) {
|
fun onCreate(db: SQLiteDatabase) {
|
||||||
db.execSQL(CREATE_TABLE_STATEMENT);
|
db.execSQL(CREATE_TABLE_STATEMENT)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onDelete(SQLiteDatabase db) {
|
fun onDelete(db: SQLiteDatabase) {
|
||||||
db.execSQL(DROP_TABLE_STATEMENT);
|
db.execSQL(DROP_TABLE_STATEMENT)
|
||||||
onCreate(db);
|
onCreate(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void onUpdate(final SQLiteDatabase db, int from, final int to) {
|
@SuppressLint("SQLiteString")
|
||||||
Timber.d("bookmarksLocations db is updated from:"+from+", to:"+to);
|
fun onUpdate(db: SQLiteDatabase, from: Int, to: Int) {
|
||||||
|
Timber.d("bookmarksLocations db is updated from:$from, to:$to")
|
||||||
|
var currFrom = from
|
||||||
|
|
||||||
if (from == to) {
|
if (from == to) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (from < 7) {
|
if (from < 7) {
|
||||||
// doesn't exist yet
|
onUpdate(db, ++currFrom, to)
|
||||||
from++;
|
return
|
||||||
onUpdate(db, from, to);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (from == 7) {
|
if (from == 7) {
|
||||||
// table added in version 8
|
onCreate(db)
|
||||||
onCreate(db);
|
onUpdate(db, ++currFrom, to)
|
||||||
from++;
|
return
|
||||||
onUpdate(db, from, to);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (from < 10) {
|
if (from < 10) {
|
||||||
from++;
|
onUpdate(db, ++currFrom, to)
|
||||||
onUpdate(db, from, to);
|
return
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
if (from == 10) {
|
if (from == 10) {
|
||||||
//This is safe, and can be called clean, as we/I do not remember the appropriate version for this
|
|
||||||
//We are anyways switching to room, these things won't be necessary then
|
|
||||||
try {
|
try {
|
||||||
db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_pic STRING;");
|
db.execSQL("ALTER TABLE $TABLE_NAME ADD COLUMN location_pic STRING;")
|
||||||
}catch (SQLiteException exception){
|
} catch (exception: SQLiteException) {
|
||||||
Timber.e(exception);//
|
Timber.e(exception)
|
||||||
}
|
}
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
if (from >= 12) {
|
if (from >= 12) {
|
||||||
try {
|
try {
|
||||||
db.execSQL(
|
db.execSQL("ALTER TABLE $TABLE_NAME ADD COLUMN location_destroyed STRING;")
|
||||||
"ALTER TABLE bookmarksLocations ADD COLUMN location_destroyed STRING;");
|
} catch (exception: SQLiteException) {
|
||||||
} catch (SQLiteException exception) {
|
Timber.e(exception)
|
||||||
Timber.e(exception);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (from >= 13) {
|
if (from >= 13) {
|
||||||
try {
|
try {
|
||||||
db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_language STRING;");
|
db.execSQL("ALTER TABLE $TABLE_NAME ADD COLUMN location_language STRING;")
|
||||||
} catch (SQLiteException exception){
|
} catch (exception: SQLiteException) {
|
||||||
Timber.e(exception);
|
Timber.e(exception)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (from >= 14) {
|
if (from >= 14) {
|
||||||
try {
|
try {
|
||||||
db.execSQL("ALTER TABLE bookmarksLocations ADD COLUMN location_exists STRING;");
|
db.execSQL("ALTER TABLE $TABLE_NAME ADD COLUMN location_exists STRING;")
|
||||||
} catch (SQLiteException exception){
|
} catch (exception: SQLiteException) {
|
||||||
Timber.e(exception);
|
Timber.e(exception)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,137 +1,145 @@
|
||||||
package fr.free.nrw.commons.bookmarks.locations;
|
package fr.free.nrw.commons.bookmarks.locations
|
||||||
|
|
||||||
import android.Manifest.permission;
|
import android.Manifest.permission
|
||||||
import android.content.Intent;
|
import android.os.Bundle
|
||||||
import android.os.Bundle;
|
import android.view.LayoutInflater
|
||||||
import android.view.LayoutInflater;
|
import android.view.View
|
||||||
import android.view.View;
|
import android.view.ViewGroup
|
||||||
import android.view.ViewGroup;
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.activity.result.ActivityResultCallback;
|
import androidx.activity.result.contract.ActivityResultContracts.RequestMultiplePermissions
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult
|
||||||
import androidx.activity.result.contract.ActivityResultContracts;
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.activity.result.contract.ActivityResultContracts.StartActivityForResult;
|
import dagger.android.support.DaggerFragment
|
||||||
import androidx.annotation.NonNull;
|
import fr.free.nrw.commons.R
|
||||||
import androidx.annotation.Nullable;
|
import fr.free.nrw.commons.contributions.ContributionController
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
import fr.free.nrw.commons.databinding.FragmentBookmarksLocationsBinding
|
||||||
import dagger.android.support.DaggerFragment;
|
import fr.free.nrw.commons.filepicker.FilePicker
|
||||||
import fr.free.nrw.commons.R;
|
import fr.free.nrw.commons.nearby.fragments.CommonPlaceClickActions
|
||||||
import fr.free.nrw.commons.contributions.ContributionController;
|
import fr.free.nrw.commons.nearby.fragments.PlaceAdapter
|
||||||
import fr.free.nrw.commons.databinding.FragmentBookmarksLocationsBinding;
|
import javax.inject.Inject
|
||||||
import fr.free.nrw.commons.nearby.Place;
|
|
||||||
import fr.free.nrw.commons.nearby.fragments.CommonPlaceClickActions;
|
|
||||||
import fr.free.nrw.commons.nearby.fragments.PlaceAdapter;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import kotlin.Unit;
|
|
||||||
|
|
||||||
public class BookmarkLocationsFragment extends DaggerFragment {
|
|
||||||
|
|
||||||
public FragmentBookmarksLocationsBinding binding;
|
class BookmarkLocationsFragment : DaggerFragment() {
|
||||||
|
|
||||||
@Inject BookmarkLocationsController controller;
|
private var binding: FragmentBookmarksLocationsBinding? = null
|
||||||
@Inject ContributionController contributionController;
|
|
||||||
@Inject BookmarkLocationsDao bookmarkLocationDao;
|
|
||||||
@Inject CommonPlaceClickActions commonPlaceClickActions;
|
|
||||||
private PlaceAdapter adapter;
|
|
||||||
|
|
||||||
private final ActivityResultLauncher<Intent> cameraPickLauncherForResult =
|
@Inject lateinit var controller: BookmarkLocationsController
|
||||||
registerForActivityResult(new StartActivityForResult(),
|
@Inject lateinit var contributionController: ContributionController
|
||||||
result -> {
|
@Inject lateinit var bookmarkLocationDao: BookmarkLocationsDao
|
||||||
contributionController.handleActivityResultWithCallback(requireActivity(), callbacks -> {
|
@Inject lateinit var commonPlaceClickActions: CommonPlaceClickActions
|
||||||
contributionController.onPictureReturnedFromCamera(result, requireActivity(), callbacks);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
private final ActivityResultLauncher<Intent> galleryPickLauncherForResult =
|
private lateinit var inAppCameraLocationPermissionLauncher:
|
||||||
registerForActivityResult(new StartActivityForResult(),
|
ActivityResultLauncher<Array<String>>
|
||||||
result -> {
|
private lateinit var adapter: PlaceAdapter
|
||||||
contributionController.handleActivityResultWithCallback(requireActivity(), callbacks -> {
|
|
||||||
contributionController.onPictureReturnedFromGallery(result, requireActivity(), callbacks);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
private ActivityResultLauncher<String[]> inAppCameraLocationPermissionLauncher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
|
private val cameraPickLauncherForResult =
|
||||||
@Override
|
registerForActivityResult(StartActivityForResult()) { result ->
|
||||||
public void onActivityResult(Map<String, Boolean> result) {
|
contributionController.handleActivityResultWithCallback(
|
||||||
boolean areAllGranted = true;
|
requireActivity(),
|
||||||
for(final boolean b : result.values()) {
|
object: FilePicker.HandleActivityResult {
|
||||||
areAllGranted = areAllGranted && b;
|
override fun onHandleActivityResult(callbacks: FilePicker.Callbacks) {
|
||||||
|
contributionController.onPictureReturnedFromCamera(
|
||||||
|
result,
|
||||||
|
requireActivity(),
|
||||||
|
callbacks
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val galleryPickLauncherForResult =
|
||||||
|
registerForActivityResult(StartActivityForResult()) { result ->
|
||||||
|
contributionController.handleActivityResultWithCallback(
|
||||||
|
requireActivity(),
|
||||||
|
object: FilePicker.HandleActivityResult {
|
||||||
|
override fun onHandleActivityResult(callbacks: FilePicker.Callbacks) {
|
||||||
|
contributionController.onPictureReturnedFromGallery(
|
||||||
|
result,
|
||||||
|
requireActivity(),
|
||||||
|
callbacks
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
fun newInstance(): BookmarkLocationsFragment {
|
||||||
|
return BookmarkLocationsFragment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onCreateView(
|
||||||
|
inflater: LayoutInflater,
|
||||||
|
container: ViewGroup?,
|
||||||
|
savedInstanceState: Bundle?
|
||||||
|
): View? {
|
||||||
|
binding = FragmentBookmarksLocationsBinding.inflate(inflater, container, false)
|
||||||
|
return binding?.root
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
binding?.loadingImagesProgressBar?.visibility = View.VISIBLE
|
||||||
|
binding?.listView?.layoutManager = LinearLayoutManager(context)
|
||||||
|
|
||||||
|
inAppCameraLocationPermissionLauncher =
|
||||||
|
registerForActivityResult(RequestMultiplePermissions()) { result ->
|
||||||
|
val areAllGranted = result.values.all { it }
|
||||||
|
|
||||||
if (areAllGranted) {
|
if (areAllGranted) {
|
||||||
contributionController.locationPermissionCallback.onLocationPermissionGranted();
|
contributionController.locationPermissionCallback.onLocationPermissionGranted()
|
||||||
} else {
|
} else {
|
||||||
if (shouldShowRequestPermissionRationale(permission.ACCESS_FINE_LOCATION)) {
|
if (shouldShowRequestPermissionRationale(permission.ACCESS_FINE_LOCATION)) {
|
||||||
contributionController.handleShowRationaleFlowCameraLocation(getActivity(), inAppCameraLocationPermissionLauncher, cameraPickLauncherForResult);
|
contributionController.handleShowRationaleFlowCameraLocation(
|
||||||
|
activity,
|
||||||
|
inAppCameraLocationPermissionLauncher,
|
||||||
|
cameraPickLauncherForResult
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
contributionController.locationPermissionCallback.onLocationPermissionDenied(getActivity().getString(R.string.in_app_camera_location_permission_denied));
|
contributionController.locationPermissionCallback
|
||||||
|
.onLocationPermissionDenied(
|
||||||
|
getString(R.string.in_app_camera_location_permission_denied)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an instance of the fragment with the right bundle parameters
|
|
||||||
* @return an instance of the fragment
|
|
||||||
*/
|
|
||||||
public static BookmarkLocationsFragment newInstance() {
|
|
||||||
return new BookmarkLocationsFragment();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
adapter = PlaceAdapter(
|
||||||
public View onCreateView(
|
bookmarkLocationDao,
|
||||||
@NonNull LayoutInflater inflater,
|
{ },
|
||||||
ViewGroup container,
|
{ place, _ ->
|
||||||
Bundle savedInstanceState
|
adapter.remove(place)
|
||||||
) {
|
|
||||||
binding = FragmentBookmarksLocationsBinding.inflate(inflater, container, false);
|
|
||||||
return binding.getRoot();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
binding.loadingImagesProgressBar.setVisibility(View.VISIBLE);
|
|
||||||
binding.listView.setLayoutManager(new LinearLayoutManager(getContext()));
|
|
||||||
adapter = new PlaceAdapter(bookmarkLocationDao,
|
|
||||||
place -> Unit.INSTANCE,
|
|
||||||
(place, isBookmarked) -> {
|
|
||||||
adapter.remove(place);
|
|
||||||
return Unit.INSTANCE;
|
|
||||||
},
|
},
|
||||||
commonPlaceClickActions,
|
commonPlaceClickActions,
|
||||||
inAppCameraLocationPermissionLauncher,
|
inAppCameraLocationPermissionLauncher,
|
||||||
galleryPickLauncherForResult,
|
galleryPickLauncherForResult,
|
||||||
cameraPickLauncherForResult
|
cameraPickLauncherForResult
|
||||||
);
|
)
|
||||||
binding.listView.setAdapter(adapter);
|
binding?.listView?.adapter = adapter
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onResume() {
|
||||||
public void onResume() {
|
super.onResume()
|
||||||
super.onResume();
|
initList()
|
||||||
initList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private fun initList() {
|
||||||
* Initialize the recycler view with bookmarked locations
|
val places = controller.loadFavoritesLocations()
|
||||||
*/
|
adapter.items = places
|
||||||
private void initList() {
|
binding?.loadingImagesProgressBar?.visibility = View.GONE
|
||||||
List<Place> places = controller.loadFavoritesLocations();
|
if (places.isEmpty()) {
|
||||||
adapter.setItems(places);
|
binding?.statusMessage?.text = getString(R.string.bookmark_empty)
|
||||||
binding.loadingImagesProgressBar.setVisibility(View.GONE);
|
binding?.statusMessage?.visibility = View.VISIBLE
|
||||||
if (places.size() <= 0) {
|
|
||||||
binding.statusMessage.setText(R.string.bookmark_empty);
|
|
||||||
binding.statusMessage.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
} else {
|
||||||
binding.statusMessage.setVisibility(View.GONE);
|
binding?.statusMessage?.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
override fun onDestroy() {
|
||||||
public void onDestroy() {
|
super.onDestroy()
|
||||||
super.onDestroy();
|
// Make sure to null out the binding to avoid memory leaks
|
||||||
binding = null;
|
binding = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ import com.nhaarman.mockitokotlin2.mock
|
||||||
import com.nhaarman.mockitokotlin2.verify
|
import com.nhaarman.mockitokotlin2.verify
|
||||||
import com.nhaarman.mockitokotlin2.whenever
|
import com.nhaarman.mockitokotlin2.whenever
|
||||||
import fr.free.nrw.commons.TestCommonsApplication
|
import fr.free.nrw.commons.TestCommonsApplication
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsContentProvider.BASE_URI
|
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao.Table.COLUMN_CATEGORY
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao.Table.COLUMN_CATEGORY
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao.Table.COLUMN_COMMONS_LINK
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao.Table.COLUMN_COMMONS_LINK
|
||||||
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao.Table.COLUMN_DESCRIPTION
|
import fr.free.nrw.commons.bookmarks.locations.BookmarkLocationsDao.Table.COLUMN_DESCRIPTION
|
||||||
|
|
@ -149,7 +148,7 @@ class BookMarkLocationDaoTest {
|
||||||
fun getAllLocationBookmarks() {
|
fun getAllLocationBookmarks() {
|
||||||
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(createCursor(14))
|
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(createCursor(14))
|
||||||
|
|
||||||
var result = testObject.allBookmarksLocations
|
var result = testObject.getAllBookmarksLocations()
|
||||||
|
|
||||||
assertEquals(14, result.size)
|
assertEquals(14, result.size)
|
||||||
}
|
}
|
||||||
|
|
@ -157,19 +156,19 @@ class BookMarkLocationDaoTest {
|
||||||
@Test(expected = RuntimeException::class)
|
@Test(expected = RuntimeException::class)
|
||||||
fun getAllLocationBookmarksTranslatesExceptions() {
|
fun getAllLocationBookmarksTranslatesExceptions() {
|
||||||
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenThrow(RemoteException(""))
|
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenThrow(RemoteException(""))
|
||||||
testObject.allBookmarksLocations
|
testObject.getAllBookmarksLocations()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getAllLocationBookmarksReturnsEmptyList_emptyCursor() {
|
fun getAllLocationBookmarksReturnsEmptyList_emptyCursor() {
|
||||||
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(createCursor(0))
|
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(createCursor(0))
|
||||||
assertTrue(testObject.allBookmarksLocations.isEmpty())
|
assertTrue(testObject.getAllBookmarksLocations().isEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun getAllLocationBookmarksReturnsEmptyList_nullCursor() {
|
fun getAllLocationBookmarksReturnsEmptyList_nullCursor() {
|
||||||
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(null)
|
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(null)
|
||||||
assertTrue(testObject.allBookmarksLocations.isEmpty())
|
assertTrue(testObject.getAllBookmarksLocations().isEmpty())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -178,7 +177,7 @@ class BookMarkLocationDaoTest {
|
||||||
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(mockCursor)
|
whenever(client.query(any(), any(), anyOrNull(), any(), anyOrNull())).thenReturn(mockCursor)
|
||||||
whenever(mockCursor.moveToFirst()).thenReturn(false)
|
whenever(mockCursor.moveToFirst()).thenReturn(false)
|
||||||
|
|
||||||
testObject.allBookmarksLocations
|
testObject.getAllBookmarksLocations()
|
||||||
|
|
||||||
verify(mockCursor).close()
|
verify(mockCursor).close()
|
||||||
}
|
}
|
||||||
|
|
@ -189,7 +188,7 @@ class BookMarkLocationDaoTest {
|
||||||
whenever(client.query(any(), any(), any(), any(), anyOrNull())).thenReturn(null)
|
whenever(client.query(any(), any(), any(), any(), anyOrNull())).thenReturn(null)
|
||||||
|
|
||||||
assertTrue(testObject.updateBookmarkLocation(examplePlaceBookmark))
|
assertTrue(testObject.updateBookmarkLocation(examplePlaceBookmark))
|
||||||
verify(client).insert(eq(BASE_URI), captor.capture())
|
verify(client).insert(eq(BookmarkLocationsContentProvider.BASE_URI), captor.capture())
|
||||||
captor.firstValue.let { cv ->
|
captor.firstValue.let { cv ->
|
||||||
assertEquals(13, cv.size())
|
assertEquals(13, cv.size())
|
||||||
assertEquals(examplePlaceBookmark.name, cv.getAsString(COLUMN_NAME))
|
assertEquals(examplePlaceBookmark.name, cv.getAsString(COLUMN_NAME))
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ class BookmarkLocationControllerTest {
|
||||||
@Before
|
@Before
|
||||||
fun setup() {
|
fun setup() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
whenever(bookmarkDao!!.allBookmarksLocations)
|
whenever(bookmarkDao!!.getAllBookmarksLocations())
|
||||||
.thenReturn(mockBookmarkList)
|
.thenReturn(mockBookmarkList)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -463,7 +463,7 @@ class NearbyParentFragmentPresenterTest {
|
||||||
nearbyPlacesInfo.searchLatLng = latestLocation
|
nearbyPlacesInfo.searchLatLng = latestLocation
|
||||||
nearbyPlacesInfo.placeList = emptyList<Place>()
|
nearbyPlacesInfo.placeList = emptyList<Place>()
|
||||||
|
|
||||||
whenever(bookmarkLocationsDao.allBookmarksLocations).thenReturn(Collections.emptyList())
|
whenever(bookmarkLocationsDao.getAllBookmarksLocations()).thenReturn(Collections.emptyList())
|
||||||
nearbyPresenter.updateMapMarkers(nearbyPlacesInfo.placeList, latestLocation, null)
|
nearbyPresenter.updateMapMarkers(nearbyPlacesInfo.placeList, latestLocation, null)
|
||||||
Mockito.verify(nearbyParentFragmentView).setProgressBarVisibility(false)
|
Mockito.verify(nearbyParentFragmentView).setProgressBarVisibility(false)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue