Skip to content

Commit

Permalink
Merge pull request #20 from paulcoding810/feat/post-info
Browse files Browse the repository at this point in the history
Add post info bottomsheet
  • Loading branch information
paulcoding810 authored Dec 10, 2024
2 parents 14dbb95 + 5cff302 commit 3c47a3e
Show file tree
Hide file tree
Showing 16 changed files with 436 additions and 78 deletions.
24 changes: 21 additions & 3 deletions app/schemas/com.paulcoding.hviewer.database.AppDatabase/3.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "40109ede6ba29fdee1d23735114a2981",
"identityHash": "374e52582fb9d67d7560b3849abda364",
"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`))",
"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, `tags` TEXT NOT NULL, `size` TEXT, `quantity` TEXT, PRIMARY KEY(`url`))",
"fields": [
{
"fieldPath": "url",
Expand Down Expand Up @@ -37,6 +37,24 @@
"columnName": "createdAt",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "size",
"columnName": "size",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "quantity",
"columnName": "quantity",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
Expand All @@ -52,7 +70,7 @@
"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')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '374e52582fb9d67d7560b3849abda364')"
]
}
}
82 changes: 82 additions & 0 deletions app/schemas/com.paulcoding.hviewer.database.AppDatabase/4.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
{
"formatVersion": 1,
"database": {
"version": 4,
"identityHash": "9cae14220c3b54c73ec622e03a0d6f08",
"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, `tags` TEXT, `size` INTEGER, `views` INTEGER, `quantity` INTEGER, 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
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "size",
"columnName": "size",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "views",
"columnName": "views",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "quantity",
"columnName": "quantity",
"affinity": "INTEGER",
"notNull": false
}
],
"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, '9cae14220c3b54c73ec622e03a0d6f08')"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package com.paulcoding.hviewer.database

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

@Database(entities = [PostItem::class], version = 3, exportSchema = true)
@Database(entities = [PostItem::class], version = 4, exportSchema = true)
@TypeConverters(Converters::class)
abstract class AppDatabase : RoomDatabase() {
abstract fun favoritePostDao(): FavoritePostDao
}
21 changes: 21 additions & 0 deletions app/src/main/java/com/paulcoding/hviewer/database/Converters.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.paulcoding.hviewer.database

import androidx.room.TypeConverter
import com.google.gson.Gson
import com.google.gson.reflect.TypeToken
import com.paulcoding.hviewer.model.Tag

class Converters {
@TypeConverter
fun fromListTagToString(list: List<Tag>?): String? {
return list?.let { Gson().toJson(it) }
}

@TypeConverter
fun fromStringToListTag(data: String?): List<Tag>? {
return data?.let {
val listType = object : TypeToken<List<Tag>>() {}.type
Gson().fromJson(it, listType)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ object DatabaseProvider {
appContext,
AppDatabase::class.java, "hviewer_db"
)
.addMigrations(MIGRATION_1_2, MIGRATION_2_3)
.addMigrations(MIGRATION_1_2, MIGRATION_2_3, MIGRATION_3_4)
.build()
}
return db!!
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,13 @@ 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")
}
}

val MIGRATION_3_4 = object : Migration(3, 4) {
override fun migrate(db: SupportSQLiteDatabase) {
db.execSQL("ALTER TABLE favorite_posts ADD COLUMN tags TEXT")
db.execSQL("ALTER TABLE favorite_posts ADD COLUMN size INTEGER")
db.execSQL("ALTER TABLE favorite_posts ADD COLUMN views INTEGER")
db.execSQL("ALTER TABLE favorite_posts ADD COLUMN quantity INTEGER")
}
}
11 changes: 10 additions & 1 deletion app/src/main/java/com/paulcoding/hviewer/model/PostModel.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.paulcoding.hviewer.model

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

data class PostData(
Expand All @@ -18,6 +18,15 @@ data class PostItem(
val thumbnail: String = "",
val site: String = "",
val createdAt: Long = 0,
val tags: List<Tag>? = null,
val size: Int? = null,
val views: Int? = null,
val quantity: Int? = null,
)

data class Tag(
val name: String = "",
val url: String = "",
)

data class Posts(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.lifecycle.viewmodel.compose.viewModel
import com.paulcoding.hviewer.model.PostItem
import com.paulcoding.hviewer.model.Tag
import com.paulcoding.hviewer.ui.component.HBackIcon
import com.paulcoding.hviewer.ui.component.HEmpty
import com.paulcoding.hviewer.ui.page.AppViewModel
Expand All @@ -31,6 +32,7 @@ import kotlinx.coroutines.launch
fun FavoritePage(
appViewModel: AppViewModel,
navToImages: (PostItem) -> Unit,
navToCustomTag: (PostItem, Tag) -> Unit,
goBack: () -> Boolean
) {
val viewModel: AppViewModel = viewModel()
Expand Down Expand Up @@ -68,9 +70,11 @@ fun FavoritePage(
}) { paddings ->
LazyColumn(modifier = Modifier.padding(paddings)) {
items(items = favoritePosts, key = { it.url }) { item ->
FavoriteItem(item, navToImages = { navToImages(item) }, deleteFavorite = {
onDelete(item)
})
FavoriteItem(item, navToImages = { navToImages(item) },
onTagClick = { tag -> navToCustomTag(item, tag) },
deleteFavorite = {
onDelete(item)
})
}
if (favoritePosts.isEmpty())
item { HEmpty() }
Expand All @@ -83,11 +87,16 @@ fun FavoritePage(
fun FavoriteItem(
post: PostItem,
navToImages: () -> Unit,
onTagClick: (Tag) -> Unit,
deleteFavorite: () -> Unit
) {
PostCard(post, isFavorite = true, setFavorite = {
deleteFavorite()
}) {
PostCard(
post, isFavorite = true,
setFavorite = {
deleteFavorite()
},
onTagClick = { onTagClick(it) },
) {
navToImages()
}
}
22 changes: 22 additions & 0 deletions app/src/main/java/com/paulcoding/hviewer/ui/page/AppEntry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.paulcoding.hviewer.model.PostItem
import com.paulcoding.hviewer.model.SiteConfigs
import com.paulcoding.hviewer.model.Tag
import com.paulcoding.hviewer.network.Github
import com.paulcoding.hviewer.preference.Preferences
import com.paulcoding.hviewer.ui.favorite.FavoritePage
import com.paulcoding.hviewer.ui.page.editor.EditorPage
import com.paulcoding.hviewer.ui.page.editor.ListScriptPage
import com.paulcoding.hviewer.ui.page.lock.LockPage
import com.paulcoding.hviewer.ui.page.post.PostPage
import com.paulcoding.hviewer.ui.page.posts.CustomTagPage
import com.paulcoding.hviewer.ui.page.posts.PostsPage
import com.paulcoding.hviewer.ui.page.search.SearchPage
import com.paulcoding.hviewer.ui.page.settings.SettingsPage
Expand All @@ -46,6 +48,11 @@ fun AppEntry() {
navController.navigate(Route.POST)
}

fun navToCustomTag(tag: Tag) {
appViewModel.setCurrentTag(tag)
navController.navigate(Route.CUSTOM_TAG)
}

val startDestination =
remember { if (Preferences.pin.isNotEmpty()) Route.LOCK else Route.SITES }

Expand Down Expand Up @@ -88,9 +95,19 @@ fun AppEntry() {
navToImages(post)
},
navToSearch = { navController.navigate(Route.SEARCH) },
navToCustomTag = { navToCustomTag(it) },
goBack = { navController.popBackStack() },
)
}
animatedComposable(Route.CUSTOM_TAG) {
CustomTagPage(
appViewModel,
navToCustomTag = { navToCustomTag(it) },
goBack = { navController.popBackStack() }
) {
navToImages(it)
}
}
animatedComposable(Route.POST) {
PostPage(
appViewModel,
Expand All @@ -104,6 +121,7 @@ fun AppEntry() {
navToImages = { post: PostItem ->
navToImages(post)
},
navToCustomTag = { navToCustomTag(it) },
goBack = { navController.popBackStack() },
)
}
Expand All @@ -114,6 +132,10 @@ fun AppEntry() {
appViewModel.setSiteConfig(post.site, siteConfigs.sites[post.site]!!)
navToImages(post)
},
navToCustomTag = { post, tag ->
appViewModel.setSiteConfig(post.site, siteConfigs.sites[post.site]!!)
navToCustomTag(tag)
},
goBack = { navController.popBackStack() }
)
}
Expand Down
11 changes: 9 additions & 2 deletions app/src/main/java/com/paulcoding/hviewer/ui/page/AppViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import androidx.lifecycle.viewModelScope
import com.paulcoding.hviewer.BuildConfig
import com.paulcoding.hviewer.MainApp.Companion.appContext
import com.paulcoding.hviewer.database.DatabaseProvider
import com.paulcoding.hviewer.helper.alsoLog
import com.paulcoding.hviewer.helper.crashLogDir
import com.paulcoding.hviewer.helper.scriptsDir
import com.paulcoding.hviewer.model.PostItem
import com.paulcoding.hviewer.model.SiteConfig
import com.paulcoding.hviewer.model.Tag
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
Expand All @@ -32,6 +32,12 @@ class AppViewModel : ViewModel() {
_stateFlow.update { it.copy(post = post) }
}

fun setCurrentTag(tag: Tag) {
_stateFlow.update { it.copy(tag = tag) }
}

fun getCurrentTag() = _stateFlow.value.tag

fun setSiteConfig(site: String, siteConfig: SiteConfig) {
_stateFlow.update { it.copy(site = site to siteConfig) }
}
Expand All @@ -40,7 +46,8 @@ class AppViewModel : ViewModel() {
data class UiState(
val post: PostItem = PostItem(),
val site: Pair<String, SiteConfig> = "" to SiteConfig(),
val isDevMode: Boolean = BuildConfig.DEBUG.alsoLog("debug"),
val tag: Tag = Tag(),
val isDevMode: Boolean = BuildConfig.DEBUG,
)

fun setDevMode(isDevMode: Boolean) {
Expand Down
1 change: 1 addition & 0 deletions app/src/main/java/com/paulcoding/hviewer/ui/page/Route.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ object Route {
const val SITES = "sites"
const val TOPICS = "topics"
const val POSTS = "posts"
const val CUSTOM_TAG = "custom_tag"
const val POST = "post"
const val SEARCH = "search"
const val SETTINGS = "settings"
Expand Down
Loading

0 comments on commit 3c47a3e

Please sign in to comment.