diff --git a/app/src/main/java/awais/instagrabber/db/dao/AccountDao.kt b/app/src/main/java/awais/instagrabber/db/dao/AccountDao.kt index 4a9e356d..5661de80 100644 --- a/app/src/main/java/awais/instagrabber/db/dao/AccountDao.kt +++ b/app/src/main/java/awais/instagrabber/db/dao/AccountDao.kt @@ -12,7 +12,7 @@ interface AccountDao { suspend fun findAccountByUid(uid: String): Account? @Insert(onConflict = OnConflictStrategy.REPLACE) - suspend fun insertAccounts(vararg accounts: Account): List + suspend fun insertAccounts(vararg accounts: Account) @Update suspend fun updateAccounts(vararg accounts: Account) diff --git a/app/src/main/java/awais/instagrabber/db/dao/FavoriteDao.java b/app/src/main/java/awais/instagrabber/db/dao/FavoriteDao.java deleted file mode 100644 index 4bf0f2ad..00000000 --- a/app/src/main/java/awais/instagrabber/db/dao/FavoriteDao.java +++ /dev/null @@ -1,35 +0,0 @@ -package awais.instagrabber.db.dao; - -import androidx.room.Dao; -import androidx.room.Delete; -import androidx.room.Insert; -import androidx.room.OnConflictStrategy; -import androidx.room.Query; -import androidx.room.Update; - -import java.util.List; - -import awais.instagrabber.db.entities.Favorite; -import awais.instagrabber.models.enums.FavoriteType; - -@Dao -public interface FavoriteDao { - - @Query("SELECT * FROM favorites") - List getAllFavorites(); - - @Query("SELECT * FROM favorites WHERE query_text = :query and type = :type") - Favorite findFavoriteByQueryAndType(String query, FavoriteType type); - - @Insert - List insertFavorites(Favorite... favorites); - - @Update - void updateFavorites(Favorite... favorites); - - @Delete - void deleteFavorites(Favorite... favorites); - - @Query("DELETE from favorites") - void deleteAllFavorites(); -} diff --git a/app/src/main/java/awais/instagrabber/db/dao/FavoriteDao.kt b/app/src/main/java/awais/instagrabber/db/dao/FavoriteDao.kt new file mode 100644 index 00000000..f78e531a --- /dev/null +++ b/app/src/main/java/awais/instagrabber/db/dao/FavoriteDao.kt @@ -0,0 +1,26 @@ +package awais.instagrabber.db.dao + +import androidx.room.* +import awais.instagrabber.db.entities.Favorite +import awais.instagrabber.models.enums.FavoriteType + +@Dao +interface FavoriteDao { + @Query("SELECT * FROM favorites") + suspend fun getAllFavorites(): List + + @Query("SELECT * FROM favorites WHERE query_text = :query and type = :type") + suspend fun findFavoriteByQueryAndType(query: String, type: FavoriteType): Favorite? + + @Insert + suspend fun insertFavorites(vararg favorites: Favorite) + + @Update + suspend fun updateFavorites(vararg favorites: Favorite) + + @Delete + suspend fun deleteFavorites(vararg favorites: Favorite) + + @Query("DELETE from favorites") + suspend fun deleteAllFavorites() +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/db/datasources/FavoriteDataSource.java b/app/src/main/java/awais/instagrabber/db/datasources/FavoriteDataSource.java deleted file mode 100644 index bc013926..00000000 --- a/app/src/main/java/awais/instagrabber/db/datasources/FavoriteDataSource.java +++ /dev/null @@ -1,62 +0,0 @@ -package awais.instagrabber.db.datasources; - -import android.content.Context; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import java.util.List; - -import awais.instagrabber.db.AppDatabase; -import awais.instagrabber.db.dao.FavoriteDao; -import awais.instagrabber.db.entities.Favorite; -import awais.instagrabber.models.enums.FavoriteType; - -public class FavoriteDataSource { - private static final String TAG = FavoriteDataSource.class.getSimpleName(); - - private static FavoriteDataSource INSTANCE; - - private final FavoriteDao favoriteDao; - - private FavoriteDataSource(final FavoriteDao favoriteDao) { - this.favoriteDao = favoriteDao; - } - - public static synchronized FavoriteDataSource getInstance(@NonNull Context context) { - if (INSTANCE == null) { - synchronized (FavoriteDataSource.class) { - if (INSTANCE == null) { - final AppDatabase database = AppDatabase.getDatabase(context); - INSTANCE = new FavoriteDataSource(database.favoriteDao()); - } - } - } - return INSTANCE; - } - - - @Nullable - public final Favorite getFavorite(@NonNull final String query, @NonNull final FavoriteType type) { - return favoriteDao.findFavoriteByQueryAndType(query, type); - } - - @NonNull - public final List getAllFavorites() { - return favoriteDao.getAllFavorites(); - } - - public final void insertOrUpdateFavorite(@NonNull final Favorite favorite) { - if (favorite.getId() != 0) { - favoriteDao.updateFavorites(favorite); - return; - } - favoriteDao.insertFavorites(favorite); - } - - public final void deleteFavorite(@NonNull final String query, @NonNull final FavoriteType type) { - final Favorite favorite = getFavorite(query, type); - if (favorite == null) return; - favoriteDao.deleteFavorites(favorite); - } -} diff --git a/app/src/main/java/awais/instagrabber/db/datasources/FavoriteDataSource.kt b/app/src/main/java/awais/instagrabber/db/datasources/FavoriteDataSource.kt new file mode 100644 index 00000000..e14a9409 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/db/datasources/FavoriteDataSource.kt @@ -0,0 +1,44 @@ +package awais.instagrabber.db.datasources + +import android.content.Context +import awais.instagrabber.db.AppDatabase +import awais.instagrabber.db.dao.FavoriteDao +import awais.instagrabber.db.entities.Favorite +import awais.instagrabber.models.enums.FavoriteType + +class FavoriteDataSource private constructor(private val favoriteDao: FavoriteDao) { + suspend fun getFavorite(query: String, type: FavoriteType): Favorite? = favoriteDao.findFavoriteByQueryAndType(query, type) + + suspend fun getAllFavorites(): List = favoriteDao.getAllFavorites() + + suspend fun insertOrUpdateFavorite(favorite: Favorite) { + if (favorite.id != 0) { + favoriteDao.updateFavorites(favorite) + return + } + favoriteDao.insertFavorites(favorite) + } + + suspend fun deleteFavorite(query: String, type: FavoriteType) { + val favorite = getFavorite(query, type) ?: return + favoriteDao.deleteFavorites(favorite) + } + + companion object { + private lateinit var INSTANCE: FavoriteDataSource + + @JvmStatic + @Synchronized + fun getInstance(context: Context): FavoriteDataSource { + if (!this::INSTANCE.isInitialized) { + synchronized(FavoriteDataSource::class.java) { + if (!this::INSTANCE.isInitialized) { + val database = AppDatabase.getDatabase(context) + INSTANCE = FavoriteDataSource(database.favoriteDao()) + } + } + } + return INSTANCE + } + } +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/db/repositories/FavoriteRepository.java b/app/src/main/java/awais/instagrabber/db/repositories/FavoriteRepository.java deleted file mode 100644 index eb130e22..00000000 --- a/app/src/main/java/awais/instagrabber/db/repositories/FavoriteRepository.java +++ /dev/null @@ -1,88 +0,0 @@ -package awais.instagrabber.db.repositories; - -import java.util.List; - -import awais.instagrabber.db.datasources.FavoriteDataSource; -import awais.instagrabber.db.entities.Favorite; -import awais.instagrabber.models.enums.FavoriteType; -import awais.instagrabber.utils.AppExecutors; - -public class FavoriteRepository { - private static final String TAG = FavoriteRepository.class.getSimpleName(); - - private static FavoriteRepository instance; - - private final AppExecutors appExecutors; - private final FavoriteDataSource favoriteDataSource; - - private FavoriteRepository(final AppExecutors appExecutors, final FavoriteDataSource favoriteDataSource) { - this.appExecutors = appExecutors; - this.favoriteDataSource = favoriteDataSource; - } - - public static FavoriteRepository getInstance(final FavoriteDataSource favoriteDataSource) { - if (instance == null) { - instance = new FavoriteRepository(AppExecutors.INSTANCE, favoriteDataSource); - } - return instance; - } - - public void getFavorite(final String query, final FavoriteType type, final RepositoryCallback callback) { - // request on the I/O thread - appExecutors.getDiskIO().execute(() -> { - final Favorite favorite = favoriteDataSource.getFavorite(query, type); - // notify on the main thread - appExecutors.getMainThread().execute(() -> { - if (callback == null) return; - if (favorite == null) { - callback.onDataNotAvailable(); - return; - } - callback.onSuccess(favorite); - }); - }); - } - - public void getAllFavorites(final RepositoryCallback> callback) { - // request on the I/O thread - appExecutors.getDiskIO().execute(() -> { - final List favorites = favoriteDataSource.getAllFavorites(); - // notify on the main thread - appExecutors.getMainThread().execute(() -> { - if (callback == null) return; - if (favorites == null) { - callback.onDataNotAvailable(); - return; - } - callback.onSuccess(favorites); - }); - }); - } - - public void insertOrUpdateFavorite(final Favorite favorite, - final RepositoryCallback callback) { - // request on the I/O thread - appExecutors.getDiskIO().execute(() -> { - favoriteDataSource.insertOrUpdateFavorite(favorite); - // notify on the main thread - appExecutors.getMainThread().execute(() -> { - if (callback == null) return; - callback.onSuccess(null); - }); - }); - } - - public void deleteFavorite(final String query, - final FavoriteType type, - final RepositoryCallback callback) { - // request on the I/O thread - appExecutors.getDiskIO().execute(() -> { - favoriteDataSource.deleteFavorite(query, type); - // notify on the main thread - appExecutors.getMainThread().execute(() -> { - if (callback == null) return; - callback.onSuccess(null); - }); - }); - } -} diff --git a/app/src/main/java/awais/instagrabber/db/repositories/FavoriteRepository.kt b/app/src/main/java/awais/instagrabber/db/repositories/FavoriteRepository.kt new file mode 100644 index 00000000..5a1b2572 --- /dev/null +++ b/app/src/main/java/awais/instagrabber/db/repositories/FavoriteRepository.kt @@ -0,0 +1,28 @@ +package awais.instagrabber.db.repositories + +import awais.instagrabber.db.datasources.FavoriteDataSource +import awais.instagrabber.db.entities.Favorite +import awais.instagrabber.models.enums.FavoriteType + +class FavoriteRepository private constructor(private val favoriteDataSource: FavoriteDataSource) { + + suspend fun getFavorite(query: String, type: FavoriteType): Favorite? = favoriteDataSource.getFavorite(query, type) + + suspend fun getAllFavorites(): List = favoriteDataSource.getAllFavorites() + + suspend fun insertOrUpdateFavorite(favorite: Favorite) = favoriteDataSource.insertOrUpdateFavorite(favorite) + + suspend fun deleteFavorite(query: String, type: FavoriteType) = favoriteDataSource.deleteFavorite(query, type) + + companion object { + private lateinit var instance: FavoriteRepository + + @JvmStatic + fun getInstance(favoriteDataSource: FavoriteDataSource): FavoriteRepository { + if (!this::instance.isInitialized) { + instance = FavoriteRepository(favoriteDataSource) + } + return instance + } + } +} \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java index 1d141437..441bf324 100644 --- a/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/HashTagFragment.java @@ -51,7 +51,6 @@ import awais.instagrabber.databinding.LayoutHashtagDetailsBinding; import awais.instagrabber.db.datasources.FavoriteDataSource; import awais.instagrabber.db.entities.Favorite; import awais.instagrabber.db.repositories.FavoriteRepository; -import awais.instagrabber.db.repositories.RepositoryCallback; import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.models.enums.FavoriteType; @@ -480,73 +479,81 @@ public class HashTagFragment extends Fragment implements SwipeRefreshLayout.OnRe final Context context = getContext(); if (context == null) return; final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(context)); - favoriteRepository.getFavorite(hashtag, FavoriteType.HASHTAG, new RepositoryCallback() { - @Override - public void onSuccess(final Favorite result) { - favoriteRepository.insertOrUpdateFavorite(new Favorite( - result.getId(), - hashtag, - FavoriteType.HASHTAG, - hashtagModel.getName(), - "res:/" + R.drawable.ic_hashtag, - result.getDateAdded() - ), new RepositoryCallback() { - @Override - public void onSuccess(final Void result) { - hashtagDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); - hashtagDetailsBinding.favChip.setText(R.string.favorite_short); + favoriteRepository.getFavorite( + hashtag, + FavoriteType.HASHTAG, + CoroutineUtilsKt.getContinuation((favorite, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null || favorite == null) { + hashtagDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); + hashtagDetailsBinding.favChip.setText(R.string.add_to_favorites); + return; } - - @Override - public void onDataNotAvailable() {} - }); - } - - @Override - public void onDataNotAvailable() { - hashtagDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); - hashtagDetailsBinding.favChip.setText(R.string.add_to_favorites); - } - }); - hashtagDetailsBinding.favChip.setOnClickListener( - v -> favoriteRepository.getFavorite(hashtag, FavoriteType.HASHTAG, new RepositoryCallback() { - @Override - public void onSuccess(final Favorite result) { - favoriteRepository.deleteFavorite(hashtag, FavoriteType.HASHTAG, new RepositoryCallback() { - @Override - public void onSuccess(final Void result) { + favoriteRepository.insertOrUpdateFavorite( + new Favorite( + favorite.getId(), + hashtag, + FavoriteType.HASHTAG, + hashtagModel.getName(), + "res:/" + R.drawable.ic_hashtag, + favorite.getDateAdded() + ), + CoroutineUtilsKt.getContinuation((unit, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable1 != null) { + Log.e(TAG, "onSuccess: ", throwable1); + return; + } + hashtagDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); + hashtagDetailsBinding.favChip.setText(R.string.favorite_short); + }), Dispatchers.getIO()) + ); + }), Dispatchers.getIO()) + ); + hashtagDetailsBinding.favChip.setOnClickListener(v -> favoriteRepository.getFavorite( + hashtag, + FavoriteType.HASHTAG, + CoroutineUtilsKt.getContinuation((favorite, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null) { + Log.e(TAG, "setHashtagDetails: ", throwable); + return; + } + if (favorite == null) { + favoriteRepository.insertOrUpdateFavorite( + new Favorite( + 0, + hashtag, + FavoriteType.HASHTAG, + hashtagModel.getName(), + "res:/" + R.drawable.ic_hashtag, + LocalDateTime.now() + ), + CoroutineUtilsKt.getContinuation((unit, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable1 != null) { + Log.e(TAG, "onDataNotAvailable: ", throwable1); + return; + } + hashtagDetailsBinding.favChip.setText(R.string.favorite_short); + hashtagDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); + showSnackbar(getString(R.string.added_to_favs)); + }), Dispatchers.getIO()) + ); + return; + } + favoriteRepository.deleteFavorite( + hashtag, + FavoriteType.HASHTAG, + CoroutineUtilsKt.getContinuation((unit, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable1 != null) { + Log.e(TAG, "onSuccess: ", throwable1); + return; + } hashtagDetailsBinding.favChip.setText(R.string.add_to_favorites); hashtagDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); showSnackbar(getString(R.string.removed_from_favs)); - } - - @Override - public void onDataNotAvailable() {} - }); - } - - @Override - public void onDataNotAvailable() { - favoriteRepository.insertOrUpdateFavorite(new Favorite( - 0, - hashtag, - FavoriteType.HASHTAG, - hashtagModel.getName(), - "res:/" + R.drawable.ic_hashtag, - LocalDateTime.now() - ), new RepositoryCallback() { - @Override - public void onSuccess(final Void result) { - hashtagDetailsBinding.favChip.setText(R.string.favorite_short); - hashtagDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); - showSnackbar(getString(R.string.added_to_favs)); - } - - @Override - public void onDataNotAvailable() {} - }); - } - })); + }), Dispatchers.getIO()) + ); + }), Dispatchers.getIO()) + ) + ); hashtagDetailsBinding.mainHashtagImage.setImageURI("res:/" + R.drawable.ic_hashtag); final String postCount = String.valueOf(hashtagModel.getMediaCount()); final SpannableStringBuilder span = new SpannableStringBuilder(getResources().getQuantityString(R.plurals.main_posts_count_inline, diff --git a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java index df0ff4eb..58d4c2e0 100644 --- a/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/LocationFragment.java @@ -49,7 +49,6 @@ import awais.instagrabber.databinding.LayoutLocationDetailsBinding; import awais.instagrabber.db.datasources.FavoriteDataSource; import awais.instagrabber.db.entities.Favorite; import awais.instagrabber.db.repositories.FavoriteRepository; -import awais.instagrabber.db.repositories.RepositoryCallback; import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; import awais.instagrabber.models.PostsLayoutPreferences; import awais.instagrabber.models.enums.FavoriteType; @@ -493,75 +492,82 @@ public class LocationFragment extends Fragment implements SwipeRefreshLayout.OnR final FavoriteDataSource dataSource = FavoriteDataSource.getInstance(context); final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(dataSource); locationDetailsBinding.favChip.setVisibility(View.VISIBLE); - favoriteRepository.getFavorite(String.valueOf(locationId), FavoriteType.LOCATION, new RepositoryCallback() { - @Override - public void onSuccess(final Favorite result) { - locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); - locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); - locationDetailsBinding.favChip.setText(R.string.favorite_short); - favoriteRepository.insertOrUpdateFavorite(new Favorite( - result.getId(), - String.valueOf(locationId), - FavoriteType.LOCATION, - locationModel.getName(), - "res:/" + R.drawable.ic_location, - result.getDateAdded() - ), new RepositoryCallback() { - @Override - public void onSuccess(final Void result) {} - - @Override - public void onDataNotAvailable() {} - }); - } - - @Override - public void onDataNotAvailable() { - locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); - locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); - locationDetailsBinding.favChip.setText(R.string.add_to_favorites); - } - }); - locationDetailsBinding.favChip.setOnClickListener(v -> { - favoriteRepository.getFavorite(String.valueOf(locationId), FavoriteType.LOCATION, new RepositoryCallback() { - @Override - public void onSuccess(final Favorite result) { - favoriteRepository.deleteFavorite(String.valueOf(locationId), FavoriteType.LOCATION, new RepositoryCallback() { - @Override - public void onSuccess(final Void result) { - locationDetailsBinding.favChip.setText(R.string.add_to_favorites); - locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); - showSnackbar(getString(R.string.removed_from_favs)); - } - - @Override - public void onDataNotAvailable() {} - }); - } - - @Override - public void onDataNotAvailable() { - favoriteRepository.insertOrUpdateFavorite(new Favorite( - 0, + favoriteRepository.getFavorite( + String.valueOf(locationId), + FavoriteType.LOCATION, + CoroutineUtilsKt.getContinuation((favorite, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null || favorite == null) { + locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); + locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); + locationDetailsBinding.favChip.setText(R.string.add_to_favorites); + Log.e(TAG, "setupLocationDetails: ", throwable); + return; + } + locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); + locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); + locationDetailsBinding.favChip.setText(R.string.favorite_short); + favoriteRepository.insertOrUpdateFavorite( + new Favorite( + favorite.getId(), + String.valueOf(locationId), + FavoriteType.LOCATION, + locationModel.getName(), + "res:/" + R.drawable.ic_location, + favorite.getDateAdded() + ), + CoroutineUtilsKt.getContinuation((unit, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable1 != null) { + Log.e(TAG, "onSuccess: ", throwable1); + } + }), Dispatchers.getIO()) + ); + }), Dispatchers.getIO()) + ); + locationDetailsBinding.favChip.setOnClickListener(v -> favoriteRepository.getFavorite( + String.valueOf(locationId), + FavoriteType.LOCATION, + CoroutineUtilsKt.getContinuation((favorite, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null) { + Log.e(TAG, "setupLocationDetails: ", throwable); + return; + } + if (favorite == null) { + favoriteRepository.insertOrUpdateFavorite( + new Favorite( + 0, + String.valueOf(locationId), + FavoriteType.LOCATION, + locationModel.getName(), + "res:/" + R.drawable.ic_location, + LocalDateTime.now() + ), + CoroutineUtilsKt.getContinuation((unit, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable1 != null) { + Log.e(TAG, "onDataNotAvailable: ", throwable1); + return; + } + locationDetailsBinding.favChip.setText(R.string.favorite_short); + locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); + showSnackbar(getString(R.string.added_to_favs)); + }), Dispatchers.getIO()) + ); + return; + } + favoriteRepository.deleteFavorite( String.valueOf(locationId), FavoriteType.LOCATION, - locationModel.getName(), - "res:/" + R.drawable.ic_location, - LocalDateTime.now() - ), new RepositoryCallback() { - @Override - public void onSuccess(final Void result) { - locationDetailsBinding.favChip.setText(R.string.favorite_short); - locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); - showSnackbar(getString(R.string.added_to_favs)); - } - - @Override - public void onDataNotAvailable() {} - }); - } - }); - }); + CoroutineUtilsKt.getContinuation((unit, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable1 != null) { + Log.e(TAG, "onSuccess: ", throwable1); + return; + } + locationDetailsBinding.favChip.setText(R.string.add_to_favorites); + locationDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); + showSnackbar(getString(R.string.removed_from_favs)); + }), Dispatchers.getIO()) + ); + }), Dispatchers.getIO()) + )); locationDetailsBinding.mainLocationImage.setOnClickListener(v -> { if (hasStories) { // show stories diff --git a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java index 05676d67..4c762e64 100644 --- a/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java +++ b/app/src/main/java/awais/instagrabber/fragments/main/ProfileFragment.java @@ -65,7 +65,6 @@ import awais.instagrabber.db.datasources.FavoriteDataSource; import awais.instagrabber.db.entities.Favorite; import awais.instagrabber.db.repositories.AccountRepository; import awais.instagrabber.db.repositories.FavoriteRepository; -import awais.instagrabber.db.repositories.RepositoryCallback; import awais.instagrabber.dialogs.PostsLayoutPreferencesDialogFragment; import awais.instagrabber.dialogs.ProfilePicDialogFragment; import awais.instagrabber.fragments.PostViewV2Fragment; @@ -702,76 +701,80 @@ public class ProfileFragment extends Fragment implements SwipeRefreshLayout.OnRe setupButtons(profileId); final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(getContext())); - favoriteRepository.getFavorite(profileModel.getUsername(), FavoriteType.USER, new RepositoryCallback() { - @Override - public void onSuccess(final Favorite result) { - profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); - profileDetailsBinding.favChip.setText(R.string.favorite_short); - favoriteRepository.insertOrUpdateFavorite(new Favorite( - result.getId(), - profileModel.getUsername(), - FavoriteType.USER, - profileModel.getFullName(), - profileModel.getProfilePicUrl(), - result.getDateAdded() - ), new RepositoryCallback() { - @Override - public void onSuccess(final Void result) { + favoriteRepository.getFavorite( + profileModel.getUsername(), + FavoriteType.USER, + CoroutineUtilsKt.getContinuation((favorite, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null || favorite == null) { + profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); + profileDetailsBinding.favChip.setText(R.string.add_to_favorites); + Log.e(TAG, "setProfileDetails: ", throwable); + return; } - - @Override - public void onDataNotAvailable() { + profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); + profileDetailsBinding.favChip.setText(R.string.favorite_short); + favoriteRepository.insertOrUpdateFavorite( + new Favorite( + favorite.getId(), + profileModel.getUsername(), + FavoriteType.USER, + profileModel.getFullName(), + profileModel.getProfilePicUrl(), + favorite.getDateAdded() + ), + CoroutineUtilsKt.getContinuation((unit, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable1 != null) { + Log.e(TAG, "onSuccess: ", throwable1); + } + }), Dispatchers.getIO()) + ); + })) + ); + profileDetailsBinding.favChip.setOnClickListener(v -> favoriteRepository.getFavorite( + profileModel.getUsername(), + FavoriteType.USER, + CoroutineUtilsKt.getContinuation((favorite, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null) { + Log.e(TAG, "setProfileDetails: ", throwable); + return; } - }); - } - - @Override - public void onDataNotAvailable() { - profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); - profileDetailsBinding.favChip.setText(R.string.add_to_favorites); - } - }); - profileDetailsBinding.favChip.setOnClickListener( - v -> favoriteRepository.getFavorite(profileModel.getUsername(), FavoriteType.USER, new RepositoryCallback() { - @Override - public void onSuccess(final Favorite result) { - favoriteRepository.deleteFavorite(profileModel.getUsername(), FavoriteType.USER, new RepositoryCallback() { - @Override - public void onSuccess(final Void result) { + if (favorite == null) { + favoriteRepository.insertOrUpdateFavorite( + new Favorite( + 0, + profileModel.getUsername(), + FavoriteType.USER, + profileModel.getFullName(), + profileModel.getProfilePicUrl(), + LocalDateTime.now() + ), + CoroutineUtilsKt.getContinuation((unit, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable1 != null) { + Log.e(TAG, "onDataNotAvailable: ", throwable1); + return; + } + profileDetailsBinding.favChip.setText(R.string.favorite_short); + profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); + showSnackbar(getString(R.string.added_to_favs)); + }), Dispatchers.getIO()) + ); + return; + } + favoriteRepository.deleteFavorite( + profileModel.getUsername(), + FavoriteType.USER, + CoroutineUtilsKt.getContinuation((unit, throwable1) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable1 != null) { + Log.e(TAG, "onSuccess: ", throwable1); + return; + } profileDetailsBinding.favChip.setText(R.string.add_to_favorites); profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_outline_star_plus_24); showSnackbar(getString(R.string.removed_from_favs)); - } - - @Override - public void onDataNotAvailable() { - } - }); - } - - @Override - public void onDataNotAvailable() { - favoriteRepository.insertOrUpdateFavorite(new Favorite( - 0, - profileModel.getUsername(), - FavoriteType.USER, - profileModel.getFullName(), - profileModel.getProfilePicUrl(), - LocalDateTime.now() - ), new RepositoryCallback() { - @Override - public void onSuccess(final Void result) { - profileDetailsBinding.favChip.setText(R.string.favorite_short); - profileDetailsBinding.favChip.setChipIconResource(R.drawable.ic_star_check_24); - showSnackbar(getString(R.string.added_to_favs)); - } - - @Override - public void onDataNotAvailable() { - } - }); - } - })); + }), Dispatchers.getIO()) + ); + }), Dispatchers.getIO()) + )); profileDetailsBinding.mainProfileImage.setImageURI(profileModel.getProfilePicUrl()); profileDetailsBinding.mainProfileImage.setVisibility(View.VISIBLE); diff --git a/app/src/main/java/awais/instagrabber/utils/ExportImportUtils.java b/app/src/main/java/awais/instagrabber/utils/ExportImportUtils.java index 3d1a5431..b34c7260 100755 --- a/app/src/main/java/awais/instagrabber/utils/ExportImportUtils.java +++ b/app/src/main/java/awais/instagrabber/utils/ExportImportUtils.java @@ -38,7 +38,6 @@ import awais.instagrabber.db.entities.Account; import awais.instagrabber.db.entities.Favorite; import awais.instagrabber.db.repositories.AccountRepository; import awais.instagrabber.db.repositories.FavoriteRepository; -import awais.instagrabber.db.repositories.RepositoryCallback; import awais.instagrabber.interfaces.FetchListener; import awais.instagrabber.models.enums.FavoriteType; import awais.instagrabber.utils.PasswordUtils.IncorrectPasswordException; @@ -161,17 +160,20 @@ public final class ExportImportUtils { ); // Log.d(TAG, "importJson: favoriteModel: " + favoriteModel); final FavoriteRepository favRepo = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(context)); - favRepo.getFavorite(query, favoriteType, new RepositoryCallback() { - @Override - public void onSuccess(final Favorite result) { - // local has priority since it's more frequently updated - } - - @Override - public void onDataNotAvailable() { - favRepo.insertOrUpdateFavorite(favorite, null); - } - }); + favRepo.getFavorite( + query, + favoriteType, + CoroutineUtilsKt.getContinuation((favorite1, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null) { + Log.e(TAG, "importFavorites: ", throwable); + return; + } + if (favorite1 == null) { + favRepo.insertOrUpdateFavorite(favorite, CoroutineUtilsKt.getContinuation((unit, throwable1) -> {}, Dispatchers.getIO())); + } + // local has priority since it's more frequently updated + }), Dispatchers.getIO()) + ); } } @@ -198,7 +200,7 @@ public final class ExportImportUtils { return; } AccountRepository.getInstance(AccountDataSource.getInstance(context)) - .insertOrUpdateAccounts(accounts, null); + .insertOrUpdateAccounts(accounts, CoroutineUtilsKt.getContinuation((unit, throwable) -> {}, Dispatchers.getIO())); } private static void importSettings(final JSONObject jsonObject) { @@ -364,33 +366,32 @@ public final class ExportImportUtils { private static ListenableFuture getFavorites(final Context context) { final SettableFuture future = SettableFuture.create(); final FavoriteRepository favoriteRepository = FavoriteRepository.getInstance(FavoriteDataSource.getInstance(context)); - favoriteRepository.getAllFavorites(new RepositoryCallback>() { - @Override - public void onSuccess(final List favorites) { - final JSONArray jsonArray = new JSONArray(); - try { - for (final Favorite favorite : favorites) { - final JSONObject jsonObject = new JSONObject(); - jsonObject.put("q", favorite.getQuery()); - jsonObject.put("type", favorite.getType().toString()); - jsonObject.put("s", favorite.getDisplayName()); - jsonObject.put("pic_url", favorite.getPicUrl()); - jsonObject.put("d", favorite.getDateAdded().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); - jsonArray.put(jsonObject); + favoriteRepository.getAllFavorites( + CoroutineUtilsKt.getContinuation((favorites, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null) { + future.set(new JSONArray()); + Log.e(TAG, "getFavorites: ", throwable); + return; } - } catch (Exception e) { - if (BuildConfig.DEBUG) { - Log.e(TAG, "Error exporting favorites", e); + final JSONArray jsonArray = new JSONArray(); + try { + for (final Favorite favorite : favorites) { + final JSONObject jsonObject = new JSONObject(); + jsonObject.put("q", favorite.getQuery()); + jsonObject.put("type", favorite.getType().toString()); + jsonObject.put("s", favorite.getDisplayName()); + jsonObject.put("pic_url", favorite.getPicUrl()); + jsonObject.put("d", favorite.getDateAdded().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()); + jsonArray.put(jsonObject); + } + } catch (Exception e) { + if (BuildConfig.DEBUG) { + Log.e(TAG, "Error exporting favorites", e); + } } - } - future.set(jsonArray); - } - - @Override - public void onDataNotAvailable() { - future.set(new JSONArray()); - } - }); + future.set(jsonArray); + }), Dispatchers.getIO()) + ); return future; } diff --git a/app/src/main/java/awais/instagrabber/viewmodels/FavoritesViewModel.kt b/app/src/main/java/awais/instagrabber/viewmodels/FavoritesViewModel.kt index 8a2feb3a..bdf2381f 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/FavoritesViewModel.kt +++ b/app/src/main/java/awais/instagrabber/viewmodels/FavoritesViewModel.kt @@ -1,13 +1,18 @@ package awais.instagrabber.viewmodels import android.app.Application +import android.util.Log import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.viewModelScope import awais.instagrabber.db.datasources.FavoriteDataSource import awais.instagrabber.db.entities.Favorite import awais.instagrabber.db.repositories.FavoriteRepository -import awais.instagrabber.db.repositories.RepositoryCallback +import awais.instagrabber.utils.extensions.TAG +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext class FavoritesViewModel(application: Application) : AndroidViewModel(application) { private val _list = MutableLiveData>() @@ -20,29 +25,24 @@ class FavoritesViewModel(application: Application) : AndroidViewModel(applicatio } fun fetch() { - favoriteRepository.getAllFavorites(object : RepositoryCallback> { - override fun onSuccess(favorites: List?) { - _list.postValue(favorites ?: emptyList()) + viewModelScope.launch(Dispatchers.IO) { + try { + _list.postValue(favoriteRepository.getAllFavorites()) + } catch (e: Exception) { + Log.e(TAG, "fetch: ", e) } - - override fun onDataNotAvailable() {} - }) + } } fun delete(favorite: Favorite, onSuccess: () -> Unit) { - favoriteRepository.deleteFavorite(favorite.query, favorite.type, object : RepositoryCallback { - override fun onSuccess(result: Void?) { - onSuccess() - favoriteRepository.getAllFavorites(object : RepositoryCallback> { - override fun onSuccess(result: List?) { - _list.postValue(result ?: emptyList()) - } - - override fun onDataNotAvailable() {} - }) + viewModelScope.launch(Dispatchers.IO) { + try { + favoriteRepository.deleteFavorite(favorite.query, favorite.type) + withContext(Dispatchers.Main) { onSuccess() } + _list.postValue(favoriteRepository.getAllFavorites()) + } catch (e: Exception) { + Log.e(TAG, "delete: ", e) } - - override fun onDataNotAvailable() {} - }) + } } } \ No newline at end of file diff --git a/app/src/main/java/awais/instagrabber/viewmodels/SearchFragmentViewModel.java b/app/src/main/java/awais/instagrabber/viewmodels/SearchFragmentViewModel.java index 14c7964f..18811a7d 100644 --- a/app/src/main/java/awais/instagrabber/viewmodels/SearchFragmentViewModel.java +++ b/app/src/main/java/awais/instagrabber/viewmodels/SearchFragmentViewModel.java @@ -33,9 +33,11 @@ import awais.instagrabber.repositories.responses.search.SearchResponse; import awais.instagrabber.utils.AppExecutors; import awais.instagrabber.utils.Constants; import awais.instagrabber.utils.CookieUtils; +import awais.instagrabber.utils.CoroutineUtilsKt; import awais.instagrabber.utils.Debouncer; import awais.instagrabber.utils.TextUtils; import awais.instagrabber.webservices.SearchService; +import kotlinx.coroutines.Dispatchers; import retrofit2.Call; import retrofit2.Callback; import retrofit2.Response; @@ -191,17 +193,17 @@ public class SearchFragmentViewModel extends AppStateViewModel { recentResultsFuture.set(Collections.emptyList()); } }); - favoriteRepository.getAllFavorites(new RepositoryCallback>() { - @Override - public void onSuccess(final List result) { - favoritesFuture.set(result); - } - - @Override - public void onDataNotAvailable() { - favoritesFuture.set(Collections.emptyList()); - } - }); + favoriteRepository.getAllFavorites( + CoroutineUtilsKt.getContinuation((favorites, throwable) -> AppExecutors.INSTANCE.getMainThread().execute(() -> { + if (throwable != null) { + favoritesFuture.set(Collections.emptyList()); + Log.e(TAG, "showRecentSearchesAndFavorites: ", throwable); + return; + } + //noinspection unchecked + favoritesFuture.set((List) favorites); + }), Dispatchers.getIO()) + ); //noinspection UnstableApiUsage final ListenableFuture>> listenableFuture = Futures.allAsList(recentResultsFuture, favoritesFuture); Futures.addCallback(listenableFuture, new FutureCallback>>() {