Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
871a29c
feat: add BottomNavigation bar
KevinMartinezC Apr 26, 2023
fd17006
feat: add login screen and logic to make a request to get the correct…
KevinMartinezC Apr 26, 2023
0dc10a3
feat: get api key save it with SharedPreference to search movies
KevinMartinezC Apr 27, 2023
38def3b
feat: make a ModalNavigationDrawer to be able to logout
KevinMartinezC Apr 27, 2023
aceb2d6
feat: get the last login date and updating code
KevinMartinezC Apr 27, 2023
cba39a5
feat: add icon and fixing to don't close the session when the app res…
KevinMartinezC Apr 27, 2023
95aa867
feat: add extra data to get from the API to show in the DetailScreen
KevinMartinezC Apr 27, 2023
44c006d
feat: remove the viewModel from the MoviesScreen and add MovieUiState
KevinMartinezC Apr 28, 2023
dbc10f6
feat: show BottomSheet when a item is clicked
KevinMartinezC Apr 28, 2023
b1c7651
feat: improve DetailScreen Design and organize code
KevinMartinezC Apr 28, 2023
239b7fc
feat: add fravorite screen and save item selected in room database
KevinMartinezC Apr 28, 2023
8b545d4
feat: add functionality to delete the favorite movies add it when the…
KevinMartinezC Apr 28, 2023
be37459
feat: show the movies add it in the FavoriteScreen with animation
KevinMartinezC Apr 28, 2023
a0cec01
feat: show a bottomsheet with the details of movies when the image is…
KevinMartinezC Apr 28, 2023
fb9c7d0
feat: add MovieDetails to the design to the BottomSheet information
KevinMartinezC Apr 28, 2023
a5dabf8
feat: organize code
KevinMartinezC Apr 28, 2023
7f3a941
feat: organize code
KevinMartinezC Apr 28, 2023
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
34 changes: 19 additions & 15 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("com.google.devtools.ksp")



}

