Skip to content

Commit

Permalink
add Favorite, add switch theme
Browse files Browse the repository at this point in the history
  • Loading branch information
narayoga committed Oct 7, 2023
1 parent c816c1f commit a0a3a98
Show file tree
Hide file tree
Showing 24 changed files with 532 additions and 28 deletions.
17 changes: 17 additions & 0 deletions .idea/deploymentTargetDropDown.xml

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

15 changes: 15 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("kotlin-parcelize")
id("com.google.devtools.ksp")
}

android {
Expand Down Expand Up @@ -52,6 +53,8 @@ dependencies {
implementation ("com.squareup.picasso:picasso:2.8")

implementation ("androidx.lifecycle:lifecycle-runtime-ktx:2.4.0-rc01")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.6.1")
implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.6.1")

implementation("androidx.core:core-ktx:1.9.0")
implementation("androidx.appcompat:appcompat:1.6.1")
Expand All @@ -60,4 +63,16 @@ dependencies {
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")

val room_version = "2.5.2"
implementation ("androidx.room:room-runtime:$room_version")
annotationProcessor ("androidx.room:room-compiler:$room_version")
androidTestImplementation ("androidx.room:room-testing:$room_version")
implementation ("androidx.room:room-ktx:$room_version")
ksp("androidx.room:room-compiler:2.5.2")

implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0")
implementation ("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0")
implementation ("androidx.datastore:datastore-preferences-core:1.0.0")
implementation ("androidx.datastore:datastore-preferences:1.0.0")
}
3 changes: 3 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
android:supportsRtl="true"
android:theme="@style/Theme.GithubUser"
tools:targetApi="31">
<activity
android:name=".ui.FavoriteActivity"
android:exported="false" />
<activity
android:name=".ui.ProfileActivity"
android:exported="false" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.githubuser.data.model.local

import androidx.room.Entity
import androidx.room.PrimaryKey
import java.io.Serializable

@Entity(tableName = "favorite_list")
data class Favorite (
val login: String,
@PrimaryKey
val id: Int,
val avatar_url: String
): Serializable
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.example.githubuser.data.model.local

import androidx.lifecycle.LiveData
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.Query

@Dao
interface FavoriteDao {
@Insert
suspend fun addFavorite(favorite: Favorite)

@Query("SELECT * FROM favorite_list")
fun getFavorite(): LiveData<List<Favorite>>

@Query("SELECT count(*) FROM favorite_list WHERE favorite_list.id = :id")
suspend fun checkUser(id: Int): Int

@Query("DELETE FROM favorite_list WHERE favorite_list.id = :id")
suspend fun deleteUser(id: Int): Int
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.example.githubuser.data.model.local

import android.content.Context
import androidx.room.Database
import androidx.room.Room
import androidx.room.RoomDatabase

@Database(
version = 1,
entities = [Favorite::class]
)
abstract class FavoriteDatabase: RoomDatabase() {
companion object{
var INSTANCE : FavoriteDatabase? = null

fun getDatabase(context: Context): FavoriteDatabase?{
if(INSTANCE == null) {
synchronized(FavoriteDatabase::class) {
INSTANCE = Room.databaseBuilder(context.applicationContext, FavoriteDatabase::class.java, "favorite_database").build()
}
}
return INSTANCE
}
}
abstract fun favoriteDao() : FavoriteDao
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package com.example.githubuser.data.model.local

import android.content.Context
import androidx.datastore.core.DataStore
import androidx.datastore.preferences.core.Preferences
import androidx.datastore.preferences.core.booleanPreferencesKey
import androidx.datastore.preferences.core.edit
import androidx.datastore.preferences.preferencesDataStore
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
class SettingPreferences private constructor(private val dataStore: DataStore<Preferences>) {

private val THEME_KEY = booleanPreferencesKey("theme_setting")

fun getThemeSetting(): Flow<Boolean> {
return dataStore.data.map { preferences ->
preferences[THEME_KEY] ?: false
}
}

suspend fun saveThemeSetting(isDarkModeActive: Boolean) {
dataStore.edit { preferences ->
preferences[THEME_KEY] = isDarkModeActive
}
}

companion object {
@Volatile
private var INSTANCE: SettingPreferences? = null

fun getInstance(dataStore: DataStore<Preferences>): SettingPreferences {
return INSTANCE ?: synchronized(this) {
val instance = SettingPreferences(dataStore)
INSTANCE = instance
instance
}
}
}

}

//class SettingPreference private constructor(context: Context) {
// private val settingsDataStore = context.prefDataStore
// private val themeKEY = booleanPreferencesKey("theme_setting")
//
// fun getThemeSetting(): Flow<Boolean> =
// settingsDataStore.data.map { preferences ->
// preferences[themeKEY]?:false
// }
// suspend fun saveThemeSetting(isDarkModeActive: Boolean) {
// settingsDataStore.edit { preferences ->
// preferences[themeKEY] = isDarkModeActive
// }
// }
//}
12 changes: 7 additions & 5 deletions app/src/main/java/com/example/githubuser/data/networking/Api.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,30 +9,32 @@ import retrofit2.http.Headers
import retrofit2.http.Path
import retrofit2.http.Query

const val token = "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"
interface Api {
// search user
@GET("search/users")
@Headers("Authorization: token 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")
@Headers("Authorization: token $token")
fun getUsers(
@Query("q") query: String
): Call<User>

// detail user
@GET("users/{username}")
@Headers("Authorization: token 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")
@Headers("Authorization: token $token")
fun getProfile(
@Path("username") username: String?
): Call<Profile>

@GET("users/{username}/followers")
@Headers("Authorization: token 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")
@Headers("Authorization: token $token")
fun getFollowers(
@Path("username") username: String
): Call<ArrayList<UserDetail>>

@GET("users/{username}/following")
@Headers("Authorization: token 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")
@Headers("Authorization: token $token")
fun getFollowing(
@Path("username") username: String
): Call<ArrayList<UserDetail>>
}
}

75 changes: 75 additions & 0 deletions app/src/main/java/com/example/githubuser/ui/FavoriteActivity.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package com.example.githubuser.ui

import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.MenuItem
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.githubuser.R
import com.example.githubuser.data.model.UserDetail
import com.example.githubuser.data.model.local.Favorite
import com.example.githubuser.databinding.ActivityFavoriteBinding

class FavoriteActivity : AppCompatActivity() {

private lateinit var binding: ActivityFavoriteBinding
private lateinit var viewModel: FavoriteViewModel
private lateinit var adapter: UserAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityFavoriteBinding.inflate(layoutInflater)
setContentView(binding.root)
supportActionBar?.setDisplayHomeAsUpEnabled(true)

adapter = UserAdapter()
adapter.notifyDataSetChanged()

viewModel = ViewModelProvider(this)[FavoriteViewModel::class.java]

adapter.setOnItemClickFunction(object :UserAdapter.OnItemClickCallback {
override fun onFunctionClicked(data: UserDetail) {
Intent(this@FavoriteActivity, ProfileActivity::class.java).also {
it.putExtra(ProfileActivity.EXTRA_USERNAME, data.login)
it.putExtra(ProfileActivity.EXTRA_ID, data.id)
it.putExtra(ProfileActivity.EXTRA_URL, data.avatar_url)
startActivity(it)
}
}
})

binding.apply {
rvUserFavorite.setHasFixedSize(true)
rvUserFavorite.layoutManager = LinearLayoutManager(this@FavoriteActivity)
rvUserFavorite.adapter = adapter
}

viewModel.getFavorite()?.observe(this, {
if(it != null) {
val list = mapList(it)
adapter.setList(list)
}
})
}
private fun mapList(it: List<Favorite>): ArrayList<UserDetail> {
val list = ArrayList<UserDetail>()
for (user in it) {
val userMapped = UserDetail(
user.login,
user.id,
user.avatar_url
)
list.add(userMapped)
}
return list
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
android.R.id.home -> {
finish()
}
}
return super.onOptionsItemSelected(item)
}
}
22 changes: 22 additions & 0 deletions app/src/main/java/com/example/githubuser/ui/FavoriteViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.githubuser.ui

import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import com.example.githubuser.data.model.local.Favorite
import com.example.githubuser.data.model.local.FavoriteDao
import com.example.githubuser.data.model.local.FavoriteDatabase

class FavoriteViewModel(application: Application): AndroidViewModel(application) {
private var userDao: FavoriteDao?
private var userDb: FavoriteDatabase?

init {
userDb = FavoriteDatabase.getDatabase(application)
userDao = userDb?.favoriteDao()
}

fun getFavorite():LiveData<List<Favorite>>? {
return userDao?.getFavorite()
}
}
Loading

0 comments on commit a0a3a98

Please sign in to comment.