mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 16:11:20 +02:00
Add ability to customize the navigation drawer menu (#60)
Adds support for customizing the items listed on the left side navigation drawer menu. Each item can be toggled on/off in settings. The hidden ones are still accessible under "More" on the nav drawer, which only appears if some items are hidden. Additionally, if any of menu items are hidden, their "latest" content will not appear on the home page. The setting is stored per user profile.
This commit is contained in:
parent
27d0a17a00
commit
fc4954b561
17 changed files with 776 additions and 184 deletions
|
|
@ -8,20 +8,26 @@ import androidx.room.TypeConverters
|
|||
import androidx.room.migration.Migration
|
||||
import androidx.sqlite.db.SupportSQLiteDatabase
|
||||
import com.github.damontecres.wholphin.data.model.ItemPlayback
|
||||
import com.github.damontecres.wholphin.data.model.NavDrawerPinnedItem
|
||||
import org.jellyfin.sdk.model.serializer.toUUID
|
||||
import java.util.UUID
|
||||
|
||||
@Database(
|
||||
entities = [JellyfinServer::class, JellyfinUser::class, ItemPlayback::class],
|
||||
version = 4,
|
||||
entities = [JellyfinServer::class, JellyfinUser::class, ItemPlayback::class, NavDrawerPinnedItem::class],
|
||||
version = 5,
|
||||
exportSchema = true,
|
||||
autoMigrations = [AutoMigration(3, 4)],
|
||||
autoMigrations = [
|
||||
AutoMigration(3, 4),
|
||||
AutoMigration(4, 5),
|
||||
],
|
||||
)
|
||||
@TypeConverters(Converters::class)
|
||||
abstract class AppDatabase : RoomDatabase() {
|
||||
abstract fun serverDao(): JellyfinServerDao
|
||||
|
||||
abstract fun itemPlaybackDao(): ItemPlaybackDao
|
||||
|
||||
abstract fun serverPreferencesDao(): ServerPreferencesDao
|
||||
}
|
||||
|
||||
class Converters {
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ interface JellyfinServerDao {
|
|||
fun updateUser(user: JellyfinUser): Int
|
||||
|
||||
@Transaction
|
||||
fun addOrUpdateUser(user: JellyfinUser) {
|
||||
fun addOrUpdateUser(user: JellyfinUser): JellyfinUser {
|
||||
val result = addUser(user)
|
||||
if (result == -1L) {
|
||||
val toSave =
|
||||
|
|
@ -92,7 +92,9 @@ interface JellyfinServerDao {
|
|||
user
|
||||
}
|
||||
updateUser(toSave)
|
||||
return toSave
|
||||
}
|
||||
return user.copy(rowId = result.toInt())
|
||||
}
|
||||
|
||||
@Query("SELECT * FROM users WHERE serverId = :serverId AND id = :userId")
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
package com.github.damontecres.wholphin.data
|
||||
|
||||
import android.content.Context
|
||||
import com.github.damontecres.wholphin.data.model.BaseItem
|
||||
import com.github.damontecres.wholphin.data.model.NavDrawerPinnedItem
|
||||
import com.github.damontecres.wholphin.data.model.NavPinType
|
||||
import com.github.damontecres.wholphin.ui.nav.NavDrawerItem
|
||||
import com.github.damontecres.wholphin.ui.nav.ServerNavDrawerItem
|
||||
import com.github.damontecres.wholphin.util.supportedCollectionTypes
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import org.jellyfin.sdk.api.client.ApiClient
|
||||
import org.jellyfin.sdk.api.client.extensions.userViewsApi
|
||||
import org.jellyfin.sdk.model.api.CollectionType
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class NavDrawerItemRepository
|
||||
@Inject
|
||||
constructor(
|
||||
@param:ApplicationContext private val context: Context,
|
||||
private val api: ApiClient,
|
||||
private val serverRepository: ServerRepository,
|
||||
private val serverPreferencesDao: ServerPreferencesDao,
|
||||
) {
|
||||
suspend fun getNavDrawerItems(): List<NavDrawerItem> {
|
||||
val user = serverRepository.currentUser
|
||||
val userViews =
|
||||
api.userViewsApi
|
||||
.getUserViews(userId = user?.id)
|
||||
.content.items
|
||||
|
||||
val builtins = listOf(NavDrawerItem.Favorites)
|
||||
val libraries =
|
||||
userViews
|
||||
.filter { it.collectionType in supportedCollectionTypes }
|
||||
.map {
|
||||
ServerNavDrawerItem(
|
||||
itemId = it.id,
|
||||
name = it.name ?: it.id.toString(),
|
||||
destination = BaseItem.from(it, api).destination(),
|
||||
type = it.collectionType ?: CollectionType.UNKNOWN,
|
||||
)
|
||||
}
|
||||
return builtins + libraries
|
||||
}
|
||||
|
||||
suspend fun getFilteredNavDrawerItems(items: List<NavDrawerItem>): List<NavDrawerItem> {
|
||||
val user = serverRepository.currentUser
|
||||
val navDrawerPins =
|
||||
user
|
||||
?.let {
|
||||
serverPreferencesDao.getNavDrawerPinnedItems(it)
|
||||
}.orEmpty()
|
||||
val filtered = items.filter { navDrawerPins.isPinned(it.id) }
|
||||
if (items.size != filtered.size) {
|
||||
// Some were filtered out, check if should include More
|
||||
if (navDrawerPins.isPinned(NavDrawerItem.More.id)) {
|
||||
return filtered + listOf(NavDrawerItem.More)
|
||||
}
|
||||
}
|
||||
return filtered
|
||||
}
|
||||
}
|
||||
|
||||
fun List<NavDrawerPinnedItem>.isPinned(id: String) = (firstOrNull { it.itemId == id }?.type ?: NavPinType.PINNED) == NavPinType.PINNED
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.github.damontecres.wholphin.data
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.github.damontecres.wholphin.data.model.NavDrawerPinnedItem
|
||||
|
||||
@Dao
|
||||
interface ServerPreferencesDao {
|
||||
fun getNavDrawerPinnedItems(user: JellyfinUser): List<NavDrawerPinnedItem> = getNavDrawerPinnedItems(user.rowId)
|
||||
|
||||
@Query("SELECT * from NavDrawerPinnedItem WHERE userId=:userId")
|
||||
fun getNavDrawerPinnedItems(userId: Int): List<NavDrawerPinnedItem>
|
||||
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun saveNavDrawerPinnedItems(vararg items: NavDrawerPinnedItem)
|
||||
}
|
||||
|
|
@ -82,15 +82,13 @@ class ServerRepository
|
|||
val sysInfo by apiClient.systemApi.getSystemInfo()
|
||||
|
||||
val updatedServer = server.copy(name = sysInfo.serverName)
|
||||
val updatedUser =
|
||||
var updatedUser =
|
||||
user.copy(
|
||||
id = userDto.id,
|
||||
name = userDto.name,
|
||||
)
|
||||
if (updatedUser.rowId <= 0) {
|
||||
}
|
||||
serverDao.addOrUpdateServer(updatedServer)
|
||||
serverDao.addOrUpdateUser(updatedUser)
|
||||
updatedUser = serverDao.addOrUpdateUser(updatedUser)
|
||||
userPreferencesDataStore.updateData {
|
||||
it
|
||||
.toBuilder()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package com.github.damontecres.wholphin.data.model
|
||||
|
||||
import androidx.room.Entity
|
||||
import androidx.room.ForeignKey
|
||||
import com.github.damontecres.wholphin.data.JellyfinUser
|
||||
|
||||
enum class NavPinType {
|
||||
PINNED,
|
||||
UNPINNED,
|
||||
}
|
||||
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
entity = JellyfinUser::class,
|
||||
parentColumns = arrayOf("rowId"),
|
||||
childColumns = arrayOf("userId"),
|
||||
onDelete = ForeignKey.CASCADE,
|
||||
onUpdate = ForeignKey.CASCADE,
|
||||
),
|
||||
],
|
||||
primaryKeys = ["userId", "itemId"],
|
||||
)
|
||||
data class NavDrawerPinnedItem(
|
||||
val userId: Int,
|
||||
val itemId: String,
|
||||
val type: NavPinType,
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue