Skip to content

Commit

Permalink
Merge pull request #7 from paulcoding810/feat/add-favorite
Browse files Browse the repository at this point in the history
Implement favorite feature
  • Loading branch information
paulcoding810 authored Dec 3, 2024
2 parents df4b381 + c764c4e commit 9f421e6
Show file tree
Hide file tree
Showing 20 changed files with 449 additions and 21 deletions.
9 changes: 9 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
id("com.google.devtools.ksp")
}

android {
Expand Down Expand Up @@ -81,11 +82,19 @@ dependencies {
implementation(libs.ktor.client.content.negotiation)
implementation(libs.ktor.client.logging)

implementation(libs.androidx.room.runtime)
ksp(libs.androidx.room.compiler)
implementation(libs.androidx.room.ktx)

testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}

ksp {
arg("room.schemaLocation", "$projectDir/schemas")
}
52 changes: 52 additions & 0 deletions app/schemas/com.paulcoding.hviewer.database.AppDatabase/1.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"formatVersion": 1,
"database": {
"version": 1,
"identityHash": "f8c3310b39b34e0c6c9c004f8557d416",
"entities": [
{
"tableName": "favorite_posts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `name` TEXT NOT NULL, `thumbnail` TEXT NOT NULL, `site` TEXT NOT NULL, PRIMARY KEY(`url`))",
"fields": [
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "thumbnail",
"columnName": "thumbnail",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "site",
"columnName": "site",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"url"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f8c3310b39b34e0c6c9c004f8557d416')"
]
}
}
52 changes: 52 additions & 0 deletions app/schemas/com.paulcoding.hviewer.database.AppDatabase/2.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
{
"formatVersion": 1,
"database": {
"version": 2,
"identityHash": "f8c3310b39b34e0c6c9c004f8557d416",
"entities": [
{
"tableName": "favorite_posts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `name` TEXT NOT NULL, `thumbnail` TEXT NOT NULL, `site` TEXT NOT NULL, PRIMARY KEY(`url`))",
"fields": [
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "thumbnail",
"columnName": "thumbnail",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "site",
"columnName": "site",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"url"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f8c3310b39b34e0c6c9c004f8557d416')"
]
}
}
58 changes: 58 additions & 0 deletions app/schemas/com.paulcoding.hviewer.database.AppDatabase/3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "40109ede6ba29fdee1d23735114a2981",
"entities": [
{
"tableName": "favorite_posts",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`url` TEXT NOT NULL, `name` TEXT NOT NULL, `thumbnail` TEXT NOT NULL, `site` TEXT NOT NULL, `createdAt` INTEGER NOT NULL, PRIMARY KEY(`url`))",
"fields": [
{
"fieldPath": "url",
"columnName": "url",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "thumbnail",
"columnName": "thumbnail",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "site",
"columnName": "site",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "createdAt",
"columnName": "createdAt",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"url"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '40109ede6ba29fdee1d23735114a2981')"
]
}
}
10 changes: 10 additions & 0 deletions app/src/main/java/com/paulcoding/hviewer/database/AppDatabase.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.paulcoding.hviewer.database

import androidx.room.Database
import androidx.room.RoomDatabase
import com.paulcoding.hviewer.model.PostItem

@Database(entities = [PostItem::class], version = 3, exportSchema = true)
abstract class AppDatabase : RoomDatabase() {
abstract fun favoritePostDao(): FavoritePostDao
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.paulcoding.hviewer.database

import androidx.room.Room
import com.paulcoding.hviewer.MainApp.Companion.appContext

object DatabaseProvider {
private var db: AppDatabase? = null

fun getInstance(): AppDatabase {
if (db == null) {
db = Room.databaseBuilder(
appContext,
AppDatabase::class.java, "hviewer_db"
)
.addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.build()
}
return db!!
}
}
21 changes: 21 additions & 0 deletions app/src/main/java/com/paulcoding/hviewer/database/FavoriteDao.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.paulcoding.hviewer.database

import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import com.paulcoding.hviewer.model.PostItem
import kotlinx.coroutines.flow.Flow

@Dao
interface FavoritePostDao {
@Query("SELECT * FROM favorite_posts ORDER BY createdAt DESC")
fun getAll(): Flow<List<PostItem>>

@Insert(onConflict = OnConflictStrategy.REPLACE)
suspend fun insert(post: PostItem)

@Delete
suspend fun delete(post: PostItem)
}
16 changes: 16 additions & 0 deletions app/src/main/java/com/paulcoding/hviewer/database/Migrations.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.paulcoding.hviewer.database

import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase

val MIGRATION_1_2 = object : Migration(1, 2) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE favorite_posts ADD COLUMN site TEXT NOT NULL DEFAULT \"\"")
}
}

val MIGRATION_2_3 = object : Migration(2, 3) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE favorite_posts ADD COLUMN createdAt INTEGER NOT NULL DEFAULT 0")
}
}
9 changes: 8 additions & 1 deletion app/src/main/java/com/paulcoding/hviewer/model/PostModel.kt
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
package com.paulcoding.hviewer.model

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

data class PostData(
val images: List<String>,
val total: Int,
val next: String? = null
)


@Entity(tableName = "favorite_posts")
data class PostItem(
val name: String = "",
@PrimaryKey
val url: String = "",
val name: String = "",
val thumbnail: String = "",
val site: String = "",
val createdAt: Long = 0,
)

data class Posts(
Expand Down
14 changes: 13 additions & 1 deletion app/src/main/java/com/paulcoding/hviewer/ui/component/HIcon.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,14 @@ package com.paulcoding.hviewer.ui.component

import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.ArrowBack
import androidx.compose.material.icons.filled.Favorite
import androidx.compose.material.icons.filled.FavoriteBorder
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.LocalContentColor
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import com.paulcoding.hviewer.ui.icon.SettingsIcon

Expand All @@ -16,14 +20,22 @@ fun HBackIcon(onClick: () -> Unit) {
}
}

@Composable
fun HFavoriteIcon(modifier: Modifier = Modifier, isFavorite: Boolean, onClick: () -> Unit) {
val icon = if (isFavorite) Icons.Filled.Favorite else Icons.Filled.FavoriteBorder
val tint: Color = if (isFavorite) Color.Red else Color.Gray
HIcon(modifier = modifier, imageVector = icon, tint = tint, onClick = onClick)
}

@Composable
fun HIcon(
modifier: Modifier = Modifier,
imageVector: ImageVector = SettingsIcon,
description: String = "",
tint: Color = LocalContentColor.current,
onClick: () -> Unit
) {
IconButton(onClick = { onClick() }, modifier = modifier) {
Icon(imageVector, description)
Icon(imageVector, description, tint = tint)
}
}
Loading

0 comments on commit 9f421e6

Please sign in to comment.