mirror of
https://github.com/JustinZeus/Wholphin.git
synced 2026-07-09 16:11:20 +02:00
Add a lot of code documentation (#1145)
## Description A brain dump documenting many classes and functions throughout the app. Definitely does not document everything, but covers most of the major components. This should be useful for new contributors. There is a small amount of code clean up too. There are no user facing changes. ### Related issues N/A ### Testing N/A ## Screenshots N/A ## AI or LLM usage None
This commit is contained in:
parent
2485d2c644
commit
66f060dccb
92 changed files with 719 additions and 222 deletions
|
|
@ -8,12 +8,18 @@ import com.github.damontecres.wholphin.ui.nav.Destination
|
|||
import org.jellyfin.sdk.model.UUID
|
||||
import org.jellyfin.sdk.model.api.ExtraType
|
||||
|
||||
/**
|
||||
* Represents "extras" for media such as behind-the-scenes or deleted scenes
|
||||
*/
|
||||
sealed interface ExtrasItem {
|
||||
val parentId: UUID
|
||||
val type: ExtraType
|
||||
val destination: Destination
|
||||
val title: String?
|
||||
|
||||
/**
|
||||
* Represents multiple extras of the same type
|
||||
*/
|
||||
data class Group(
|
||||
override val parentId: UUID,
|
||||
override val type: ExtraType,
|
||||
|
|
@ -25,6 +31,9 @@ sealed interface ExtrasItem {
|
|||
override val title: String? = null
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a single extra
|
||||
*/
|
||||
data class Single(
|
||||
override val parentId: UUID,
|
||||
override val type: ExtraType,
|
||||
|
|
@ -38,6 +47,9 @@ sealed interface ExtrasItem {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts [ExtraType] to the string resource ID
|
||||
*/
|
||||
@get:StringRes
|
||||
val ExtraType.stringRes: Int
|
||||
get() =
|
||||
|
|
@ -56,6 +68,9 @@ val ExtraType.stringRes: Int
|
|||
ExtraType.SHORT -> R.string.shorts
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts [ExtraType] to the plural resource ID
|
||||
*/
|
||||
@get:PluralsRes
|
||||
val ExtraType.pluralRes: Int
|
||||
get() =
|
||||
|
|
|
|||
|
|
@ -50,6 +50,11 @@ val DefaultPlaylistItemsOptions =
|
|||
DecadeFilter,
|
||||
)
|
||||
|
||||
/**
|
||||
* A way to filter libraries
|
||||
*
|
||||
* Gets and sets values within a [GetItemsFilter]
|
||||
*/
|
||||
sealed interface ItemFilterBy<T> {
|
||||
@get:StringRes
|
||||
val stringRes: Int
|
||||
|
|
|
|||
|
|
@ -5,6 +5,14 @@ import org.jellyfin.sdk.model.extensions.ticks
|
|||
import java.util.UUID
|
||||
import kotlin.time.Duration
|
||||
|
||||
/**
|
||||
* Represents audio or a song as a stripped down [BaseItem] since there may be a lot of these created.
|
||||
*
|
||||
* Typically added to a MediaItem as the tag for reference later
|
||||
*
|
||||
* The "key" can be used by a Compose LazyList key function as it will uniquely identify this particular
|
||||
* audio even if the same song is added to the queue multiple times
|
||||
*/
|
||||
@Stable
|
||||
data class AudioItem(
|
||||
val key: Long = keyTracker++,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,9 @@ import java.util.Locale
|
|||
import java.util.UUID
|
||||
import kotlin.time.Duration
|
||||
|
||||
/**
|
||||
* Wrapper for [BaseItemDto] with shortcuts for various UI elements
|
||||
*/
|
||||
@Serializable
|
||||
@Stable
|
||||
data class BaseItem(
|
||||
|
|
@ -92,6 +95,9 @@ data class BaseItem(
|
|||
@Transient
|
||||
val timeRemainingOrRuntime: Duration? = data.timeRemaining ?: data.runTimeTicks?.ticks
|
||||
|
||||
/**
|
||||
* Contains pre computed UI elements that would be expensive to create on the main thread
|
||||
*/
|
||||
@Transient
|
||||
val ui =
|
||||
BaseItemUi(
|
||||
|
|
@ -178,6 +184,9 @@ data class BaseItem(
|
|||
it.dayOfMonth.toString().padStart(2, '0')
|
||||
}?.toIntOrNull()
|
||||
|
||||
/**
|
||||
* Convert this [BaseItem] into a [Destination] to navigate to its page in the app
|
||||
*/
|
||||
fun destination(index: Int? = null): Destination {
|
||||
if (destinationOverride != null) return destinationOverride
|
||||
val result =
|
||||
|
|
@ -228,6 +237,7 @@ data class BaseItem(
|
|||
}
|
||||
|
||||
companion object {
|
||||
@Deprecated("Use regular constructor instead")
|
||||
fun from(
|
||||
dto: BaseItemDto,
|
||||
api: ApiClient,
|
||||
|
|
@ -249,6 +259,9 @@ data class BaseItemUi(
|
|||
val quickDetails: AnnotatedString,
|
||||
)
|
||||
|
||||
/**
|
||||
* Create the special [Destination.FilteredCollection] for the given genre information
|
||||
*/
|
||||
fun createGenreDestination(
|
||||
genreId: UUID,
|
||||
genreName: String,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,9 @@ import org.jellyfin.sdk.model.api.ImageType
|
|||
import org.jellyfin.sdk.model.extensions.ticks
|
||||
import kotlin.time.Duration
|
||||
|
||||
/**
|
||||
* Represents a chapter within a video
|
||||
*/
|
||||
data class Chapter(
|
||||
val name: String?,
|
||||
val position: Duration,
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@ import org.jellyfin.sdk.model.serializer.UUIDSerializer
|
|||
import java.time.LocalDate
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* The type of a Seerr/Discover object with mapping to the Jellyfin [BaseItemKind]
|
||||
*/
|
||||
@Serializable
|
||||
enum class SeerrItemType(
|
||||
val baseItemKind: BaseItemKind?,
|
||||
|
|
@ -46,6 +49,9 @@ enum class SeerrItemType(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* How available is a particular discovered item within the Jellyfin server
|
||||
*/
|
||||
@Serializable
|
||||
enum class SeerrAvailability(
|
||||
val status: Int,
|
||||
|
|
@ -64,7 +70,7 @@ enum class SeerrAvailability(
|
|||
}
|
||||
|
||||
/**
|
||||
* An item provided by a discovery service (ie Seerr). It may exist on the JF server as well.
|
||||
* An item provided by a discovery service (ie Seerr). It may exist on the JF server as well, see [availability].
|
||||
*/
|
||||
@Stable
|
||||
@Serializable
|
||||
|
|
@ -104,6 +110,9 @@ data class DiscoverItem(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A rating for a discovered item which is usually fetched separately from the item
|
||||
*/
|
||||
data class DiscoverRating(
|
||||
val criticRating: Int?,
|
||||
val audienceRating: Float?,
|
||||
|
|
|
|||
|
|
@ -14,6 +14,9 @@ import org.jellyfin.sdk.model.api.request.GetPersonsRequest
|
|||
import org.jellyfin.sdk.model.serializer.UUIDSerializer
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Filter for a collection folder
|
||||
*/
|
||||
@Serializable
|
||||
data class CollectionFolderFilter(
|
||||
val nameOverride: String? = null,
|
||||
|
|
@ -24,6 +27,9 @@ data class CollectionFolderFilter(
|
|||
val useSavedLibraryDisplayInfo: Boolean = true,
|
||||
)
|
||||
|
||||
/**
|
||||
* A sort of simplified filter which can be [applyTo] a [GetItemsRequest] or [GetPersonsRequest] to add or remove filters
|
||||
*/
|
||||
@Serializable
|
||||
data class GetItemsFilter(
|
||||
val favorite: Boolean? = null,
|
||||
|
|
@ -52,7 +58,7 @@ data class GetItemsFilter(
|
|||
}
|
||||
|
||||
/**
|
||||
* Clear all of the values for the given filters
|
||||
* Clear all the values for the given filters
|
||||
*/
|
||||
fun delete(filterOptions: List<ItemFilterBy<*>>): GetItemsFilter {
|
||||
var newFilter = this
|
||||
|
|
@ -128,6 +134,9 @@ data class GetItemsFilter(
|
|||
isFavorite = favorite,
|
||||
)
|
||||
|
||||
/**
|
||||
* Merge another [GetItemsFilter] onto this one, replacing only unset values
|
||||
*/
|
||||
fun merge(filter: GetItemsFilter): GetItemsFilter =
|
||||
this.copy(
|
||||
favorite = favorite ?: filter.favorite,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,10 @@ import kotlinx.serialization.UseSerializers
|
|||
import org.jellyfin.sdk.model.serializer.UUIDSerializer
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Store the media source and audio/subtitle tracks chosen for a specific media item
|
||||
*
|
||||
*/
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ import kotlinx.serialization.UseSerializers
|
|||
import org.jellyfin.sdk.model.serializer.UUIDSerializer
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Store modifications to an audio/subtitle track in a media item
|
||||
*
|
||||
* For example, the subtitle delay
|
||||
*/
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
|
|
|
|||
|
|
@ -17,6 +17,9 @@ import org.jellyfin.sdk.model.ServerVersion
|
|||
import org.jellyfin.sdk.model.serializer.UUIDSerializer
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Represents a Jellyfin server
|
||||
*/
|
||||
@Entity(tableName = "servers")
|
||||
@Serializable
|
||||
data class JellyfinServer(
|
||||
|
|
@ -29,6 +32,9 @@ data class JellyfinServer(
|
|||
val serverVersion: ServerVersion? by lazy { version?.let(ServerVersion::fromString) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a Jellyfin user for a particular server
|
||||
*/
|
||||
@Entity(
|
||||
tableName = "users",
|
||||
foreignKeys = [
|
||||
|
|
@ -59,6 +65,9 @@ data class JellyfinUser(
|
|||
"JellyfinUser(rowId=$rowId, id=$id, name=$name, serverId=$serverId, accessToken?=${accessToken.isNotNullOrBlank()}, pin?=${pin.isNotNullOrBlank()})"
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the relationship between [JellyfinServer] and its [JellyfinUser]
|
||||
*/
|
||||
data class JellyfinServerUsers(
|
||||
@Embedded val server: JellyfinServer,
|
||||
@Relation(
|
||||
|
|
|
|||
|
|
@ -18,6 +18,11 @@ import org.jellyfin.sdk.model.api.SortOrder
|
|||
import org.jellyfin.sdk.model.serializer.UUIDSerializer
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Stores the filter, sort, and view options a user changes for a library
|
||||
*
|
||||
* This allows for restoring these settings whenever the user navigates to the library
|
||||
*/
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ enum class NavPinType {
|
|||
UNPINNED,
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores preference information about nav drawer items such as its order and whether to show or put in More
|
||||
*/
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
|
|
@ -12,6 +12,9 @@ import org.jellyfin.sdk.model.api.BaseItemPerson
|
|||
import org.jellyfin.sdk.model.api.ImageType
|
||||
import org.jellyfin.sdk.model.api.PersonKind
|
||||
|
||||
/**
|
||||
* Represents a person in some media such as an actor or director
|
||||
*/
|
||||
@Stable
|
||||
data class Person(
|
||||
val id: UUID,
|
||||
|
|
|
|||
|
|
@ -5,6 +5,9 @@ import androidx.room.Entity
|
|||
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Store effects applied to some media such as color or hue adjustments
|
||||
*/
|
||||
@Entity(tableName = "playback_effects", primaryKeys = ["jellyfinUserRowId", "itemId", "type"])
|
||||
data class PlaybackEffect(
|
||||
val jellyfinUserRowId: Int,
|
||||
|
|
|
|||
|
|
@ -9,6 +9,10 @@ import kotlinx.serialization.UseSerializers
|
|||
import org.jellyfin.sdk.model.serializer.UUIDSerializer
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Stores the language choices for a series so they can be applied automatically to other episodes
|
||||
* without the user needing to explicitly choose the tracks
|
||||
*/
|
||||
@Entity(
|
||||
foreignKeys = [
|
||||
ForeignKey(
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@ import androidx.compose.runtime.setValue
|
|||
import org.jellyfin.sdk.model.api.MediaType
|
||||
import java.util.UUID
|
||||
|
||||
/**
|
||||
* Tracks playback of multiple items. Points to the current media with function to advance or go to previous ones.
|
||||
*
|
||||
* This is not the same thing as a Jellyfin server playlist
|
||||
*/
|
||||
class Playlist(
|
||||
items: List<BaseItem>,
|
||||
startIndex: Int = 0,
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@ package com.github.damontecres.wholphin.data.model
|
|||
|
||||
import com.github.damontecres.wholphin.services.SeerrUserConfig
|
||||
|
||||
/**
|
||||
* Permission levels for a user on a Seerr server
|
||||
*/
|
||||
enum class SeerrPermission(
|
||||
private val flag: Int,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,9 @@ import kotlinx.serialization.Serializable
|
|||
import kotlinx.serialization.UseSerializers
|
||||
import org.jellyfin.sdk.model.serializer.UUIDSerializer
|
||||
|
||||
/**
|
||||
* Represents a Seerr server instance
|
||||
*/
|
||||
@Entity(
|
||||
tableName = "seerr_servers",
|
||||
indices = [Index("url", unique = true)],
|
||||
|
|
@ -26,6 +29,9 @@ data class SeerrServer(
|
|||
val version: String? = null,
|
||||
)
|
||||
|
||||
/**
|
||||
* Represents a user on a [SeerrServer]
|
||||
*/
|
||||
@Entity(
|
||||
tableName = "seerr_users",
|
||||
foreignKeys = [
|
||||
|
|
@ -56,12 +62,18 @@ data class SeerrUser(
|
|||
"SeerrUser(jellyfinUserRowId=$jellyfinUserRowId, serverId=$serverId, authMethod=$authMethod, username=$username, password?=${password.isNotNullOrBlank()}, credential?=${credential.isNotNullOrBlank()})"
|
||||
}
|
||||
|
||||
/**
|
||||
* The method used to authenticate a user to the server
|
||||
*/
|
||||
enum class SeerrAuthMethod {
|
||||
LOCAL,
|
||||
JELLYFIN,
|
||||
API_KEY,
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the relationship between a [SeerrServer] and its [SeerrUser]s
|
||||
*/
|
||||
data class SeerrServerUsers(
|
||||
@Embedded val server: SeerrServer,
|
||||
@Relation(
|
||||
|
|
|
|||
|
|
@ -1,9 +1,15 @@
|
|||
package com.github.damontecres.wholphin.data.model
|
||||
|
||||
/**
|
||||
* Represents a trailer for media
|
||||
*/
|
||||
sealed interface Trailer {
|
||||
val name: String
|
||||
}
|
||||
|
||||
/**
|
||||
* A [Trailer] stored on the Jellyfin server
|
||||
*/
|
||||
data class LocalTrailer(
|
||||
val baseItem: BaseItem,
|
||||
) : Trailer {
|
||||
|
|
@ -11,6 +17,9 @@ data class LocalTrailer(
|
|||
get() = baseItem.name ?: ""
|
||||
}
|
||||
|
||||
/**
|
||||
* A [Trailer] available via a remote URL, such as YouTube
|
||||
*/
|
||||
data class RemoteTrailer(
|
||||
override val name: String,
|
||||
val url: String,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import androidx.media3.effect.ScaleAndRotateTransformation
|
|||
import androidx.room.Ignore
|
||||
|
||||
/**
|
||||
* Modifications to a video playback
|
||||
* Modifications to an image or video playback
|
||||
*/
|
||||
data class VideoFilter(
|
||||
val rotation: Int = 0,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue