Skip to content

Commit

Permalink
feat(watchlist): add 'addedOn' column for sorting by date
Browse files Browse the repository at this point in the history
Added a new column 'addedOn' to the watchlist entity to store the timestamp when items are added. This change allows the watchlist to be sorted based on the date they were added (descendingly), providing a more intuitive sorting order for users.
  • Loading branch information
rhenwinch committed Jun 17, 2024
1 parent 16001dc commit 93d847f
Show file tree
Hide file tree
Showing 8 changed files with 180 additions and 15 deletions.
140 changes: 140 additions & 0 deletions core/database/schemas/com.flixclusive.core.database.AppDatabase/3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
{
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "5e9692e1dee6b366a13a665eb1daf587",
"entities": [
{
"tableName": "watch_history",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `ownerId` INTEGER NOT NULL, `seasons` INTEGER, `episodes` TEXT NOT NULL, `episodesWatched` TEXT NOT NULL, `dateWatched` INTEGER NOT NULL, `film` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "ownerId",
"columnName": "ownerId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "seasons",
"columnName": "seasons",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "episodes",
"columnName": "episodes",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "episodesWatched",
"columnName": "episodesWatched",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "dateWatched",
"columnName": "dateWatched",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "film",
"columnName": "film",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "watchlist",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `ownerId` INTEGER NOT NULL, `addedOn` INTEGER NOT NULL, `film` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "ownerId",
"columnName": "ownerId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "addedOn",
"columnName": "addedOn",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "film",
"columnName": "film",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"id"
]
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`userId` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `name` TEXT NOT NULL, `image` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "userId",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "name",
"columnName": "name",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "image",
"columnName": "image",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"autoGenerate": true,
"columnNames": [
"userId"
]
},
"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, '5e9692e1dee6b366a13a665eb1daf587')"
]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.sqlite.db.SupportSQLiteDatabase
import com.flixclusive.core.database.dao.UserDao
import com.flixclusive.core.database.dao.WatchHistoryDao
import com.flixclusive.core.database.dao.WatchlistDao
import com.flixclusive.core.database.util.DateConverter
import com.flixclusive.core.database.util.FilmDataConverter
import com.flixclusive.core.database.util.WatchHistoryItemConverter
import com.flixclusive.core.util.common.dispatcher.di.ApplicationScope
Expand All @@ -24,9 +25,9 @@ const val APP_DATABASE = "app_database"

@Database(
entities = [WatchHistoryItem::class, WatchlistItem::class, User::class],
version = 2
version = 3
)
@TypeConverters(FilmDataConverter::class, WatchHistoryItemConverter::class)
@TypeConverters(FilmDataConverter::class, WatchHistoryItemConverter::class, DateConverter::class)
internal abstract class AppDatabase : RoomDatabase() {
abstract fun userDao(): UserDao
abstract fun watchlistDao(): WatchlistDao
Expand All @@ -50,7 +51,10 @@ internal abstract class AppDatabase : RoomDatabase() {
AppDatabase::class.java,
APP_DATABASE
)
.addMigrations(DatabaseMigrations.Schema1to2())
.addMigrations(
DatabaseMigrations.Schema1to2(),
DatabaseMigrations.Schema2to3()
)
.addCallback(
object: Callback() {
private fun prepopulateUsers() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.flixclusive.core.database

import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase
import java.util.Date

internal object DatabaseMigrations {
class Schema1to2 : Migration(startVersion = 1, endVersion = 2) {
Expand All @@ -14,4 +15,13 @@ internal object DatabaseMigrations {
db.execSQL("ALTER TABLE `watch_history` ADD COLUMN ownerId INTEGER NOT NULL DEFAULT 1")
}
}

class Schema2to3 : Migration(startVersion = 2, endVersion = 3) {
override fun migrate(db: SupportSQLiteDatabase) {
val timeToday = Date().time

// Edit watchlist table to add dateAdded column
db.execSQL("ALTER TABLE `watchlist` ADD COLUMN addedOn INTEGER NOT NULL DEFAULT $timeToday")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ interface WatchlistDao {
JOIN User as u
ON w.ownerId = u.userId
WHERE userId = :ownerId
ORDER BY w.addedOn DESC;
""")
suspend fun getAllItems(ownerId: Int): List<WatchlistItem>

Expand All @@ -39,6 +40,7 @@ interface WatchlistDao {
JOIN User as u
ON w.ownerId = u.userId
WHERE userId = :ownerId
ORDER BY w.addedOn DESC;
""")
fun getAllItemsInFlow(ownerId: Int): Flow<List<WatchlistItem>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.flixclusive.core.database.util

import androidx.room.TypeConverter
import java.util.Date

internal class DateConverter {
@TypeConverter
fun fromDate(value: Date): Long {
return value.time
}

@TypeConverter
fun toDate(value: Long): Date {
return Date(value)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import androidx.room.TypeConverter
import com.flixclusive.core.util.network.fromJson
import com.flixclusive.model.database.EpisodeWatched
import com.google.gson.Gson
import java.util.Date

internal class WatchHistoryItemConverter {
private val gson = Gson()
Expand All @@ -28,14 +27,4 @@ internal class WatchHistoryItemConverter {
fun toEpisodeLimitsMap(json: String): Map<Int, Int> {
return fromJson<Map<Int, Int>>(json)
}

@TypeConverter
fun fromDate(value: Date): Long {
return value.time
}

@TypeConverter
fun toDate(value: Long): Date {
return Date(value)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ class WatchlistScreenViewModel @Inject constructor(

val items = watchlistRepository
.getAllItemsInFlow()
.mapLatest { list -> list.map { it.film } }
.mapLatest { list ->
list.map { it.film }
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(5000),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ import androidx.room.PrimaryKey
import com.flixclusive.model.tmdb.Film
import com.flixclusive.model.tmdb.FilmImpl
import com.flixclusive.model.tmdb.toFilmInstance
import java.util.Date

@Entity(tableName = "watchlist")
data class WatchlistItem(
@PrimaryKey val id: Int = 0,
val ownerId: Int = 1,
val addedOn: Date = Date(),
val film: FilmImpl = FilmImpl()
)

Expand Down

0 comments on commit 93d847f

Please sign in to comment.