Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
236a5fb
feat: add top rated movies
ahmedhgabr Jul 15, 2025
2395019
feat: di database
ahmedhgabr Jul 15, 2025
851355d
style: sort the functions
ahmedhgabr Jul 15, 2025
48fcc37
feat: search in local by name
ahmedhgabr Jul 15, 2025
32b7e84
feat: top rated local
ahmedhgabr Jul 15, 2025
362ee23
Merge branch 'develop' into feat/local-db-in-prod
ahmedhgabr Jul 15, 2025
125df9f
fix: merge conflict import
ahmedhgabr Jul 15, 2025
2f0a7e4
feat: add most searched categories
ahmedhgabr Jul 15, 2025
d13591b
feat: add recent search
ahmedhgabr Jul 15, 2025
b53d5a9
Merge branch 'develop' into feat/local-db-in-prod
ahmedhgabr Jul 15, 2025
b467427
fix: recent search ksp error
ahmedhgabr Jul 16, 2025
2fb1603
refactor api response
Mousaber00 Jul 16, 2025
f431925
Merge branch 'refactor/remote-data-source' into feat/local-db-in-prod
ahmedhgabr Jul 16, 2025
ec4eb77
refactor: change search datasource
ahmedhgabr Jul 16, 2025
3ac19f5
refactor: remove flow from local
ahmedhgabr Jul 16, 2025
21c7113
Merge branch 'develop' into feat/local-db-in-prod
ahmedhgabr Jul 17, 2025
b69a052
fix: missing import
ahmedhgabr Jul 17, 2025
aed299e
refactor: put interfaces in packge
ahmedhgabr Jul 17, 2025
c940b16
refactor : delete unused files
fatimafaisalghazi Jul 17, 2025
4e2b702
refactor : Movio card size
fatimafaisalghazi Jul 17, 2025
63768dc
refactor :search card size
fatimafaisalghazi Jul 17, 2025
19d61b1
refactor : add search interactionListener
fatimafaisalghazi Jul 17, 2025
75d57c3
refactor : use stringresource
fatimafaisalghazi Jul 17, 2025
53fe4ef
refactor : search screen to make it accept theme
fatimafaisalghazi Jul 17, 2025
e4e13f0
refactor : add statusBarsPadding
fatimafaisalghazi Jul 17, 2025
d07bf63
finalize data source
Mousaber00 Jul 17, 2025
b03784f
Merge remote-tracking branch 'origin/feature/data-source' into refact…
Mohamedragabali Jul 17, 2025
e89ae41
refactor search screen in presentation
Mohamedragabali Jul 17, 2025
655e154
Merge remote-tracking branch 'origin/feat/local-db-in-prod' into refa…
Mohamedragabali Jul 17, 2025
cd60d59
refactor search screen in artists
Mohamedragabali Jul 18, 2025
a3cb06e
Merge branch 'develop' into refactor/search-screen-ui
Mohamedragabali Jul 18, 2025
271aa7d
refactor search screen
Mohamedragabali Jul 18, 2025
3308761
style: white space
ahmedhgabr Jul 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ dependencies {
implementation("com.google.firebase:firebase-analytics")
implementation(platform("com.google.firebase:firebase-bom:33.16.0"))
implementation("com.google.firebase:firebase-crashlytics-ndk")
implementation(libs.firebase.crashlytics.buildtools)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
Expand Down
17 changes: 10 additions & 7 deletions app/src/main/java/com/madrid/movio/app.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.madrid.movio


import com.madrid.data.dataSource.local.SearchLocalDataSource
import com.madrid.data.dataSource.remote.search.SearchRemoteSourceImpl
import com.madrid.data.repositories.SearchLocalSource
import com.madrid.data.repositories.SearchRemoteSource
import com.madrid.data.dataSource.local.MovioDatabase
import com.madrid.data.repositories.SearchRepositoryImpl
import com.madrid.data.repositories.local.LocalDataSource
import com.madrid.data.repositories.local.LocalDataSourceImpl
import com.madrid.detectImageContent.GetImageBitmap
import com.madrid.detectImageContent.SensitiveContentDetection
import com.madrid.domain.repository.SearchRepository
Expand All @@ -15,6 +14,7 @@ import com.madrid.domain.usecase.searchUseCase.PreferredMediaUseCase
import com.madrid.domain.usecase.searchUseCase.RecentSearchUseCase
import com.madrid.domain.usecase.searchUseCase.TrendingMediaUseCase
import com.madrid.presentation.screens.searchScreen.viewModel.SearchViewModel
import org.koin.android.ext.koin.androidContext
import org.koin.androidx.viewmodel.dsl.viewModel
import org.koin.dsl.module

Expand All @@ -23,8 +23,11 @@ val app = module {

// data
single<SearchRepository> { SearchRepositoryImpl(get(), get()) }
single<SearchLocalSource> { SearchLocalDataSource(get()) }
single<SearchRemoteSource> { SearchRemoteSourceImpl() }
single<LocalDataSource> { LocalDataSourceImpl(get()) }


single { MovioDatabase.getInstance(androidContext()) }


// presentation
viewModel {
Expand All @@ -40,7 +43,7 @@ val app = module {
//domain
single { ArtistUseCase(get()) }
single { MediaUseCase(get()) }
single{ PreferredMediaUseCase(get()) }
single { PreferredMediaUseCase(get()) }
single { RecentSearchUseCase(get()) }
single { TrendingMediaUseCase(get()) }
// detectImageContent
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/java/com/madrid/movio/data.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
package com.madrid.movio

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.madrid.data.dataSource.remote.movies
package com.madrid.data

import com.madrid.data.BuildConfig.API_KEY
import com.madrid.data.BuildConfig.BASE_URL
Expand All @@ -10,33 +10,29 @@ import io.ktor.client.plugins.defaultRequest
import io.ktor.client.request.get
import io.ktor.client.request.header
import io.ktor.client.statement.HttpResponse
import io.ktor.client.statement.bodyAsText
import io.ktor.http.URLBuilder
import io.ktor.http.URLProtocol.Companion.HTTPS
import io.ktor.http.encodedPath
import kotlinx.serialization.json.Json

class MoviesApiImpl() : MoviesApi {
class CustomHttpClient {
suspend fun buildHttpClient(
urlBuilder: URLBuilder.() -> Unit
): HttpResponse {
return HttpClient(CIO) {
defaultRequest {
header("accept", "application/json")

private val client = HttpClient(CIO) {
defaultRequest {
header("accept", "application/json")
}
}
val json = Json {
ignoreUnknownKeys = true
}

override suspend fun getTopRatedMovies(language: String, page: Int): HttpResponse {
val result = client.get {
}
}.get {
url {
protocol = HTTPS
host = BASE_URL
encodedPath = "movie/top_rated"
parameters.append("language", "en-US")
parameters.append(PAGE, "1")
parameters.append(KEY, API_KEY)
apply(urlBuilder)
}
}
return json.decodeFromString<HttpResponse>(result.bodyAsText())

}
}

}
23 changes: 19 additions & 4 deletions data/src/main/java/com/madrid/data/DiModule.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
package com.madrid.data

import android.app.Application
import androidx.room.Room
import com.madrid.data.dataSource.remote.utils.Constants.PAGE
import com.madrid.data.repositories.remote.RemoteDataSource
import com.madrid.data.repositories.remote.RemoteDataSourceImpl
import io.ktor.client.HttpClient
import io.ktor.client.HttpClientConfig
import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.engine.cio.CIO
import io.ktor.client.engine.cio.CIOEngineConfig
import io.ktor.client.plugins.contentnegotiation.ContentNegotiation
import io.ktor.client.plugins.defaultRequest
import io.ktor.client.request.header
import io.ktor.serialization.kotlinx.json.json
import kotlinx.serialization.json.Json
import org.koin.dsl.module

val roomModule = module {

}
single<RemoteDataSource> { RemoteDataSourceImpl(get(), get()) }
single { Json { ignoreUnknownKeys = true } }
single { CustomHttpClient() }
single<HttpClientEngine> { CIO.create() }
single<HttpClientConfig<CIOEngineConfig>> { HttpClientConfig() }
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@ import androidx.room.RoomDatabase
import com.madrid.data.dataSource.local.dao.ArtistDao
import com.madrid.data.dataSource.local.dao.CategoryDao
import com.madrid.data.dataSource.local.dao.MovieDao
import com.madrid.data.dataSource.local.dao.RecentSearchDao
import com.madrid.data.dataSource.local.dao.SeriesDao
import com.madrid.data.dataSource.local.entity.ArtistEntity
import com.madrid.data.dataSource.local.entity.MovieCategoryEntity
import com.madrid.data.dataSource.local.entity.MovieEntity
import com.madrid.data.dataSource.local.entity.SeriesEntity
import com.madrid.data.dataSource.local.entity.RecentSearchEntity

@Database(
entities = [
MovieEntity::class,
SeriesEntity::class,
MovieCategoryEntity::class,
ArtistEntity::class
ArtistEntity::class,
RecentSearchEntity::class
],
version = 1
)
Expand All @@ -28,6 +31,7 @@ abstract class MovioDatabase : RoomDatabase() {
abstract fun seriesDao(): SeriesDao
abstract fun movieCategoryDao(): CategoryDao
abstract fun artistDao(): ArtistDao
abstract fun recentSearchDao(): RecentSearchDao

companion object {
const val DATABASE_NAME = "MOVIO_DATABASE"
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import androidx.room.Delete
import androidx.room.Insert
import androidx.room.Query
import com.madrid.data.dataSource.local.entity.ArtistEntity
import com.madrid.data.dataSource.local.entity.MovieEntity
import kotlinx.coroutines.flow.Flow

@Dao
interface ArtistDao {
Expand All @@ -18,13 +16,13 @@ interface ArtistDao {
suspend fun deleteArtist(artist: ArtistEntity)

@Query("SELECT * FROM ARTIST_TABLE WHERE id = :id")
fun getArtistById(id: Int): Flow<ArtistEntity?>
fun getArtistById(id: Int): ArtistEntity?

@Query("SELECT * FROM ARTIST_TABLE WHERE name LIKE :name")
fun getArtistByName(name: String): Flow<List<ArtistEntity>>
fun getArtistByName(name: String): List<ArtistEntity>

@Query("SELECT * FROM ARTIST_TABLE")
fun getAllArtists(): Flow<List<ArtistEntity>>
fun getAllArtists(): List<ArtistEntity>

@Query("DELETE FROM ARTIST_TABLE")
suspend fun deleteAllArtists()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.madrid.data.dataSource.local.entity.MovieCategoryEntity
import kotlinx.coroutines.flow.Flow


@Dao
Expand All @@ -19,17 +18,17 @@ interface CategoryDao {
suspend fun deleteCategory(category: MovieCategoryEntity)

@Query("SELECT * FROM CATEGORY_TABLE WHERE id = :id")
fun getCategoryById(id: Int): Flow<MovieCategoryEntity?>
fun getCategoryById(id: Int): MovieCategoryEntity?

@Query("SELECT * FROM CATEGORY_TABLE WHERE title = :title")
fun getCategoryByTitle(title: String): Flow<List<MovieCategoryEntity>>
fun getCategoryByTitle(title: String): List<MovieCategoryEntity>

@Query("SELECT * FROM CATEGORY_TABLE")
fun getAllCategories(): Flow<List<MovieCategoryEntity>>
fun getAllCategories(): List<MovieCategoryEntity>

// descending order by searchCount
@Query("SELECT * FROM CATEGORY_TABLE ORDER BY searchCount DESC")
fun getAllCategoriesBySearchCount(): Flow<List<MovieCategoryEntity>>
fun getAllCategoriesBySearchCount(): List<MovieCategoryEntity>

@Query("DELETE FROM CATEGORY_TABLE")
suspend fun deleteAllCategories()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import androidx.room.OnConflictStrategy
import androidx.room.Query
import androidx.room.Update
import com.madrid.data.dataSource.local.entity.MovieEntity
import kotlinx.coroutines.flow.Flow

@Dao
interface MovieDao {
Expand All @@ -22,16 +21,16 @@ interface MovieDao {
suspend fun updateMovie(movie: MovieEntity)

@Query("SELECT * FROM MOVIE_TABLE WHERE id = :id")
fun getMovieById(id: Int): Flow<MovieEntity?>
fun getMovieById(id: Int): MovieEntity?

@Query("SELECT * FROM MOVIE_TABLE WHERE title LIKE :title")
fun getMovieByTitle(title: String): Flow<List<MovieEntity>>
fun getMovieByTitle(title: String): List<MovieEntity>

@Query("SELECT * FROM MOVIE_TABLE ORDER BY rate DESC")
fun getTopRatedMovies(): Flow<List<MovieEntity>>
fun getTopRatedMovies(): List<MovieEntity>

@Query("SELECT * FROM MOVIE_TABLE")
fun getAllMovies(): Flow<List<MovieEntity>>
fun getAllMovies(): List<MovieEntity>

@Query("DELETE FROM MOVIE_TABLE")
suspend fun deleteAllMovies()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.madrid.data.dataSource.local.dao

import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.madrid.data.dataSource.local.entity.RecentSearchEntity

@Dao
interface RecentSearchDao {
@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun addRecentSearch(query: RecentSearchEntity)

@Query("SELECT * FROM RECENT_TABLE")
fun getRecentSearches(): List<RecentSearchEntity>

@Query("DELETE FROM RECENT_TABLE WHERE searchQuery = :query")
suspend fun removeRecentSearch(query: String)

@Query("DELETE FROM RECENT_TABLE")
suspend fun clearAllRecentSearches()
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.madrid.data.dataSource.local.entity.MovieEntity
import com.madrid.data.dataSource.local.entity.SeriesEntity
import kotlinx.coroutines.flow.Flow

@Dao
interface SeriesDao {
Expand All @@ -22,10 +20,13 @@ interface SeriesDao {
fun getSeriesById(id: Int): SeriesEntity?

@Query("SELECT * FROM SERIES_TABLE WHERE title LIKE :title")
fun getSeriesByTitle(title: String): Flow<List<SeriesEntity>>
fun getSeriesByTitle(title: String): List<SeriesEntity>

@Query("SELECT * FROM SERIES_TABLE ORDER BY rate DESC")
fun getTopRatedSeries(): List<SeriesEntity>

@Query("SELECT * FROM SERIES_TABLE")
fun getAllSeries(): Flow<List<SeriesEntity>>
fun getAllSeries(): List<SeriesEntity>

@Query("DELETE FROM SERIES_TABLE")
suspend fun deleteAllSeries()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.madrid.data.dataSource.local.entity

import androidx.room.Entity
import androidx.room.PrimaryKey


@Entity(tableName = "RECENT_TABLE")
data class RecentSearchEntity(
@PrimaryKey(autoGenerate = false) val searchQuery: String,
val timestamp: Long = System.currentTimeMillis()
)
Loading
Loading