android {
Expand Down Expand Up @@ -30,11 +34,11 @@ android {
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "1.8"
jvmTarget = "17"
}
buildFeatures {
compose = true
Expand All @@ -50,15 +54,19 @@ android {
}

dependencies {

val navVersion = "2.5.3"
val lifecycleVersion = "2.6.1"
val roomVersion = "2.5.1"
implementation("androidx.core:core-ktx:1.10.0")
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1")
implementation("androidx.activity:activity-compose:1.7.1")
implementation(platform("androidx.compose:compose-bom:2023.03.00"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.material3:material3:1.1.0-rc01")
implementation("androidx.compose.material3:material3-window-size-class:1.0.1")
implementation("androidx.compose.material:material:1.4.2")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
Expand All @@ -70,24 +78,20 @@ dependencies {
implementation ("com.squareup.retrofit2:converter-gson:2.9.0")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4")
// Lifecycle
val lifecycleVersion = "2.6.1"
// ViewModel
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion")
// ViewModel utilities for Compose
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycleVersion")
// LiveData
implementation("androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion")
// Lifecycles only (without ViewModel or LiveData)
implementation("androidx.lifecycle:lifecycle-runtime-ktx:$lifecycleVersion")
// Lifecycle utilities for Compose
implementation("androidx.lifecycle:lifecycle-viewmodel-compose:$lifecycleVersion")

implementation ("io.coil-kt:coil-compose:2.3.0")
implementation("androidx.navigation:navigation-compose:$navVersion")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4")
implementation("androidx.room:room-runtime:$roomVersion")
annotationProcessor("androidx.room:room-compiler:$roomVersion")
implementation("androidx.room:room-ktx:$roomVersion")
ksp("androidx.room:room-compiler:2.5.1")

val navVersion = "2.5.3"

implementation("androidx.navigation:navigation-compose:$navVersion")



Expand Down
47 changes: 0 additions & 47 deletions app/src/main/java/com/example/moviesvapp/components/MovieItem.kt

This file was deleted.

2 changes: 1 addition & 1 deletion app/src/main/java/com/example/moviesvapp/model/Movie.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ data class Movie(
@SerializedName("Type")
val type: String,
@SerializedName("Poster")
val poster: String
val poster: String,
)
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
package com.example.moviesvapp.model

data class MoviesResponse(val Search: List<Movie>, val totalResults: String, val Response: String)
import com.google.gson.annotations.SerializedName

data class MoviesResponse(
@SerializedName("Search")
val search: List<Movie>,
val totalResults: String,
@SerializedName("Response")
val response: String
)

40 changes: 0 additions & 40 deletions app/src/main/java/com/example/moviesvapp/model/MoviesViewModel.kt

This file was deleted.

8 changes: 8 additions & 0 deletions app/src/main/java/com/example/moviesvapp/model/Resource.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.example.moviesvapp.model

sealed class Resource<out T> {
data class Success<out T>(val data: T) : Resource<T>()
data class Error(val message: String) : Resource<Nothing>()
object Loading : Resource<Nothing>()
object Idle : Resource<Nothing>()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.example.moviesvapp.model

import android.content.SharedPreferences
import android.os.Build
import androidx.annotation.RequiresApi
import com.example.moviesvapp.model.SharedPreferencesExtensionsKey.API_KEY
import com.example.moviesvapp.model.SharedPreferencesExtensionsKey.LAST_LOGIN_DATE
import com.example.moviesvapp.model.SharedPreferencesExtensionsKey.USER_NAME
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter


fun SharedPreferences.saveUsername(username: String) {
edit().putString("USERNAME", username).apply()
}

fun SharedPreferences.getUsername(): String? {
return getString("USERNAME", null)
}

fun SharedPreferences.saveApiKey(apiKey: String) {
edit().putString("API_KEY", apiKey).apply()
}

fun SharedPreferences.getApiKey(): String? {
return getString(API_KEY, null)
}

fun SharedPreferences.clearUsername() {
edit().remove(USER_NAME).apply()
}

fun SharedPreferences.clearApiKey() {
edit().remove(API_KEY).apply()
}

fun SharedPreferences.saveLastLoginDate(date: String) {
edit().putString(LAST_LOGIN_DATE, date).apply()
}

fun SharedPreferences.getLastLoginDate(): String? {
return getString(LAST_LOGIN_DATE, null)
}

fun SharedPreferences.clearLastLoginDate() {
edit().remove(LAST_LOGIN_DATE).apply()
}

@RequiresApi(Build.VERSION_CODES.O)
fun getCurrentDateTime(): String {
val currentDateTime = LocalDateTime.now()
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
return currentDateTime.format(formatter)
}

object SharedPreferencesExtensionsKey{
const val API_KEY ="API_KEY"
const val USER_NAME = "USERNAME"
const val LAST_LOGIN_DATE = "LAST_LOGIN_DATE"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.moviesvapp.model.database

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

@Entity(tableName = "favorite_movies")
data class FavoriteMovie(
@PrimaryKey
@ColumnInfo(name = "imdbID") val imdbID: String,
@ColumnInfo(name = "title") val title: String,
@ColumnInfo(name = "year") val year: String,
@ColumnInfo(name = "type") val type: String,
@ColumnInfo(name = "poster") val poster: String,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.moviesvapp.model.database

import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import kotlinx.coroutines.flow.Flow

@Dao
interface MovieDao {
@Query("SELECT * FROM favorite_movies")
fun getAll(): Flow<List<FavoriteMovie>>

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(favoriteMovie: FavoriteMovie)

@Delete
suspend fun delete(favoriteMovie: FavoriteMovie)

@Query("DELETE FROM favorite_movies")
suspend fun deleteAll()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.example.moviesvapp.model.database

import androidx.room.Database
import androidx.room.RoomDatabase

@Database(entities = [FavoriteMovie::class], version = 1)
abstract class MovieDatabase : RoomDatabase() {
abstract fun movieDao(): MovieDao
}
43 changes: 38 additions & 5 deletions app/src/main/java/com/example/moviesvapp/ui/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,19 +1,52 @@
package com.example.moviesvapp.ui

import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.lifecycle.viewmodel.compose.viewModel
import com.example.moviesvapp.components.MoviesScreen
import com.example.moviesvapp.model.MoviesViewModel
import androidx.annotation.RequiresApi
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import com.example.moviesvapp.ui.components.MainScreen
import com.example.moviesvapp.ui.components.home.viewmodel.MoviesViewModel
import com.example.moviesvapp.ui.components.login.LoginScreen
import com.example.moviesvapp.ui.components.login.viewmodel.LoginViewModel
import com.example.moviesvapp.ui.theme.MyApplicationTheme


class MainActivity : ComponentActivity() {
private lateinit var viewModel: LoginViewModel
private lateinit var moviesViewModel: MoviesViewModel

@RequiresApi(Build.VERSION_CODES.O)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = LoginViewModel(this)
moviesViewModel = MoviesViewModel(this)

setContent {
val viewModel: MoviesViewModel = viewModel()
MoviesScreen(viewModel)
MyApplicationTheme {
val lastLoginDate = viewModel.getLastLoginDate()
val uiState by viewModel.uiState.collectAsState()

if (!uiState.isLoggedIn) {
LoginScreen(
loginStatus = uiState.loginStatus,
onClickedLogin = viewModel::login,
onLogin = viewModel::saveCredentials,
)
} else {
MainScreen(
onLogout = {
viewModel.clearData()
moviesViewModel.clearFavoriteMovies()

},
username = uiState.userName,
lastLoginDate = lastLoginDate
)
}
}
}
}
}
Expand Down
Loading