Skip to content

Commit

Permalink
Search history
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelbel committed Jan 21, 2024
1 parent ecc3ea5 commit f1f2094
Show file tree
Hide file tree
Showing 34 changed files with 817 additions and 114 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ class Interactor @Inject constructor(
notificationInteractor: NotificationInteractor,
pagingKeyInteractor: PagingKeyInteractor,
searchInteractor: SearchInteractor,
settingsInteractor: SettingsInteractor
settingsInteractor: SettingsInteractor,
suggestionInteractor: SuggestionInteractor
): AccountInteractor by accountInteractor,
AuthenticationInteractor by authenticationInteractor,
ImageInteractor by imageInteractor,
MovieInteractor by movieInteractor,
NotificationInteractor by notificationInteractor,
PagingKeyInteractor by pagingKeyInteractor,
SearchInteractor by searchInteractor,
SettingsInteractor by settingsInteractor
SettingsInteractor by settingsInteractor,
SuggestionInteractor by suggestionInteractor
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.michaelbel.movies.interactor

import androidx.paging.PagingSource
import kotlinx.coroutines.flow.Flow
import org.michaelbel.movies.network.Either
import org.michaelbel.movies.network.model.MovieResponse
import org.michaelbel.movies.network.model.Result
Expand All @@ -10,11 +11,19 @@ interface MovieInteractor {

fun moviesPagingSource(pagingKey: String): PagingSource<Int, MovieDb>

suspend fun moviesResult(movieList: String, page: Int): Result<MovieResponse>
fun moviesFlow(pagingKey: String, limit: Int): Flow<List<MovieDb>>

suspend fun moviesResult(pagingKey: String, page: Int): Result<MovieResponse>

suspend fun movie(pagingKey: String, movieId: Int): MovieDb

suspend fun movieDetails(movieId: Int): Either<MovieDb>

suspend fun removeAllMovies(pagingKey: String)
suspend fun removeMovies(pagingKey: String)

suspend fun removeMovie(pagingKey: String, movieId: Int)

suspend fun insertMovies(pagingKey: String, movies: List<MovieResponse>)

suspend fun insertAllMovies(pagingKey: String, movies: List<MovieResponse>)
suspend fun insertMovie(pagingKey: String, movie: MovieDb)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.michaelbel.movies.interactor

import kotlinx.coroutines.flow.Flow
import org.michaelbel.movies.persistence.database.entity.SuggestionDb

interface SuggestionInteractor {

fun suggestions(): Flow<List<SuggestionDb>>

suspend fun updateSuggestions()
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import org.michaelbel.movies.interactor.NotificationInteractor
import org.michaelbel.movies.interactor.PagingKeyInteractor
import org.michaelbel.movies.interactor.SearchInteractor
import org.michaelbel.movies.interactor.SettingsInteractor
import org.michaelbel.movies.interactor.SuggestionInteractor
import org.michaelbel.movies.interactor.impl.AccountInteractorImpl
import org.michaelbel.movies.interactor.impl.AuthenticationInteractorImpl
import org.michaelbel.movies.interactor.impl.ImageInteractorImpl
Expand All @@ -21,6 +22,7 @@ import org.michaelbel.movies.interactor.impl.NotificationInteractorImpl
import org.michaelbel.movies.interactor.impl.PagingKeyInteractorImpl
import org.michaelbel.movies.interactor.impl.SearchInteractorImpl
import org.michaelbel.movies.interactor.impl.SettingsInteractorImpl
import org.michaelbel.movies.interactor.impl.SuggestionInteractorImpl

@Module
@InstallIn(SingletonComponent::class)
Expand Down Expand Up @@ -73,4 +75,10 @@ internal interface InteractorModule {
fun provideSettingsInteractor(
interactor: SettingsInteractorImpl
): SettingsInteractor

@Binds
@Singleton
fun provideSuggestionInteractor(
interactor: SuggestionInteractorImpl
): SuggestionInteractor
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.michaelbel.movies.interactor.impl
import androidx.paging.PagingSource
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext
import org.michaelbel.movies.common.dispatchers.MoviesDispatchers
import org.michaelbel.movies.interactor.MovieInteractor
Expand All @@ -22,9 +23,22 @@ internal class MovieInteractorImpl @Inject constructor(
return movieRepository.moviesPagingSource(pagingKey)
}

override suspend fun moviesResult(movieList: String, page: Int): Result<MovieResponse> {
override fun moviesFlow(pagingKey: String, limit: Int): Flow<List<MovieDb>> {
return movieRepository.moviesFlow(
pagingKey = pagingKey,
limit = limit
)
}

override suspend fun moviesResult(pagingKey: String, page: Int): Result<MovieResponse> {
return withContext(dispatchers.io) {
movieRepository.moviesResult(movieList, page)
movieRepository.moviesResult(pagingKey, page)
}
}

override suspend fun movie(pagingKey: String, movieId: Int): MovieDb {
return withContext(dispatchers.io) {
movieRepository.movie(pagingKey, movieId)
}
}

Expand All @@ -34,15 +48,27 @@ internal class MovieInteractorImpl @Inject constructor(
}
}

override suspend fun removeAllMovies(pagingKey: String) {
override suspend fun removeMovies(pagingKey: String) {
return withContext(dispatchers.io) {
movieRepository.removeMovies(pagingKey)
}
}

override suspend fun removeMovie(pagingKey: String, movieId: Int) {
return withContext(dispatchers.io) {
movieRepository.removeMovie(pagingKey, movieId)
}
}

override suspend fun insertMovies(pagingKey: String, movies: List<MovieResponse>) {
return withContext(dispatchers.io) {
movieRepository.removeAllMovies(pagingKey)
movieRepository.insertMovies(pagingKey, movies)
}
}

override suspend fun insertAllMovies(pagingKey: String, movies: List<MovieResponse>) {
override suspend fun insertMovie(pagingKey: String, movie: MovieDb) {
return withContext(dispatchers.io) {
movieRepository.insertAllMovies(pagingKey, movies)
movieRepository.insertMovie(pagingKey, movie)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.michaelbel.movies.interactor.impl

import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.withContext
import org.michaelbel.movies.common.dispatchers.MoviesDispatchers
import org.michaelbel.movies.interactor.SuggestionInteractor
import org.michaelbel.movies.persistence.database.entity.SuggestionDb
import org.michaelbel.movies.repository.SuggestionRepository

@Singleton
internal class SuggestionInteractorImpl @Inject constructor(
private val dispatchers: MoviesDispatchers,
private val suggestionRepository: SuggestionRepository
): SuggestionInteractor {

override fun suggestions(): Flow<List<SuggestionDb>> {
return suggestionRepository.suggestions()
}

override suspend fun updateSuggestions() {
withContext(dispatchers.io) {
suggestionRepository.updateSuggestions()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import org.michaelbel.movies.persistence.database.dao.AccountDao
import org.michaelbel.movies.persistence.database.dao.ImageDao
import org.michaelbel.movies.persistence.database.dao.MovieDao
import org.michaelbel.movies.persistence.database.dao.PagingKeyDao
import org.michaelbel.movies.persistence.database.dao.SuggestionDao
import org.michaelbel.movies.persistence.database.entity.AccountDb
import org.michaelbel.movies.persistence.database.entity.ImageDb
import org.michaelbel.movies.persistence.database.entity.MovieDb
import org.michaelbel.movies.persistence.database.entity.PagingKeyDb
import org.michaelbel.movies.persistence.database.entity.SuggestionDb

/**
* The Room database for this app.
Expand All @@ -24,7 +26,8 @@ import org.michaelbel.movies.persistence.database.entity.PagingKeyDb
MovieDb::class,
ImageDb::class,
AccountDb::class,
PagingKeyDb::class
PagingKeyDb::class,
SuggestionDb::class
],
version = AppDatabase.DATABASE_VERSION,
exportSchema = false
Expand All @@ -36,10 +39,11 @@ internal abstract class AppDatabase: RoomDatabase() {
abstract fun imageDao(): ImageDao
abstract fun accountDao(): AccountDao
abstract fun pagingKeyDao(): PagingKeyDao
abstract fun suggestionDao(): SuggestionDao

companion object {
private val DATABASE_NAME: String = if (BuildConfig.DEBUG) "movies-db-debug" else "movies-db"
const val DATABASE_VERSION = 18
const val DATABASE_VERSION = 19

@Volatile
private var instance: AppDatabase? = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import kotlinx.coroutines.flow.Flow
import org.michaelbel.movies.persistence.database.entity.MovieDb

/**
Expand All @@ -16,15 +17,30 @@ interface MovieDao {
@Query("SELECT * FROM movies WHERE movieList = :movieList ORDER BY position ASC")
fun pagingSource(movieList: String): PagingSource<Int, MovieDb>

@Query("SELECT * FROM movies WHERE movieList = :movieList ORDER BY position DESC LIMIT :limit")
fun moviesFlow(movieList: String, limit: Int): Flow<List<MovieDb>>

@Query("SELECT * FROM movies WHERE movieList = :movieList ORDER BY position ASC LIMIT :limit")
suspend fun movies(movieList: String, limit: Int): List<MovieDb>

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertMovies(movies: List<MovieDb>)

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insertAllMovies(movies: List<MovieDb>)
suspend fun insertMovie(movie: MovieDb)

@Query("DELETE FROM movies WHERE movieList = :movieList")
suspend fun removeAllMovies(movieList: String)
suspend fun removeMovies(movieList: String)

@Query("DELETE FROM movies WHERE movieList = :movieList AND id = :movieId")
suspend fun removeMovie(movieList: String, movieId: Int)

@Query("SELECT * FROM movies WHERE id = :movieId")
suspend fun movieById(movieId: Int): MovieDb?

@Query("SELECT * FROM movies WHERE movieList = :pagingKey AND id = :movieId")
suspend fun movieById(pagingKey: String, movieId: Int): MovieDb?

@Query("SELECT MAX(position) FROM movies WHERE movieList = :movieList")
suspend fun maxPosition(movieList: String): Int?

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package org.michaelbel.movies.persistence.database.dao

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import kotlinx.coroutines.flow.Flow
import org.michaelbel.movies.persistence.database.entity.SuggestionDb

/**
* The Data Access Object for the [SuggestionDb] class.
*/
@Dao
interface SuggestionDao {

@Query("SELECT * FROM suggestions")
fun suggestionsFlow(): Flow<List<SuggestionDb>>

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(suggestions: List<SuggestionDb>)

@Query("DELETE FROM suggestions")
suspend fun removeAll()
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import org.michaelbel.movies.persistence.database.dao.AccountDao
import org.michaelbel.movies.persistence.database.dao.ImageDao
import org.michaelbel.movies.persistence.database.dao.MovieDao
import org.michaelbel.movies.persistence.database.dao.PagingKeyDao
import org.michaelbel.movies.persistence.database.dao.SuggestionDao

@Module
@InstallIn(SingletonComponent::class)
Expand All @@ -34,4 +35,7 @@ internal object DatabaseModule {

@Provides
fun providePagingKeyDao(appDatabase: AppDatabase): PagingKeyDao = appDatabase.pagingKeyDao()

@Provides
fun provideSuggestionDao(appDatabase: AppDatabase): SuggestionDao = appDatabase.suggestionDao()
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ data class MovieDb(
) {
companion object {
const val MOVIES_LOCAL_LIST = "movies_local"
const val MOVIES_SEARCH_HISTORY = "movies_search_history"

val Empty: MovieDb = MovieDb(
movieList = "",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.michaelbel.movies.persistence.database.entity

import androidx.room.Entity
import org.jetbrains.annotations.NotNull

@Entity(tableName = "suggestions", primaryKeys = ["title"])
data class SuggestionDb(
@NotNull val title: String
)
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package org.michaelbel.movies.persistence.database.ktx

import java.util.Locale
import org.michaelbel.movies.network.TMDB_MOVIE_URL
import org.michaelbel.movies.persistence.database.entity.MovieDb
import java.util.Locale

val MovieDb.isNotEmpty: Boolean
get() = this != MovieDb.Empty

val MovieDb.url: String
get() = String.format(Locale.US, TMDB_MOVIE_URL, movieId)
get() = String.format(Locale.US, TMDB_MOVIE_URL, movieId)

val MovieDb?.orEmpty: MovieDb
get() = this ?: MovieDb.Empty
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.michaelbel.movies.repository

import androidx.paging.PagingSource
import kotlinx.coroutines.flow.Flow
import org.michaelbel.movies.network.Either
import org.michaelbel.movies.network.model.MovieResponse
import org.michaelbel.movies.network.model.Result
Expand All @@ -10,11 +11,19 @@ interface MovieRepository {

fun moviesPagingSource(pagingKey: String): PagingSource<Int, MovieDb>

fun moviesFlow(pagingKey: String, limit: Int): Flow<List<MovieDb>>

suspend fun moviesResult(movieList: String, page: Int): Result<MovieResponse>

suspend fun movie(pagingKey: String, movieId: Int): MovieDb

suspend fun movieDetails(movieId: Int): Either<MovieDb>

suspend fun removeAllMovies(pagingKey: String)
suspend fun removeMovies(pagingKey: String)

suspend fun removeMovie(pagingKey: String, movieId: Int)

suspend fun insertMovies(pagingKey: String, movies: List<MovieResponse>)

suspend fun insertAllMovies(pagingKey: String, movies: List<MovieResponse>)
suspend fun insertMovie(pagingKey: String, movie: MovieDb)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.michaelbel.movies.repository

import kotlinx.coroutines.flow.Flow
import org.michaelbel.movies.persistence.database.entity.SuggestionDb

interface SuggestionRepository {

fun suggestions(): Flow<List<SuggestionDb>>

suspend fun updateSuggestions()
}
Loading

0 comments on commit f1f2094

Please sign in to comment.