Rename to SleepyOwl, add logo
This commit is contained in:
@@ -7,11 +7,11 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "ru.stenfredd.movies"
|
namespace = "ru.stenfredd.sleepyowl"
|
||||||
compileSdk = 37
|
compileSdk = 37
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "ru.stenfredd.movies"
|
applicationId = "ru.stenfredd.sleepyowl"
|
||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 36
|
targetSdk = 36
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
|
|||||||
@@ -12,15 +12,15 @@
|
|||||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".MoviesApp"
|
android:name=".SleepyOwlApp"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:banner="@drawable/banner"
|
android:banner="@drawable/banner"
|
||||||
android:icon="@drawable/banner"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:largeHeap="true"
|
android:largeHeap="true"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:networkSecurityConfig="@xml/network_security_config"
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
android:theme="@style/Theme.Movies">
|
android:theme="@style/Theme.SleepyOwl">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies
|
package ru.stenfredd.sleepyowl
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
@@ -15,14 +15,14 @@ import kotlinx.coroutines.flow.map
|
|||||||
import kotlinx.coroutines.flow.merge
|
import kotlinx.coroutines.flow.merge
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import ru.stenfredd.movies.core.data.ImageUrls
|
import ru.stenfredd.sleepyowl.core.data.ImageUrls
|
||||||
import ru.stenfredd.movies.core.data.SessionCache
|
import ru.stenfredd.sleepyowl.core.data.SessionCache
|
||||||
import ru.stenfredd.movies.core.data.WatchRepository
|
import ru.stenfredd.sleepyowl.core.data.WatchRepository
|
||||||
import ru.stenfredd.movies.core.data.model.ItemKind
|
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSummary
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import ru.stenfredd.movies.ui.model.landscape
|
import ru.stenfredd.sleepyowl.ui.model.landscape
|
||||||
import ru.stenfredd.movies.ui.model.remaining
|
import ru.stenfredd.sleepyowl.ui.model.remaining
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies
|
package ru.stenfredd.sleepyowl
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -30,34 +30,34 @@ import androidx.navigation3.ui.NavDisplay
|
|||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import androidx.compose.runtime.produceState
|
import androidx.compose.runtime.produceState
|
||||||
import kotlinx.coroutines.channels.Channel
|
import kotlinx.coroutines.channels.Channel
|
||||||
import ru.stenfredd.movies.core.data.LibraryRepository
|
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
|
||||||
import ru.stenfredd.movies.core.data.model.LibraryType
|
import ru.stenfredd.sleepyowl.core.data.model.LibraryType
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import ru.stenfredd.movies.playback.api.EngineId
|
import ru.stenfredd.sleepyowl.playback.api.EngineId
|
||||||
import ru.stenfredd.movies.playback.api.StreamSelection
|
import ru.stenfredd.sleepyowl.playback.api.StreamSelection
|
||||||
import ru.stenfredd.movies.ui.ItemsScreen
|
import ru.stenfredd.sleepyowl.ui.ItemsScreen
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.TourScreen
|
import ru.stenfredd.sleepyowl.ui.TourScreen
|
||||||
import ru.stenfredd.movies.ui.details.DetailsScreen
|
import ru.stenfredd.sleepyowl.ui.details.DetailsScreen
|
||||||
import ru.stenfredd.movies.ui.home.HomeScreen
|
import ru.stenfredd.sleepyowl.ui.home.HomeScreen
|
||||||
import ru.stenfredd.movies.ui.favorites.FavoritesScreen
|
import ru.stenfredd.sleepyowl.ui.favorites.FavoritesScreen
|
||||||
import ru.stenfredd.movies.ui.library.LibraryMemory
|
import ru.stenfredd.sleepyowl.ui.library.LibraryMemory
|
||||||
import ru.stenfredd.movies.ui.library.LibraryScreen
|
import ru.stenfredd.sleepyowl.ui.library.LibraryScreen
|
||||||
import ru.stenfredd.movies.ui.person.PersonScreen
|
import ru.stenfredd.sleepyowl.ui.person.PersonScreen
|
||||||
import ru.stenfredd.movies.ui.search.SearchScreen
|
import ru.stenfredd.sleepyowl.ui.search.SearchScreen
|
||||||
import ru.stenfredd.movies.ui.settings.LicenseScreen
|
import ru.stenfredd.sleepyowl.ui.settings.LicenseScreen
|
||||||
import ru.stenfredd.movies.ui.settings.SettingsScreen
|
import ru.stenfredd.sleepyowl.ui.settings.SettingsScreen
|
||||||
import ru.stenfredd.movies.ui.player.PlayerScreen
|
import ru.stenfredd.sleepyowl.ui.player.PlayerScreen
|
||||||
import ru.stenfredd.movies.ui.series.SeriesScreen
|
import ru.stenfredd.sleepyowl.ui.series.SeriesScreen
|
||||||
import ru.stenfredd.movies.ui.login.LoginScreen
|
import ru.stenfredd.sleepyowl.ui.login.LoginScreen
|
||||||
import ru.stenfredd.movies.ui.menu.WatchMenuHost
|
import ru.stenfredd.sleepyowl.ui.menu.WatchMenuHost
|
||||||
import ru.stenfredd.movies.ui.components.AppIcon
|
import ru.stenfredd.sleepyowl.ui.components.AppIcon
|
||||||
import ru.stenfredd.movies.ui.shell.RailLibrary
|
import ru.stenfredd.sleepyowl.ui.shell.RailLibrary
|
||||||
import ru.stenfredd.movies.ui.shell.Shell
|
import ru.stenfredd.sleepyowl.ui.shell.Shell
|
||||||
import ru.stenfredd.movies.ui.shell.Tab
|
import ru.stenfredd.sleepyowl.ui.shell.Tab
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppTheme
|
import ru.stenfredd.sleepyowl.ui.theme.AppTheme
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -230,7 +230,7 @@ class MainActivity : ComponentActivity() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens an item from the launch intent:
|
* Opens an item from the launch intent:
|
||||||
* `adb shell am start -S -n ru.stenfredd.movies/.MainActivity --es item <id> [--ez play true] [--el start <ms>]
|
* `adb shell am start -S -n ru.stenfredd.sleepyowl/.MainActivity --es item <id> [--ez play true] [--el start <ms>]
|
||||||
* [--ei audio <index>] [--ei sub <index>]` (stream indexes as Jellyfin numbers them; with one given, the other is off),
|
* [--ei audio <index>] [--ei sub <index>]` (stream indexes as Jellyfin numbers them; with one given, the other is off),
|
||||||
* or a series page: `--es series <id> [--es episode <id>]`. With both `item` (an episode) and `series`, the page
|
* or a series page: `--es series <id> [--es episode <id>]`. With both `item` (an episode) and `series`, the page
|
||||||
* under the player is the series page on that episode, as from the app's own cards (the TV's home screen does so).
|
* under the player is the series page on that episode, as from the app's own cards (the TV's home screen does so).
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies
|
package ru.stenfredd.sleepyowl
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import coil3.ImageLoader
|
import coil3.ImageLoader
|
||||||
@@ -21,7 +21,7 @@ import timber.log.Timber
|
|||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltAndroidApp
|
@HiltAndroidApp
|
||||||
class MoviesApp : Application(), SingletonImageLoader.Factory {
|
class SleepyOwlApp : Application(), SingletonImageLoader.Factory {
|
||||||
/** The API's client: images go to the server's LAN address at home too (`ServerRouting`), sharing its connections. */
|
/** The API's client: images go to the server's LAN address at home too (`ServerRouting`), sharing its connections. */
|
||||||
@Inject lateinit var httpClient: OkHttpClient
|
@Inject lateinit var httpClient: OkHttpClient
|
||||||
@Inject lateinit var launcherFeed: Lazy<LauncherFeed>
|
@Inject lateinit var launcherFeed: Lazy<LauncherFeed>
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui
|
package ru.stenfredd.sleepyowl.ui
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -39,11 +39,11 @@ import dagger.hilt.android.lifecycle.HiltViewModel
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import ru.stenfredd.movies.ui.components.TextInput
|
import ru.stenfredd.sleepyowl.ui.components.TextInput
|
||||||
import ru.stenfredd.movies.ui.components.rememberTextInputState
|
import ru.stenfredd.sleepyowl.ui.components.rememberTextInputState
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui
|
package ru.stenfredd.sleepyowl.ui
|
||||||
|
|
||||||
import org.jellyfin.sdk.api.client.extensions.imageApi
|
import org.jellyfin.sdk.api.client.extensions.imageApi
|
||||||
import org.jellyfin.sdk.api.client.extensions.libraryApi
|
import org.jellyfin.sdk.api.client.extensions.libraryApi
|
||||||
@@ -6,7 +6,7 @@ import org.jellyfin.sdk.model.api.BaseItemDto
|
|||||||
import org.jellyfin.sdk.model.api.BaseItemKind
|
import org.jellyfin.sdk.model.api.BaseItemKind
|
||||||
import org.jellyfin.sdk.model.api.ImageType
|
import org.jellyfin.sdk.model.api.ImageType
|
||||||
import org.jellyfin.sdk.model.api.ItemSortBy
|
import org.jellyfin.sdk.model.api.ItemSortBy
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package ru.stenfredd.movies.ui
|
package ru.stenfredd.sleepyowl.ui
|
||||||
|
|
||||||
import ru.stenfredd.movies.playback.api.EngineId
|
import ru.stenfredd.sleepyowl.playback.api.EngineId
|
||||||
import ru.stenfredd.movies.playback.api.StreamSelection
|
import ru.stenfredd.sleepyowl.playback.api.StreamSelection
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
sealed interface Screen {
|
sealed interface Screen {
|
||||||
@@ -13,7 +13,7 @@ sealed interface Screen {
|
|||||||
* after a profile switch the stack is rebuilt, and an equal entry would be kept with the old account's state.
|
* after a profile switch the stack is rebuilt, and an equal entry would be kept with the old account's state.
|
||||||
* [library]: the library tab opened on a library from the rail; a new entry, so the tab starts over on it.
|
* [library]: the library tab opened on a library from the rail; a new entry, so the tab starts over on it.
|
||||||
*/
|
*/
|
||||||
data class Root(val tab: ru.stenfredd.movies.ui.shell.Tab, val account: String, val library: UUID? = null) : Screen
|
data class Root(val tab: ru.stenfredd.sleepyowl.ui.shell.Tab, val account: String, val library: UUID? = null) : Screen
|
||||||
|
|
||||||
/** Collections and folders: the prototype's plain grid until they get a real screen. */
|
/** Collections and folders: the prototype's plain grid until they get a real screen. */
|
||||||
data class Items(val parentId: UUID, val title: String) : Screen
|
data class Items(val parentId: UUID, val title: String) : Screen
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui
|
package ru.stenfredd.sleepyowl.ui
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.KeyEvent as AndroidKeyEvent
|
import android.view.KeyEvent as AndroidKeyEvent
|
||||||
@@ -34,9 +34,9 @@ import androidx.tv.material3.Text
|
|||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import ru.stenfredd.movies.playback.api.StreamSelection
|
import ru.stenfredd.sleepyowl.playback.api.StreamSelection
|
||||||
import ru.stenfredd.movies.ui.player.PlayerScreen
|
import ru.stenfredd.sleepyowl.ui.player.PlayerScreen
|
||||||
import ru.stenfredd.movies.ui.player.TourInfo
|
import ru.stenfredd.sleepyowl.ui.player.TourInfo
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapShader
|
import android.graphics.BitmapShader
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
|
import androidx.compose.foundation.Image
|
||||||
|
import androidx.compose.foundation.layout.aspectRatio
|
||||||
|
import androidx.compose.foundation.layout.height
|
||||||
|
import androidx.compose.foundation.layout.size
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.res.painterResource
|
||||||
|
import androidx.compose.ui.res.stringResource
|
||||||
|
import androidx.compose.ui.unit.Dp
|
||||||
|
import androidx.compose.ui.unit.dp
|
||||||
|
import ru.stenfredd.sleepyowl.R
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The app's logo: the owl and the "SleepyOwl" wordmark from `design/logo/sleepyowl.png`, cut out of its navy
|
||||||
|
* background by `tools/logo/make_assets.py`. The pictures are made at the default sizes here (xhdpi), so on the TV
|
||||||
|
* they are drawn pixel for pixel; other sizes resample them.
|
||||||
|
*/
|
||||||
|
@Composable
|
||||||
|
fun OwlMark(modifier: Modifier = Modifier, size: Dp = 36.dp) {
|
||||||
|
Image(painterResource(R.drawable.logo_owl), null, modifier.size(size))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun Wordmark(modifier: Modifier = Modifier, height: Dp = 18.dp) {
|
||||||
|
val painter = painterResource(R.drawable.logo_wordmark)
|
||||||
|
Image(
|
||||||
|
painter,
|
||||||
|
stringResource(R.string.app_name),
|
||||||
|
modifier.height(height).aspectRatio(painter.intrinsicSize.width / painter.intrinsicSize.height),
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
@@ -27,8 +27,8 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.foundation.layout.widthIn
|
import androidx.compose.foundation.layout.widthIn
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
private val PrimaryFocus = FocusStyle(
|
private val PrimaryFocus = FocusStyle(
|
||||||
scale = 1.05f,
|
scale = 1.05f,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapShader
|
import android.graphics.BitmapShader
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
@@ -27,11 +27,11 @@ import androidx.compose.ui.geometry.Size
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ru.stenfredd.movies.ui.menu.WatchTarget
|
import ru.stenfredd.sleepyowl.ui.menu.WatchTarget
|
||||||
import ru.stenfredd.movies.ui.menu.clickableWithMenu
|
import ru.stenfredd.sleepyowl.ui.menu.clickableWithMenu
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/** What a poster card shows. Built by view models from server data; composables never see SDK DTOs. */
|
/** What a poster card shows. Built by view models from server data; composables never see SDK DTOs. */
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import android.graphics.DashPathEffect
|
import android.graphics.DashPathEffect
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import androidx.compose.animation.core.Animatable
|
import androidx.compose.animation.core.Animatable
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
@@ -26,7 +26,7 @@ import androidx.compose.ui.unit.IntOffset
|
|||||||
import androidx.compose.ui.unit.IntSize
|
import androidx.compose.ui.unit.IntSize
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
|
|
||||||
/** Focus look of a card: scale, outer ring and glow, as `style-focus` in the mockup (sizes in dp). */
|
/** Focus look of a card: scale, outer ring and glow, as `style-focus` in the mockup (sizes in dp). */
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BlurMaskFilter
|
import android.graphics.BlurMaskFilter
|
||||||
@@ -9,7 +9,7 @@ import android.util.LruCache
|
|||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
import androidx.compose.ui.graphics.asImageBitmap
|
import androidx.compose.ui.graphics.asImageBitmap
|
||||||
import androidx.compose.ui.graphics.toArgb
|
import java.nio.ByteBuffer
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -46,20 +46,63 @@ object GlowCache {
|
|||||||
val margin = key.layers.maxOf { it.blurPx + it.spreadPx }
|
val margin = key.layers.maxOf { it.blurPx + it.spreadPx }
|
||||||
val w = ((key.w + 2 * margin) * SCALE).roundToInt().coerceAtLeast(1)
|
val w = ((key.w + 2 * margin) * SCALE).roundToInt().coerceAtLeast(1)
|
||||||
val h = ((key.h + 2 * margin) * SCALE).roundToInt().coerceAtLeast(1)
|
val h = ((key.h + 2 * margin) * SCALE).roundToInt().coerceAtLeast(1)
|
||||||
val bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
|
// Each layer's coverage is drawn at full strength (255 levels) and the layers are composited in float:
|
||||||
val canvas = Canvas(bitmap)
|
// a dim colour stored directly in 8 bits has only 15–60 levels per channel, so the tail shows bands
|
||||||
|
// several px wide and R, G, B step at different places — a visible staircase with colour shifts.
|
||||||
|
val mask = Bitmap.createBitmap(w, h, Bitmap.Config.ALPHA_8)
|
||||||
|
val canvas = Canvas(mask)
|
||||||
canvas.scale(SCALE, SCALE)
|
canvas.scale(SCALE, SCALE)
|
||||||
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
|
val paint = Paint(Paint.ANTI_ALIAS_FLAG)
|
||||||
|
val stride = mask.rowBytes
|
||||||
|
val coverage = ByteBuffer.allocate(stride * h)
|
||||||
|
val premul = FloatArray(w * h * 4)
|
||||||
for (layer in key.layers) {
|
for (layer in key.layers) {
|
||||||
|
mask.eraseColor(0)
|
||||||
// CSS blur radius B is a Gaussian with sigma B/2; BlurMaskFilter's radius r has sigma ≈ 0.57735·r + 0.5.
|
// CSS blur radius B is a Gaussian with sigma B/2; BlurMaskFilter's radius r has sigma ≈ 0.57735·r + 0.5.
|
||||||
val radius = ((layer.blurPx / 2 - 0.5f) / 0.57735f).coerceAtLeast(0.5f)
|
val radius = ((layer.blurPx / 2 - 0.5f) / 0.57735f).coerceAtLeast(0.5f)
|
||||||
paint.maskFilter = BlurMaskFilter(radius, BlurMaskFilter.Blur.NORMAL)
|
paint.maskFilter = BlurMaskFilter(radius, BlurMaskFilter.Blur.NORMAL)
|
||||||
paint.color = layer.color.toArgb()
|
|
||||||
val s = layer.spreadPx
|
val s = layer.spreadPx
|
||||||
val rect = RectF(margin - s, margin - s, margin + key.w + s, margin + key.h + s)
|
val rect = RectF(margin - s, margin - s, margin + key.w + s, margin + key.h + s)
|
||||||
val corner = key.corner + s
|
val corner = key.corner + s
|
||||||
canvas.drawRoundRect(rect, corner, corner, paint)
|
canvas.drawRoundRect(rect, corner, corner, paint)
|
||||||
|
coverage.rewind()
|
||||||
|
mask.copyPixelsToBuffer(coverage)
|
||||||
|
val px = coverage.array()
|
||||||
|
val c = layer.color
|
||||||
|
for (y in 0 until h) for (x in 0 until w) {
|
||||||
|
val v = px[y * stride + x].toInt() and 0xFF
|
||||||
|
if (v == 0) continue
|
||||||
|
val a = c.alpha * v / 255f
|
||||||
|
val i = (y * w + x) * 4
|
||||||
|
premul[i] = c.red * a + premul[i] * (1 - a)
|
||||||
|
premul[i + 1] = c.green * a + premul[i + 1] * (1 - a)
|
||||||
|
premul[i + 2] = c.blue * a + premul[i + 2] * (1 - a)
|
||||||
|
premul[i + 3] = a + premul[i + 3] * (1 - a)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
// To 8 bits with ±1.5 levels of noise: invisible, but the average is smooth. White noise rather than
|
||||||
|
// a finer pattern, since the bitmap is upscaled 2× and the filtering would average a fine pattern out.
|
||||||
|
val out = ByteBuffer.allocate(w * h * 4)
|
||||||
|
val bytes = out.array()
|
||||||
|
for (i in 0 until w * h) {
|
||||||
|
val o = i * 4
|
||||||
|
if (premul[o + 3] <= 0f) continue
|
||||||
|
val n = 3f * noise(i) - 1.5f
|
||||||
|
val a = (premul[o + 3] * 255f + n).roundToInt().coerceIn(0, 255)
|
||||||
|
for (k in 0..2) bytes[o + k] = (premul[o + k] * 255f + n).roundToInt().coerceIn(0, a).toByte()
|
||||||
|
bytes[o + 3] = a.toByte()
|
||||||
|
}
|
||||||
|
val bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888)
|
||||||
|
bitmap.copyPixelsFromBuffer(out)
|
||||||
return Glow(bitmap.asImageBitmap(), margin)
|
return Glow(bitmap.asImageBitmap(), margin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Hash-based white noise, 0..1. */
|
||||||
|
private fun noise(i: Int): Float {
|
||||||
|
var x = i * 0x27d4eb2d
|
||||||
|
x = (x xor (x ushr 15)) * 0x2c1b3c6d
|
||||||
|
x = (x xor (x ushr 12)) * 0x297a2d39
|
||||||
|
x = x xor (x ushr 15)
|
||||||
|
return (x ushr 8) / 16777216f
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
import androidx.compose.foundation.lazy.grid.GridItemSpan
|
||||||
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
import androidx.compose.foundation.lazy.grid.LazyGridScope
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -27,7 +27,7 @@ import coil3.request.ImageRequest
|
|||||||
import coil3.request.transformations
|
import coil3.request.transformations
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
|
|
||||||
/** A server image: URL of exactly the displayed size and the BlurHash shown while it loads. */
|
/** A server image: URL of exactly the displayed size and the BlurHash shown while it loads. */
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import androidx.compose.animation.core.FastOutSlowInEasing
|
import androidx.compose.animation.core.FastOutSlowInEasing
|
||||||
import androidx.compose.animation.core.tween
|
import androidx.compose.animation.core.tween
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
@@ -14,8 +14,8 @@ import androidx.compose.ui.Alignment
|
|||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.focus.focusRestorer
|
import androidx.compose.ui.focus.focusRestorer
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/** "Недавно добавлено 12" */
|
/** "Недавно добавлено 12" */
|
||||||
@Composable
|
@Composable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.components
|
package ru.stenfredd.sleepyowl.ui.components
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
import androidx.compose.foundation.layout.WindowInsets
|
||||||
@@ -52,7 +52,7 @@ import androidx.compose.ui.text.input.KeyboardType
|
|||||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||||
import androidx.compose.ui.text.input.VisualTransformation
|
import androidx.compose.ui.text.input.VisualTransformation
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remote-friendly text field state. D-pad focus lands on the field's frame only; OK (or [edit]) puts the cursor in
|
* Remote-friendly text field state. D-pad focus lands on the field's frame only; OK (or [edit]) puts the cursor in
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.details
|
package ru.stenfredd.sleepyowl.ui.details
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
@@ -11,7 +11,7 @@ import androidx.compose.ui.graphics.toArgb
|
|||||||
import coil3.size.Dimension
|
import coil3.size.Dimension
|
||||||
import coil3.size.Size
|
import coil3.size.Size
|
||||||
import coil3.transform.Transformation
|
import coil3.transform.Transformation
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The item page backdrop as one opaque bitmap: the image dimmed to 70 % over the app background and the mockup's
|
* The item page backdrop as one opaque bitmap: the image dimmed to 70 % over the app background and the mockup's
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.details
|
package ru.stenfredd.sleepyowl.ui.details
|
||||||
|
|
||||||
import android.graphics.RectF
|
import android.graphics.RectF
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@@ -52,32 +52,32 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||||||
import coil3.compose.AsyncImage
|
import coil3.compose.AsyncImage
|
||||||
import coil3.request.ImageRequest
|
import coil3.request.ImageRequest
|
||||||
import coil3.request.transformations
|
import coil3.request.transformations
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.AnchoredScrolling
|
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
|
||||||
import ru.stenfredd.movies.ui.components.AppIcon
|
import ru.stenfredd.sleepyowl.ui.components.AppIcon
|
||||||
import ru.stenfredd.movies.ui.components.Avatar
|
import ru.stenfredd.sleepyowl.ui.components.Avatar
|
||||||
import ru.stenfredd.movies.ui.components.Chip
|
import ru.stenfredd.sleepyowl.ui.components.Chip
|
||||||
import ru.stenfredd.movies.ui.components.CircleButton
|
import ru.stenfredd.sleepyowl.ui.components.CircleButton
|
||||||
import ru.stenfredd.movies.ui.components.ContentRow
|
import ru.stenfredd.sleepyowl.ui.components.ContentRow
|
||||||
import ru.stenfredd.movies.ui.components.DefaultScrolling
|
import ru.stenfredd.sleepyowl.ui.components.DefaultScrolling
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.FormatBadge
|
import ru.stenfredd.sleepyowl.ui.components.FormatBadge
|
||||||
import ru.stenfredd.movies.ui.components.PosterCard
|
import ru.stenfredd.sleepyowl.ui.components.PosterCard
|
||||||
import ru.stenfredd.movies.ui.components.PrimaryButton
|
import ru.stenfredd.sleepyowl.ui.components.PrimaryButton
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImage
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
|
||||||
import ru.stenfredd.movies.ui.components.SecondaryButton
|
import ru.stenfredd.sleepyowl.ui.components.SecondaryButton
|
||||||
import ru.stenfredd.movies.ui.components.SectionTitle
|
import ru.stenfredd.sleepyowl.ui.components.SectionTitle
|
||||||
import ru.stenfredd.movies.ui.components.anchorViewport
|
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
|
||||||
import ru.stenfredd.movies.ui.components.anchoredRow
|
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.focus.Restore
|
import ru.stenfredd.sleepyowl.ui.focus.Restore
|
||||||
import ru.stenfredd.movies.ui.focus.ScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
|
||||||
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
|
||||||
import ru.stenfredd.movies.ui.focus.remembered
|
import ru.stenfredd.sleepyowl.ui.focus.remembered
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
import ru.stenfredd.movies.ui.details.DetailsLayout as L
|
import ru.stenfredd.sleepyowl.ui.details.DetailsLayout as L
|
||||||
|
|
||||||
/** Movie (or episode) page, the mockup's "Фильм" screen. Full screen, without the side rail. */
|
/** Movie (or episode) page, the mockup's "Фильм" screen. Full screen, without the side rail. */
|
||||||
@Composable
|
@Composable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.details
|
package ru.stenfredd.sleepyowl.ui.details
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -17,20 +17,20 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.core.data.ImageUrls
|
import ru.stenfredd.sleepyowl.core.data.ImageUrls
|
||||||
import ru.stenfredd.movies.core.data.LibraryRepository
|
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
|
||||||
import ru.stenfredd.movies.core.data.SessionCache
|
import ru.stenfredd.sleepyowl.core.data.SessionCache
|
||||||
import ru.stenfredd.movies.core.data.WatchRepository
|
import ru.stenfredd.sleepyowl.core.data.WatchRepository
|
||||||
import ru.stenfredd.movies.core.data.model.ItemDetails
|
import ru.stenfredd.sleepyowl.core.data.model.ItemDetails
|
||||||
import ru.stenfredd.movies.core.data.model.ItemKind
|
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
|
||||||
import ru.stenfredd.movies.core.data.model.MediaInfo
|
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
|
||||||
import ru.stenfredd.movies.core.data.model.PersonKind
|
import ru.stenfredd.sleepyowl.core.data.model.PersonKind
|
||||||
import ru.stenfredd.movies.playback.api.StreamSelection
|
import ru.stenfredd.sleepyowl.playback.api.StreamSelection
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackPreferences
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackPreferences
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.PosterModel
|
import ru.stenfredd.sleepyowl.ui.components.PosterModel
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImageSpec
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
|
||||||
import ru.stenfredd.movies.ui.model.CardMapper
|
import ru.stenfredd.sleepyowl.ui.model.CardMapper
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package ru.stenfredd.movies.ui.details
|
package ru.stenfredd.sleepyowl.ui.details
|
||||||
|
|
||||||
import ru.stenfredd.movies.core.data.model.AudioTrack
|
import ru.stenfredd.sleepyowl.core.data.model.AudioTrack
|
||||||
import ru.stenfredd.movies.core.data.model.MediaInfo
|
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
|
||||||
import ru.stenfredd.movies.core.data.model.SubtitleTrack
|
import ru.stenfredd.sleepyowl.core.data.model.SubtitleTrack
|
||||||
import ru.stenfredd.movies.core.data.model.VideoRange
|
import ru.stenfredd.sleepyowl.core.data.model.VideoRange
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
/** How the item page names languages, codecs and formats: "Русский", "TrueHD Atmos 7.1", "HEVC 2160p HDR10 · 62.4 ГБ". */
|
/** How the item page names languages, codecs and formats: "Русский", "TrueHD Atmos 7.1", "HEVC 2160p HDR10 · 62.4 ГБ". */
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package ru.stenfredd.movies.ui.details
|
package ru.stenfredd.sleepyowl.ui.details
|
||||||
|
|
||||||
import ru.stenfredd.movies.core.data.model.MediaInfo
|
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackPreferences
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackPreferences
|
||||||
import ru.stenfredd.movies.playback.core.TrackPick
|
import ru.stenfredd.sleepyowl.playback.core.TrackPick
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
/** Audio and subtitle choices of a file as the movie page and the series tray show them. */
|
/** Audio and subtitle choices of a file as the movie page and the series tray show them. */
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.favorites
|
package ru.stenfredd.sleepyowl.ui.favorites
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -22,20 +22,20 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.AnchoredScrolling
|
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
|
||||||
import ru.stenfredd.movies.ui.components.Chip
|
import ru.stenfredd.sleepyowl.ui.components.Chip
|
||||||
import ru.stenfredd.movies.ui.components.PosterCard
|
import ru.stenfredd.sleepyowl.ui.components.PosterCard
|
||||||
import ru.stenfredd.movies.ui.components.anchorViewport
|
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
|
||||||
import ru.stenfredd.movies.ui.components.anchoredRow
|
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
|
||||||
import ru.stenfredd.movies.ui.components.fullItem
|
import ru.stenfredd.sleepyowl.ui.components.fullItem
|
||||||
import ru.stenfredd.movies.ui.focus.ForgetMissing
|
import ru.stenfredd.sleepyowl.ui.focus.ForgetMissing
|
||||||
import ru.stenfredd.movies.ui.focus.Restore
|
import ru.stenfredd.sleepyowl.ui.focus.Restore
|
||||||
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
|
||||||
import ru.stenfredd.movies.ui.focus.remembered
|
import ru.stenfredd.sleepyowl.ui.focus.remembered
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/** Favourites tab (mockup screen «Избранное»): title with the count, library filter chips, grid of posters. */
|
/** Favourites tab (mockup screen «Избранное»): title with the count, library filter chips, grid of posters. */
|
||||||
@Composable
|
@Composable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.favorites
|
package ru.stenfredd.sleepyowl.ui.favorites
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -15,15 +15,15 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.core.data.LibraryRepository
|
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
|
||||||
import ru.stenfredd.movies.core.data.SessionCache
|
import ru.stenfredd.sleepyowl.core.data.SessionCache
|
||||||
import ru.stenfredd.movies.core.data.WatchRepository
|
import ru.stenfredd.sleepyowl.core.data.WatchRepository
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSummary
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
|
||||||
import ru.stenfredd.movies.core.data.model.LibraryView
|
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.PosterModel
|
import ru.stenfredd.sleepyowl.ui.components.PosterModel
|
||||||
import ru.stenfredd.movies.ui.model.CardMapper
|
import ru.stenfredd.sleepyowl.ui.model.CardMapper
|
||||||
import ru.stenfredd.movies.ui.model.plural
|
import ru.stenfredd.sleepyowl.ui.model.plural
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.focus
|
package ru.stenfredd.sleepyowl.ui.focus
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.home
|
package ru.stenfredd.sleepyowl.ui.home
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -20,20 +20,20 @@ import androidx.compose.ui.focus.focusRestorer
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.AnchoredScrolling
|
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
|
||||||
import ru.stenfredd.movies.ui.components.anchorViewport
|
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
|
||||||
import ru.stenfredd.movies.ui.components.anchoredRow
|
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
|
||||||
import ru.stenfredd.movies.ui.components.ContentRow
|
import ru.stenfredd.sleepyowl.ui.components.ContentRow
|
||||||
import ru.stenfredd.movies.ui.components.FeaturedCard
|
import ru.stenfredd.sleepyowl.ui.components.FeaturedCard
|
||||||
import ru.stenfredd.movies.ui.components.PosterCard
|
import ru.stenfredd.sleepyowl.ui.components.PosterCard
|
||||||
import ru.stenfredd.movies.ui.components.SectionTitle
|
import ru.stenfredd.sleepyowl.ui.components.SectionTitle
|
||||||
import ru.stenfredd.movies.ui.components.WideCard
|
import ru.stenfredd.sleepyowl.ui.components.WideCard
|
||||||
import ru.stenfredd.movies.ui.focus.Restore
|
import ru.stenfredd.sleepyowl.ui.focus.Restore
|
||||||
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
|
||||||
import ru.stenfredd.movies.ui.focus.remembered
|
import ru.stenfredd.sleepyowl.ui.focus.remembered
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeScreen(onOpen: (Screen) -> Unit, vm: HomeViewModel = hiltViewModel()) {
|
fun HomeScreen(onOpen: (Screen) -> Unit, vm: HomeViewModel = hiltViewModel()) {
|
||||||
@@ -84,7 +84,7 @@ fun HomeScreen(onOpen: (Screen) -> Unit, vm: HomeViewModel = hiltViewModel()) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
private fun ContinueGrid(state: HomeState, focus: ru.stenfredd.movies.ui.focus.ScreenFocus, open: (String) -> Unit) {
|
private fun ContinueGrid(state: HomeState, focus: ru.stenfredd.sleepyowl.ui.focus.ScreenFocus, open: (String) -> Unit) {
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
Column(verticalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||||
state.continueItems.chunked(2).forEach { pair ->
|
state.continueItems.chunked(2).forEach { pair ->
|
||||||
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
|
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.home
|
package ru.stenfredd.sleepyowl.ui.home
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -12,14 +12,14 @@ import kotlinx.coroutines.flow.catch
|
|||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.stenfredd.movies.core.data.HomeContent
|
import ru.stenfredd.sleepyowl.core.data.HomeContent
|
||||||
import ru.stenfredd.movies.core.data.HomeRepository
|
import ru.stenfredd.sleepyowl.core.data.HomeRepository
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSummary
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.FeaturedModel
|
import ru.stenfredd.sleepyowl.ui.components.FeaturedModel
|
||||||
import ru.stenfredd.movies.ui.components.PosterModel
|
import ru.stenfredd.sleepyowl.ui.components.PosterModel
|
||||||
import ru.stenfredd.movies.ui.components.WideModel
|
import ru.stenfredd.sleepyowl.ui.components.WideModel
|
||||||
import ru.stenfredd.movies.ui.model.CardMapper
|
import ru.stenfredd.sleepyowl.ui.model.CardMapper
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package ru.stenfredd.movies.ui.library
|
package ru.stenfredd.sleepyowl.ui.library
|
||||||
|
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSort
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSort
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.library
|
package ru.stenfredd.sleepyowl.ui.library
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
@@ -46,27 +46,27 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.AnchoredScroll
|
import ru.stenfredd.sleepyowl.ui.components.AnchoredScroll
|
||||||
import ru.stenfredd.movies.ui.components.AnchoredScrolling
|
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
|
||||||
import ru.stenfredd.movies.ui.components.Chip
|
import ru.stenfredd.sleepyowl.ui.components.Chip
|
||||||
import ru.stenfredd.movies.ui.components.ContentRow
|
import ru.stenfredd.sleepyowl.ui.components.ContentRow
|
||||||
import ru.stenfredd.movies.ui.components.DefaultScrolling
|
import ru.stenfredd.sleepyowl.ui.components.DefaultScrolling
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.PosterCard
|
import ru.stenfredd.sleepyowl.ui.components.PosterCard
|
||||||
import ru.stenfredd.movies.ui.components.WideCard
|
import ru.stenfredd.sleepyowl.ui.components.WideCard
|
||||||
import ru.stenfredd.movies.ui.components.anchorViewport
|
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
|
||||||
import ru.stenfredd.movies.ui.components.anchoredRow
|
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
|
||||||
import ru.stenfredd.movies.ui.components.bleed
|
import ru.stenfredd.sleepyowl.ui.components.bleed
|
||||||
import ru.stenfredd.movies.ui.components.fullItem
|
import ru.stenfredd.sleepyowl.ui.components.fullItem
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.focus.Restore
|
import ru.stenfredd.sleepyowl.ui.focus.Restore
|
||||||
import ru.stenfredd.movies.ui.focus.ScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
|
||||||
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
|
||||||
import ru.stenfredd.movies.ui.focus.remembered
|
import ru.stenfredd.sleepyowl.ui.focus.remembered
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The library tab (mockup screen «Медиатека»): library tiles on top; under them, for the selected library,
|
* The library tab (mockup screen «Медиатека»): library tiles on top; under them, for the selected library,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.library
|
package ru.stenfredd.sleepyowl.ui.library
|
||||||
|
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
@@ -18,24 +18,24 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.core.data.LibraryRepository
|
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
|
||||||
import ru.stenfredd.movies.core.data.SessionCache
|
import ru.stenfredd.sleepyowl.core.data.SessionCache
|
||||||
import ru.stenfredd.movies.core.data.WatchRepository
|
import ru.stenfredd.sleepyowl.core.data.WatchRepository
|
||||||
import ru.stenfredd.movies.core.data.model.ItemKind
|
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
|
||||||
import ru.stenfredd.movies.core.data.model.ItemQuery
|
import ru.stenfredd.sleepyowl.core.data.model.ItemQuery
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSort
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSort
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSummary
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
|
||||||
import ru.stenfredd.movies.core.data.model.LibraryType
|
import ru.stenfredd.sleepyowl.core.data.model.LibraryType
|
||||||
import ru.stenfredd.movies.core.data.model.LibraryView
|
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
|
||||||
import ru.stenfredd.movies.core.data.model.itemKinds
|
import ru.stenfredd.sleepyowl.core.data.model.itemKinds
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.PosterModel
|
import ru.stenfredd.sleepyowl.ui.components.PosterModel
|
||||||
import ru.stenfredd.movies.ui.components.WideModel
|
import ru.stenfredd.sleepyowl.ui.components.WideModel
|
||||||
import ru.stenfredd.movies.ui.model.CardMapper
|
import ru.stenfredd.sleepyowl.ui.model.CardMapper
|
||||||
import ru.stenfredd.movies.ui.model.daysAgo
|
import ru.stenfredd.sleepyowl.ui.model.daysAgo
|
||||||
import ru.stenfredd.movies.ui.model.plural
|
import ru.stenfredd.sleepyowl.ui.model.plural
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.library
|
package ru.stenfredd.sleepyowl.ui.library
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
@@ -31,7 +31,7 @@ import kotlinx.coroutines.async
|
|||||||
import kotlinx.coroutines.awaitAll
|
import kotlinx.coroutines.awaitAll
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
|
|
||||||
/** A tile's background in its two looks: the selected library's mosaic is brighter. */
|
/** A tile's background in its two looks: the selected library's mosaic is brighter. */
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.login
|
package ru.stenfredd.sleepyowl.ui.login
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.foundation.Image
|
import androidx.compose.foundation.Image
|
||||||
@@ -31,7 +31,6 @@ import androidx.compose.runtime.setValue
|
|||||||
import androidx.compose.runtime.withFrameNanos
|
import androidx.compose.runtime.withFrameNanos
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.drawBehind
|
|
||||||
import androidx.compose.ui.focus.focusProperties
|
import androidx.compose.ui.focus.focusProperties
|
||||||
import androidx.compose.ui.focus.onFocusChanged
|
import androidx.compose.ui.focus.onFocusChanged
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
@@ -48,23 +47,25 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import ru.stenfredd.movies.ui.components.AppIcon
|
import ru.stenfredd.sleepyowl.ui.components.AppIcon
|
||||||
import ru.stenfredd.movies.ui.components.Avatar
|
import ru.stenfredd.sleepyowl.ui.components.Avatar
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.Icon
|
import ru.stenfredd.sleepyowl.ui.components.Icon
|
||||||
import ru.stenfredd.movies.ui.components.KeyboardLift
|
import ru.stenfredd.sleepyowl.ui.components.KeyboardLift
|
||||||
import ru.stenfredd.movies.ui.components.LocalKeyboardLift
|
import ru.stenfredd.sleepyowl.ui.components.LocalKeyboardLift
|
||||||
import ru.stenfredd.movies.ui.components.liftForKeyboard
|
import ru.stenfredd.sleepyowl.ui.components.OwlMark
|
||||||
import ru.stenfredd.movies.ui.components.StatusDot
|
import ru.stenfredd.sleepyowl.ui.components.liftForKeyboard
|
||||||
import ru.stenfredd.movies.ui.components.TextInput
|
import ru.stenfredd.sleepyowl.ui.components.StatusDot
|
||||||
import ru.stenfredd.movies.ui.components.dashedBorder
|
import ru.stenfredd.sleepyowl.ui.components.TextInput
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.Wordmark
|
||||||
import ru.stenfredd.movies.ui.components.rememberTextInputState
|
import ru.stenfredd.sleepyowl.ui.components.dashedBorder
|
||||||
import ru.stenfredd.movies.ui.focus.Restore
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.focus.ScreenFocus
|
import ru.stenfredd.sleepyowl.ui.components.rememberTextInputState
|
||||||
import ru.stenfredd.movies.ui.focus.remembered
|
import ru.stenfredd.sleepyowl.ui.focus.Restore
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.focus.remembered
|
||||||
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/** Login flow: server → profile → login, see [LoginViewModel]. Sizes are the mockup's px / 2. */
|
/** Login flow: server → profile → login, see [LoginViewModel]. Sizes are the mockup's px / 2. */
|
||||||
@Composable
|
@Composable
|
||||||
@@ -77,7 +78,7 @@ fun LoginScreen(onDone: () -> Unit, vm: LoginViewModel = hiltViewModel()) {
|
|||||||
val lift = remember { KeyboardLift() }
|
val lift = remember { KeyboardLift() }
|
||||||
Box(Modifier.fillMaxSize().liftForKeyboard(lift)) {
|
Box(Modifier.fillMaxSize().liftForKeyboard(lift)) {
|
||||||
CompositionLocalProvider(LocalKeyboardLift provides lift) {
|
CompositionLocalProvider(LocalKeyboardLift provides lift) {
|
||||||
Logo(Modifier.padding(start = 60.dp, top = 32.dp))
|
Logo(Modifier.padding(start = 60.dp, top = 29.dp))
|
||||||
StepChain(state.step, Modifier.align(Alignment.TopEnd).padding(end = 60.dp, top = 35.dp))
|
StepChain(state.step, Modifier.align(Alignment.TopEnd).padding(end = 60.dp, top = 35.dp))
|
||||||
val focus = vm.focus.getValue(state.step)
|
val focus = vm.focus.getValue(state.step)
|
||||||
key(state.step) {
|
key(state.step) {
|
||||||
@@ -105,17 +106,12 @@ private fun hint(state: LoginState) = when (state.step) {
|
|||||||
|
|
||||||
// ---- Header ----
|
// ---- Header ----
|
||||||
|
|
||||||
/** Neutral placeholder logo until the app has a name (same as the side rail's). */
|
/** Same as the open side rail's. */
|
||||||
@Composable
|
@Composable
|
||||||
private fun Logo(modifier: Modifier = Modifier) {
|
private fun Logo(modifier: Modifier = Modifier) {
|
||||||
Row(modifier, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
Row(modifier, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
Spacer(
|
OwlMark()
|
||||||
Modifier.size(9.dp).drawBehind {
|
Wordmark()
|
||||||
drawCircle(AppColors.AccentStrong.copy(alpha = 0.35f), radius = size.minDimension)
|
|
||||||
drawCircle(AppColors.AccentStrong)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
BasicText("movies", style = AppType.Display.copy(fontSize = 18.sp, fontWeight = FontWeight.Bold, letterSpacing = 0.em))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.login
|
package ru.stenfredd.sleepyowl.ui.login
|
||||||
|
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
@@ -19,14 +19,14 @@ import kotlinx.coroutines.isActive
|
|||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import org.jellyfin.sdk.api.client.exception.InvalidStatusException
|
import org.jellyfin.sdk.api.client.exception.InvalidStatusException
|
||||||
import ru.stenfredd.movies.core.jellyfin.Account
|
import ru.stenfredd.sleepyowl.core.jellyfin.Account
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import ru.stenfredd.movies.core.jellyfin.PublicUser
|
import ru.stenfredd.sleepyowl.core.jellyfin.PublicUser
|
||||||
import ru.stenfredd.movies.core.jellyfin.QuickConnectExpiredException
|
import ru.stenfredd.sleepyowl.core.jellyfin.QuickConnectExpiredException
|
||||||
import ru.stenfredd.movies.core.jellyfin.Server
|
import ru.stenfredd.sleepyowl.core.jellyfin.Server
|
||||||
import ru.stenfredd.movies.core.jellyfin.ServerLogin
|
import ru.stenfredd.sleepyowl.core.jellyfin.ServerLogin
|
||||||
import ru.stenfredd.movies.core.jellyfin.ServerNotFoundException
|
import ru.stenfredd.sleepyowl.core.jellyfin.ServerNotFoundException
|
||||||
import ru.stenfredd.movies.ui.focus.ScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.login
|
package ru.stenfredd.sleepyowl.ui.login
|
||||||
|
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import androidx.compose.ui.graphics.ImageBitmap
|
import androidx.compose.ui.graphics.ImageBitmap
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.menu
|
package ru.stenfredd.sleepyowl.ui.menu
|
||||||
|
|
||||||
import android.view.KeyEvent as AndroidKeyEvent
|
import android.view.KeyEvent as AndroidKeyEvent
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@@ -49,16 +49,16 @@ import androidx.lifecycle.ViewModel
|
|||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.stenfredd.movies.core.data.WatchRepository
|
import ru.stenfredd.sleepyowl.core.data.WatchRepository
|
||||||
import ru.stenfredd.movies.core.data.model.ItemKind
|
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
|
||||||
import ru.stenfredd.movies.ui.components.AppIcon
|
import ru.stenfredd.sleepyowl.ui.components.AppIcon
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.Icon
|
import ru.stenfredd.sleepyowl.ui.components.Icon
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.model.plural
|
import ru.stenfredd.sleepyowl.ui.model.plural
|
||||||
import ru.stenfredd.movies.ui.player.SidePanel
|
import ru.stenfredd.sleepyowl.ui.player.SidePanel
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -1,18 +1,18 @@
|
|||||||
package ru.stenfredd.movies.ui.model
|
package ru.stenfredd.sleepyowl.ui.model
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
import ru.stenfredd.movies.core.data.ImageUrls
|
import ru.stenfredd.sleepyowl.core.data.ImageUrls
|
||||||
import ru.stenfredd.movies.core.data.model.ImageRef
|
import ru.stenfredd.sleepyowl.core.data.model.ImageRef
|
||||||
import ru.stenfredd.movies.core.data.model.ItemKind
|
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSummary
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.FeaturedModel
|
import ru.stenfredd.sleepyowl.ui.components.FeaturedModel
|
||||||
import ru.stenfredd.movies.ui.components.PosterModel
|
import ru.stenfredd.sleepyowl.ui.components.PosterModel
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImageSpec
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
|
||||||
import ru.stenfredd.movies.ui.components.WideModel
|
import ru.stenfredd.sleepyowl.ui.components.WideModel
|
||||||
import ru.stenfredd.movies.ui.menu.WatchTarget
|
import ru.stenfredd.sleepyowl.ui.menu.WatchTarget
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.model
|
package ru.stenfredd.sleepyowl.ui.model
|
||||||
|
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.person
|
package ru.stenfredd.sleepyowl.ui.person
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -22,20 +22,20 @@ import androidx.compose.ui.unit.dp
|
|||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.AnchoredScrolling
|
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
|
||||||
import ru.stenfredd.movies.ui.components.Avatar
|
import ru.stenfredd.sleepyowl.ui.components.Avatar
|
||||||
import ru.stenfredd.movies.ui.components.PosterCard
|
import ru.stenfredd.sleepyowl.ui.components.PosterCard
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImage
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
|
||||||
import ru.stenfredd.movies.ui.components.anchorViewport
|
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
|
||||||
import ru.stenfredd.movies.ui.components.anchoredRow
|
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
|
||||||
import ru.stenfredd.movies.ui.components.fullItem
|
import ru.stenfredd.sleepyowl.ui.components.fullItem
|
||||||
import ru.stenfredd.movies.ui.focus.Restore
|
import ru.stenfredd.sleepyowl.ui.focus.Restore
|
||||||
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
|
||||||
import ru.stenfredd.movies.ui.focus.remembered
|
import ru.stenfredd.sleepyowl.ui.focus.remembered
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A person (not in the mockup, built in its style like the favourites screen): photo, name, "12 фильмов · 3 сериала",
|
* A person (not in the mockup, built in its style like the favourites screen): photo, name, "12 фильмов · 3 сериала",
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.person
|
package ru.stenfredd.sleepyowl.ui.person
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -16,14 +16,14 @@ import kotlinx.coroutines.flow.StateFlow
|
|||||||
import kotlinx.coroutines.flow.asStateFlow
|
import kotlinx.coroutines.flow.asStateFlow
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.core.data.LibraryRepository
|
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
|
||||||
import ru.stenfredd.movies.core.data.SessionCache
|
import ru.stenfredd.sleepyowl.core.data.SessionCache
|
||||||
import ru.stenfredd.movies.core.data.model.ItemKind
|
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.PosterModel
|
import ru.stenfredd.sleepyowl.ui.components.PosterModel
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImageSpec
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
|
||||||
import ru.stenfredd.movies.ui.model.CardMapper
|
import ru.stenfredd.sleepyowl.ui.model.CardMapper
|
||||||
import ru.stenfredd.movies.ui.model.plural
|
import ru.stenfredd.sleepyowl.ui.model.plural
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.player
|
package ru.stenfredd.sleepyowl.ui.player
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
@@ -21,15 +21,15 @@ import androidx.tv.material3.MaterialTheme
|
|||||||
import androidx.tv.material3.Text
|
import androidx.tv.material3.Text
|
||||||
import org.jellyfin.sdk.model.api.MediaStreamType
|
import org.jellyfin.sdk.model.api.MediaStreamType
|
||||||
import org.jellyfin.sdk.model.api.PlayMethod
|
import org.jellyfin.sdk.model.api.PlayMethod
|
||||||
import ru.stenfredd.movies.playback.api.Codecs
|
import ru.stenfredd.sleepyowl.playback.api.Codecs
|
||||||
import ru.stenfredd.movies.playback.api.DolbyVisionSwitchable
|
import ru.stenfredd.sleepyowl.playback.api.DolbyVisionSwitchable
|
||||||
import ru.stenfredd.movies.playback.api.EngineId
|
import ru.stenfredd.sleepyowl.playback.api.EngineId
|
||||||
import ru.stenfredd.movies.playback.api.VideoPathSwitchable
|
import ru.stenfredd.sleepyowl.playback.api.VideoPathSwitchable
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackSession
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackSession
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackUiState
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackUiState
|
||||||
import ru.stenfredd.movies.playback.core.describe
|
import ru.stenfredd.sleepyowl.playback.core.describe
|
||||||
import ru.stenfredd.movies.playback.exo.ExoEngineProvider
|
import ru.stenfredd.sleepyowl.playback.exo.ExoEngineProvider
|
||||||
import ru.stenfredd.movies.playback.vlc.VlcEngineProvider
|
import ru.stenfredd.sleepyowl.playback.vlc.VlcEngineProvider
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Debug builds only: the prototype's numbered playback variants (badge in the corner, digit keys 0–9, MENU opens the
|
* Debug builds only: the prototype's numbered playback variants (badge in the corner, digit keys 0–9, MENU opens the
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.player
|
package ru.stenfredd.sleepyowl.ui.player
|
||||||
|
|
||||||
import android.view.KeyEvent as AndroidKeyEvent
|
import android.view.KeyEvent as AndroidKeyEvent
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@@ -48,16 +48,16 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.em
|
import androidx.compose.ui.unit.em
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ru.stenfredd.movies.ui.components.AppIcon
|
import ru.stenfredd.sleepyowl.ui.components.AppIcon
|
||||||
import ru.stenfredd.movies.ui.components.Avatar
|
import ru.stenfredd.sleepyowl.ui.components.Avatar
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.Icon
|
import ru.stenfredd.sleepyowl.ui.components.Icon
|
||||||
import ru.stenfredd.movies.ui.components.ImageShade
|
import ru.stenfredd.sleepyowl.ui.components.ImageShade
|
||||||
import ru.stenfredd.movies.ui.components.ProgressLine
|
import ru.stenfredd.sleepyowl.ui.components.ProgressLine
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImage
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
/** Height of the drawer; the controls move up by this much while it is open. */
|
/** Height of the drawer; the controls move up by this much while it is open. */
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
package ru.stenfredd.movies.ui.player
|
package ru.stenfredd.sleepyowl.ui.player
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import org.jellyfin.sdk.model.api.PlayMethod
|
import org.jellyfin.sdk.model.api.PlayMethod
|
||||||
import ru.stenfredd.movies.core.data.model.MediaInfo
|
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
|
||||||
import ru.stenfredd.movies.core.data.model.VideoRange
|
import ru.stenfredd.sleepyowl.core.data.model.VideoRange
|
||||||
import ru.stenfredd.movies.playback.api.DolbyVisionSwitchable
|
import ru.stenfredd.sleepyowl.playback.api.DolbyVisionSwitchable
|
||||||
import ru.stenfredd.movies.playback.api.PlaybackEngine
|
import ru.stenfredd.sleepyowl.playback.api.PlaybackEngine
|
||||||
import ru.stenfredd.movies.playback.api.VideoPathSwitchable
|
import ru.stenfredd.sleepyowl.playback.api.VideoPathSwitchable
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackUiState
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackUiState
|
||||||
import ru.stenfredd.movies.ui.details.MediaLabels
|
import ru.stenfredd.sleepyowl.ui.details.MediaLabels
|
||||||
import ru.stenfredd.movies.ui.details.TrackOption
|
import ru.stenfredd.sleepyowl.ui.details.TrackOption
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
/** Audio and subtitle choices of the file being played. Subtitles start with "Выкл" (index null). */
|
/** Audio and subtitle choices of the file being played. Subtitles start with "Выкл" (index null). */
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.player
|
package ru.stenfredd.sleepyowl.ui.player
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
@@ -33,13 +33,13 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.em
|
import androidx.compose.ui.unit.em
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ru.stenfredd.movies.ui.components.AppIcon
|
import ru.stenfredd.sleepyowl.ui.components.AppIcon
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.Icon
|
import ru.stenfredd.sleepyowl.ui.components.Icon
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImage
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/** Without known credits the card shows this long before the end of an episode that has a next one. */
|
/** Without known credits the card shows this long before the end of an episode that has a next one. */
|
||||||
internal const val NEXT_PROMPT_MS = 30_000L
|
internal const val NEXT_PROMPT_MS = 30_000L
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.player
|
package ru.stenfredd.sleepyowl.ui.player
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
@@ -39,16 +39,16 @@ import androidx.compose.ui.unit.Dp
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.em
|
import androidx.compose.ui.unit.em
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ru.stenfredd.movies.core.data.model.MediaSegment
|
import ru.stenfredd.sleepyowl.core.data.model.MediaSegment
|
||||||
import ru.stenfredd.movies.ui.components.AppIcon
|
import ru.stenfredd.sleepyowl.ui.components.AppIcon
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.Icon
|
import ru.stenfredd.sleepyowl.ui.components.Icon
|
||||||
import ru.stenfredd.movies.ui.components.StatusDot
|
import ru.stenfredd.sleepyowl.ui.components.StatusDot
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.shell.Clock
|
import ru.stenfredd.sleepyowl.ui.shell.Clock
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The player's controls ("OSD") as drawn in the mockup's player screen; sizes are the mockup's px / 2.
|
* The player's controls ("OSD") as drawn in the mockup's player screen; sizes are the mockup's px / 2.
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.player
|
package ru.stenfredd.sleepyowl.ui.player
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
@@ -46,14 +46,14 @@ import androidx.compose.ui.text.style.TextOverflow
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.em
|
import androidx.compose.ui.unit.em
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ru.stenfredd.movies.playback.api.SubtitleStyle
|
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.MinimalScrolling
|
import ru.stenfredd.sleepyowl.ui.components.MinimalScrolling
|
||||||
import ru.stenfredd.movies.ui.components.SecondaryButton
|
import ru.stenfredd.sleepyowl.ui.components.SecondaryButton
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.details.TrackOption
|
import ru.stenfredd.sleepyowl.ui.details.TrackOption
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
enum class PlayerPanel { Audio, Subtitles, Quality, Info }
|
enum class PlayerPanel { Audio, Subtitles, Quality, Info }
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.player
|
package ru.stenfredd.sleepyowl.ui.player
|
||||||
|
|
||||||
import android.view.KeyEvent as AndroidKeyEvent
|
import android.view.KeyEvent as AndroidKeyEvent
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
@@ -49,24 +49,24 @@ import androidx.lifecycle.Lifecycle
|
|||||||
import androidx.lifecycle.compose.LifecycleEventEffect
|
import androidx.lifecycle.compose.LifecycleEventEffect
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import ru.stenfredd.movies.BuildConfig
|
import ru.stenfredd.sleepyowl.BuildConfig
|
||||||
import ru.stenfredd.movies.core.data.model.MediaInfo
|
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
|
||||||
import ru.stenfredd.movies.core.data.model.MediaSegment
|
import ru.stenfredd.sleepyowl.core.data.model.MediaSegment
|
||||||
import ru.stenfredd.movies.core.data.model.VideoRange
|
import ru.stenfredd.sleepyowl.core.data.model.VideoRange
|
||||||
import ru.stenfredd.movies.core.data.toMediaInfo
|
import ru.stenfredd.sleepyowl.core.data.toMediaInfo
|
||||||
import ru.stenfredd.movies.playback.api.DolbyVisionSwitchable
|
import ru.stenfredd.sleepyowl.playback.api.DolbyVisionSwitchable
|
||||||
import ru.stenfredd.movies.playback.api.EngineId
|
import ru.stenfredd.sleepyowl.playback.api.EngineId
|
||||||
import ru.stenfredd.movies.playback.api.EngineState
|
import ru.stenfredd.sleepyowl.playback.api.EngineState
|
||||||
import ru.stenfredd.movies.playback.api.SubtitleStyle
|
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
|
||||||
import ru.stenfredd.movies.playback.api.VideoPathSwitchable
|
import ru.stenfredd.sleepyowl.playback.api.VideoPathSwitchable
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackSession
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackSession
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackUiState
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackUiState
|
||||||
import ru.stenfredd.movies.playback.exo.ExoEngineProvider
|
import ru.stenfredd.sleepyowl.playback.exo.ExoEngineProvider
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.AppIcon
|
import ru.stenfredd.sleepyowl.ui.components.AppIcon
|
||||||
import ru.stenfredd.movies.ui.components.SecondaryButton
|
import ru.stenfredd.sleepyowl.ui.components.SecondaryButton
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
import java.time.LocalTime
|
import java.time.LocalTime
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.player
|
package ru.stenfredd.sleepyowl.ui.player
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
@@ -24,14 +24,14 @@ import androidx.compose.ui.graphics.Color
|
|||||||
import androidx.compose.ui.text.font.FontWeight
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ru.stenfredd.movies.core.data.model.MediaSegment
|
import ru.stenfredd.sleepyowl.core.data.model.MediaSegment
|
||||||
import ru.stenfredd.movies.core.data.model.SegmentKind
|
import ru.stenfredd.sleepyowl.core.data.model.SegmentKind
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackDefaults
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackDefaults
|
||||||
import ru.stenfredd.movies.playback.core.SkipMode
|
import ru.stenfredd.sleepyowl.playback.core.SkipMode
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
|
|
||||||
/** The server's segments of one item (they arrive after the item starts playing). */
|
/** The server's segments of one item (they arrive after the item starts playing). */
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.player
|
package ru.stenfredd.sleepyowl.ui.player
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -14,26 +14,26 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.core.data.LibraryRepository
|
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
|
||||||
import ru.stenfredd.movies.core.data.model.ItemDetails
|
import ru.stenfredd.sleepyowl.core.data.model.ItemDetails
|
||||||
import ru.stenfredd.movies.core.data.model.ItemKind
|
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSummary
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
|
||||||
import ru.stenfredd.movies.core.data.model.PersonKind
|
import ru.stenfredd.sleepyowl.core.data.model.PersonKind
|
||||||
import ru.stenfredd.movies.playback.api.EngineId
|
import ru.stenfredd.sleepyowl.playback.api.EngineId
|
||||||
import ru.stenfredd.movies.playback.api.StreamSelection
|
import ru.stenfredd.sleepyowl.playback.api.StreamSelection
|
||||||
import ru.stenfredd.movies.playback.api.SubtitleStyle
|
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
|
||||||
import ru.stenfredd.movies.playback.core.DeviceCapabilitiesProbe
|
import ru.stenfredd.sleepyowl.playback.core.DeviceCapabilitiesProbe
|
||||||
import ru.stenfredd.movies.playback.core.EngineSelector
|
import ru.stenfredd.sleepyowl.playback.core.EngineSelector
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackDefaults
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackDefaults
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackPreferences
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackPreferences
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackSession
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackSession
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackSessionFactory
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackSessionFactory
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImageSpec
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
|
||||||
import ru.stenfredd.movies.ui.model.plural
|
import ru.stenfredd.sleepyowl.ui.model.plural
|
||||||
import ru.stenfredd.movies.ui.details.CastModel
|
import ru.stenfredd.sleepyowl.ui.details.CastModel
|
||||||
import ru.stenfredd.movies.ui.details.MediaLabels
|
import ru.stenfredd.sleepyowl.ui.details.MediaLabels
|
||||||
import ru.stenfredd.movies.ui.model.CardMapper
|
import ru.stenfredd.sleepyowl.ui.model.CardMapper
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.search
|
package ru.stenfredd.sleepyowl.ui.search
|
||||||
|
|
||||||
import android.view.KeyEvent as NativeKeyEvent
|
import android.view.KeyEvent as NativeKeyEvent
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@@ -48,26 +48,26 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.AnchoredScrolling
|
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
|
||||||
import ru.stenfredd.movies.ui.components.AppIcon
|
import ru.stenfredd.sleepyowl.ui.components.AppIcon
|
||||||
import ru.stenfredd.movies.ui.components.Avatar
|
import ru.stenfredd.sleepyowl.ui.components.Avatar
|
||||||
import ru.stenfredd.movies.ui.components.Chip
|
import ru.stenfredd.sleepyowl.ui.components.Chip
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.Icon
|
import ru.stenfredd.sleepyowl.ui.components.Icon
|
||||||
import ru.stenfredd.movies.ui.components.PosterCard
|
import ru.stenfredd.sleepyowl.ui.components.PosterCard
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImage
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
|
||||||
import ru.stenfredd.movies.ui.components.anchorViewport
|
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
|
||||||
import ru.stenfredd.movies.ui.components.anchoredRow
|
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.components.fullItem
|
import ru.stenfredd.sleepyowl.ui.components.fullItem
|
||||||
import ru.stenfredd.movies.ui.focus.Restore
|
import ru.stenfredd.sleepyowl.ui.focus.Restore
|
||||||
import ru.stenfredd.movies.ui.focus.ScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
|
||||||
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
|
||||||
import ru.stenfredd.movies.ui.focus.remembered
|
import ru.stenfredd.sleepyowl.ui.focus.remembered
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search tab (mockup screen «Поиск»): on the left the query and an on-screen keyboard (Russian; one key switches
|
* Search tab (mockup screen «Поиск»): on the left the query and an on-screen keyboard (Russian; one key switches
|
||||||
@@ -269,10 +269,10 @@ private fun Results(state: SearchState, focus: ScreenFocus, vm: SearchViewModel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun androidx.compose.foundation.lazy.grid.LazyGridScope.posters(
|
private fun androidx.compose.foundation.lazy.grid.LazyGridScope.posters(
|
||||||
list: List<ru.stenfredd.movies.ui.components.PosterModel>,
|
list: List<ru.stenfredd.sleepyowl.ui.components.PosterModel>,
|
||||||
focus: ScreenFocus,
|
focus: ScreenFocus,
|
||||||
open: (String) -> Unit,
|
open: (String) -> Unit,
|
||||||
anchored: ru.stenfredd.movies.ui.components.AnchoredScroll<*>,
|
anchored: ru.stenfredd.sleepyowl.ui.components.AnchoredScroll<*>,
|
||||||
) {
|
) {
|
||||||
items(list, key = { it.key }, contentType = { "poster" }) { p ->
|
items(list, key = { it.key }, contentType = { "poster" }) { p ->
|
||||||
PosterCard(p, { open(p.key) }, Modifier.padding(bottom = 18.dp).anchoredRow(anchored).remembered(focus, p.key))
|
PosterCard(p, { open(p.key) }, Modifier.padding(bottom = 18.dp).anchoredRow(anchored).remembered(focus, p.key))
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.search
|
package ru.stenfredd.sleepyowl.ui.search
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
@@ -17,13 +17,13 @@ import kotlinx.coroutines.flow.asStateFlow
|
|||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.core.data.LibraryRepository
|
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
|
||||||
import ru.stenfredd.movies.core.data.SearchHistory
|
import ru.stenfredd.sleepyowl.core.data.SearchHistory
|
||||||
import ru.stenfredd.movies.core.data.model.Person
|
import ru.stenfredd.sleepyowl.core.data.model.Person
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.PosterModel
|
import ru.stenfredd.sleepyowl.ui.components.PosterModel
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImageSpec
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
|
||||||
import ru.stenfredd.movies.ui.model.CardMapper
|
import ru.stenfredd.sleepyowl.ui.model.CardMapper
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.series
|
package ru.stenfredd.sleepyowl.ui.series
|
||||||
|
|
||||||
import android.view.KeyEvent as AndroidKeyEvent
|
import android.view.KeyEvent as AndroidKeyEvent
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
@@ -69,26 +69,26 @@ import androidx.compose.ui.unit.sp
|
|||||||
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.AppIcon
|
import ru.stenfredd.sleepyowl.ui.components.AppIcon
|
||||||
import ru.stenfredd.movies.ui.components.CircleButton
|
import ru.stenfredd.sleepyowl.ui.components.CircleButton
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.FormatBadge
|
import ru.stenfredd.sleepyowl.ui.components.FormatBadge
|
||||||
import ru.stenfredd.movies.ui.components.MinimalScrolling
|
import ru.stenfredd.sleepyowl.ui.components.MinimalScrolling
|
||||||
import ru.stenfredd.movies.ui.components.PrimaryButton
|
import ru.stenfredd.sleepyowl.ui.components.PrimaryButton
|
||||||
import ru.stenfredd.movies.ui.components.ProgressLine
|
import ru.stenfredd.sleepyowl.ui.components.ProgressLine
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImage
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.details.Backdrop
|
import ru.stenfredd.sleepyowl.ui.details.Backdrop
|
||||||
import ru.stenfredd.movies.ui.focus.Restore
|
import ru.stenfredd.sleepyowl.ui.focus.Restore
|
||||||
import ru.stenfredd.movies.ui.focus.ScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
|
||||||
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
|
||||||
import ru.stenfredd.movies.ui.focus.remembered
|
import ru.stenfredd.sleepyowl.ui.focus.remembered
|
||||||
import ru.stenfredd.movies.ui.menu.LocalWatchMenu
|
import ru.stenfredd.sleepyowl.ui.menu.LocalWatchMenu
|
||||||
import ru.stenfredd.movies.ui.menu.clickableWithMenu
|
import ru.stenfredd.sleepyowl.ui.menu.clickableWithMenu
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
import kotlin.math.floor
|
import kotlin.math.floor
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.series
|
package ru.stenfredd.sleepyowl.ui.series
|
||||||
|
|
||||||
import android.view.KeyEvent as AndroidKeyEvent
|
import android.view.KeyEvent as AndroidKeyEvent
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
@@ -40,15 +40,15 @@ import androidx.compose.ui.input.key.type
|
|||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.unit.em
|
import androidx.compose.ui.unit.em
|
||||||
import ru.stenfredd.movies.playback.api.SubtitleStyle
|
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
|
||||||
import ru.stenfredd.movies.ui.components.MinimalScrolling
|
import ru.stenfredd.sleepyowl.ui.components.MinimalScrolling
|
||||||
import ru.stenfredd.movies.ui.player.PanelChips
|
import ru.stenfredd.sleepyowl.ui.player.PanelChips
|
||||||
import ru.stenfredd.movies.ui.player.PanelList
|
import ru.stenfredd.sleepyowl.ui.player.PanelList
|
||||||
import ru.stenfredd.movies.ui.player.PanelSection
|
import ru.stenfredd.sleepyowl.ui.player.PanelSection
|
||||||
import ru.stenfredd.movies.ui.player.SubtitleChoices
|
import ru.stenfredd.sleepyowl.ui.player.SubtitleChoices
|
||||||
import ru.stenfredd.movies.ui.player.toChoices
|
import ru.stenfredd.sleepyowl.ui.player.toChoices
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "Аудио и субтитры" tray at the bottom of the series page: audio, subtitles and their look, applied at once and
|
* "Аудио и субтитры" tray at the bottom of the series page: audio, subtitles and their look, applied at once and
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.series
|
package ru.stenfredd.sleepyowl.ui.series
|
||||||
|
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
@@ -20,25 +20,25 @@ import kotlinx.coroutines.flow.stateIn
|
|||||||
import kotlinx.coroutines.flow.update
|
import kotlinx.coroutines.flow.update
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.core.data.ImageUrls
|
import ru.stenfredd.sleepyowl.core.data.ImageUrls
|
||||||
import ru.stenfredd.movies.core.data.LibraryRepository
|
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
|
||||||
import ru.stenfredd.movies.core.data.SessionCache
|
import ru.stenfredd.sleepyowl.core.data.SessionCache
|
||||||
import ru.stenfredd.movies.core.data.WatchRepository
|
import ru.stenfredd.sleepyowl.core.data.WatchRepository
|
||||||
import ru.stenfredd.movies.core.data.model.ItemDetails
|
import ru.stenfredd.sleepyowl.core.data.model.ItemDetails
|
||||||
import ru.stenfredd.movies.core.data.model.ItemKind
|
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSummary
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
|
||||||
import ru.stenfredd.movies.core.data.model.MediaInfo
|
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
|
||||||
import ru.stenfredd.movies.playback.api.SubtitleStyle
|
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackPreferences
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackPreferences
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.RemoteImageSpec
|
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
|
||||||
import ru.stenfredd.movies.ui.details.MediaLabels
|
import ru.stenfredd.sleepyowl.ui.details.MediaLabels
|
||||||
import ru.stenfredd.movies.ui.details.TrackChoices
|
import ru.stenfredd.sleepyowl.ui.details.TrackChoices
|
||||||
import ru.stenfredd.movies.ui.details.TrackOption
|
import ru.stenfredd.sleepyowl.ui.details.TrackOption
|
||||||
import ru.stenfredd.movies.ui.menu.WatchTarget
|
import ru.stenfredd.sleepyowl.ui.menu.WatchTarget
|
||||||
import ru.stenfredd.movies.ui.model.CardMapper
|
import ru.stenfredd.sleepyowl.ui.model.CardMapper
|
||||||
import ru.stenfredd.movies.ui.player.PlayerLabels
|
import ru.stenfredd.sleepyowl.ui.player.PlayerLabels
|
||||||
import ru.stenfredd.movies.ui.model.plural
|
import ru.stenfredd.sleepyowl.ui.model.plural
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.settings
|
package ru.stenfredd.sleepyowl.ui.settings
|
||||||
|
|
||||||
import android.view.KeyEvent as AndroidKeyEvent
|
import android.view.KeyEvent as AndroidKeyEvent
|
||||||
import androidx.compose.foundation.focusable
|
import androidx.compose.foundation.focusable
|
||||||
@@ -34,10 +34,10 @@ import androidx.compose.ui.unit.sp
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/** Text of a licence from `assets/licenses`; ↑/↓ scroll it (a page at a time with ←/→ or channel keys). */
|
/** Text of a licence from `assets/licenses`; ↑/↓ scroll it (a page at a time with ←/→ or channel keys). */
|
||||||
@Composable
|
@Composable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.settings
|
package ru.stenfredd.sleepyowl.ui.settings
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
|
|
||||||
@@ -8,7 +8,7 @@ data class Component(val name: String, val note: String?, val license: String, v
|
|||||||
|
|
||||||
/** "О приложении": the app itself first, then what it is built from (playback first: it carries the copyleft licences). */
|
/** "О приложении": the app itself first, then what it is built from (playback first: it carries the copyleft licences). */
|
||||||
internal object Licenses {
|
internal object Licenses {
|
||||||
val app = Component("Movies", "это приложение", "GPL-3.0", "GPL-3.0.txt")
|
val app = Component("SleepyOwl", "это приложение", "GPL-3.0", "GPL-3.0.txt")
|
||||||
|
|
||||||
val components = listOf(
|
val components = listOf(
|
||||||
Component("libVLC", "VideoLAN, второй движок воспроизведения", "LGPL-2.1", "LGPL-2.1.txt"),
|
Component("libVLC", "VideoLAN, второй движок воспроизведения", "LGPL-2.1", "LGPL-2.1.txt"),
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.settings
|
package ru.stenfredd.sleepyowl.ui.settings
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.border
|
import androidx.compose.foundation.border
|
||||||
@@ -54,31 +54,33 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
|
|||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import ru.stenfredd.movies.core.data.LanguageSettings
|
import ru.stenfredd.sleepyowl.core.data.LanguageSettings
|
||||||
import ru.stenfredd.movies.core.data.SubtitleMode
|
import ru.stenfredd.sleepyowl.core.data.SubtitleMode
|
||||||
import ru.stenfredd.movies.core.jellyfin.Account
|
import ru.stenfredd.sleepyowl.core.jellyfin.Account
|
||||||
import ru.stenfredd.movies.playback.api.SubtitleStyle
|
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
|
||||||
import ru.stenfredd.movies.playback.api.VideoPathSwitchable
|
import ru.stenfredd.sleepyowl.playback.api.VideoPathSwitchable
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackDefaults
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackDefaults
|
||||||
import ru.stenfredd.movies.playback.core.SkipMode
|
import ru.stenfredd.sleepyowl.playback.core.SkipMode
|
||||||
import ru.stenfredd.movies.ui.Screen
|
import ru.stenfredd.sleepyowl.ui.Screen
|
||||||
import ru.stenfredd.movies.ui.components.Avatar
|
import ru.stenfredd.sleepyowl.ui.components.Avatar
|
||||||
import ru.stenfredd.movies.ui.components.Chip
|
import ru.stenfredd.sleepyowl.ui.components.Chip
|
||||||
import ru.stenfredd.movies.ui.components.FocusStyle
|
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
|
||||||
import ru.stenfredd.movies.ui.components.MinimalScrolling
|
import ru.stenfredd.sleepyowl.ui.components.MinimalScrolling
|
||||||
import ru.stenfredd.movies.ui.components.SecondaryButton
|
import ru.stenfredd.sleepyowl.ui.components.OwlMark
|
||||||
import ru.stenfredd.movies.ui.components.focusCard
|
import ru.stenfredd.sleepyowl.ui.components.SecondaryButton
|
||||||
import ru.stenfredd.movies.ui.focus.Restore
|
import ru.stenfredd.sleepyowl.ui.components.Wordmark
|
||||||
import ru.stenfredd.movies.ui.focus.ScreenFocus
|
import ru.stenfredd.sleepyowl.ui.components.focusCard
|
||||||
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
|
import ru.stenfredd.sleepyowl.ui.focus.Restore
|
||||||
import ru.stenfredd.movies.ui.focus.remembered
|
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
|
||||||
import ru.stenfredd.movies.ui.player.PlayerLabels
|
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
|
||||||
import ru.stenfredd.movies.ui.player.QualityCaps
|
import ru.stenfredd.sleepyowl.ui.focus.remembered
|
||||||
import ru.stenfredd.movies.ui.player.SubtitleChoices
|
import ru.stenfredd.sleepyowl.ui.player.PlayerLabels
|
||||||
import ru.stenfredd.movies.ui.player.SubtitlePreview
|
import ru.stenfredd.sleepyowl.ui.player.QualityCaps
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.player.SubtitleChoices
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.player.SubtitlePreview
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
|
|
||||||
/** Sections on the left; the focused one is shown on the right. */
|
/** Sections on the left; the focused one is shown on the right. */
|
||||||
private enum class Section(val title: String, val dot: Color) {
|
private enum class Section(val title: String, val dot: Color) {
|
||||||
@@ -530,7 +532,10 @@ private fun InfoLine(key: String, value: String) {
|
|||||||
@Composable
|
@Composable
|
||||||
private fun AboutSection(vm: SettingsViewModel, focus: ScreenFocus, onOpen: (Screen) -> Unit) {
|
private fun AboutSection(vm: SettingsViewModel, focus: ScreenFocus, onOpen: (Screen) -> Unit) {
|
||||||
Column(verticalArrangement = Arrangement.spacedBy(5.dp)) {
|
Column(verticalArrangement = Arrangement.spacedBy(5.dp)) {
|
||||||
BasicText("Movies", style = AppType.Section.copy(fontSize = 18.sp, fontWeight = FontWeight.Bold))
|
Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
|
OwlMark()
|
||||||
|
Wordmark()
|
||||||
|
}
|
||||||
BasicText("Версия ${vm.about.version}", style = AppType.MonoMeta)
|
BasicText("Версия ${vm.about.version}", style = AppType.MonoMeta)
|
||||||
BasicText(vm.about.device, style = AppType.MonoMeta.copy(color = AppColors.TextDim))
|
BasicText(vm.about.device, style = AppType.MonoMeta.copy(color = AppColors.TextDim))
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.settings
|
package ru.stenfredd.sleepyowl.ui.settings
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@@ -21,17 +21,17 @@ import kotlinx.coroutines.flow.combine
|
|||||||
import kotlinx.coroutines.flow.stateIn
|
import kotlinx.coroutines.flow.stateIn
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.BuildConfig
|
import ru.stenfredd.sleepyowl.BuildConfig
|
||||||
import ru.stenfredd.movies.core.data.LanguageSettings
|
import ru.stenfredd.sleepyowl.core.data.LanguageSettings
|
||||||
import ru.stenfredd.movies.core.data.ServerInfo
|
import ru.stenfredd.sleepyowl.core.data.ServerInfo
|
||||||
import ru.stenfredd.movies.core.data.UserSettingsRepository
|
import ru.stenfredd.sleepyowl.core.data.UserSettingsRepository
|
||||||
import ru.stenfredd.movies.core.jellyfin.Account
|
import ru.stenfredd.sleepyowl.core.jellyfin.Account
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import ru.stenfredd.movies.playback.api.SubtitleStyle
|
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
|
||||||
import ru.stenfredd.movies.playback.core.DeviceCapabilitiesProbe
|
import ru.stenfredd.sleepyowl.playback.core.DeviceCapabilitiesProbe
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackDefaults
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackDefaults
|
||||||
import ru.stenfredd.movies.playback.core.PlaybackPreferences
|
import ru.stenfredd.sleepyowl.playback.core.PlaybackPreferences
|
||||||
import ru.stenfredd.movies.ui.TourEntry
|
import ru.stenfredd.sleepyowl.ui.TourEntry
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.shell
|
package ru.stenfredd.sleepyowl.ui.shell
|
||||||
|
|
||||||
import androidx.activity.compose.BackHandler
|
import androidx.activity.compose.BackHandler
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
@@ -43,7 +43,6 @@ import androidx.compose.ui.geometry.Size
|
|||||||
import androidx.compose.ui.graphics.Brush
|
import androidx.compose.ui.graphics.Brush
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
import androidx.compose.ui.graphics.lerp
|
import androidx.compose.ui.graphics.lerp
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.util.lerp
|
import androidx.compose.ui.util.lerp
|
||||||
import androidx.compose.ui.graphics.graphicsLayer
|
import androidx.compose.ui.graphics.graphicsLayer
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
@@ -51,12 +50,14 @@ import androidx.compose.ui.unit.Dp
|
|||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import androidx.compose.ui.zIndex
|
import androidx.compose.ui.zIndex
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import ru.stenfredd.movies.ui.components.AppIcon
|
import ru.stenfredd.sleepyowl.ui.components.AppIcon
|
||||||
import ru.stenfredd.movies.ui.components.Avatar
|
import ru.stenfredd.sleepyowl.ui.components.Avatar
|
||||||
import ru.stenfredd.movies.ui.components.Icon
|
import ru.stenfredd.sleepyowl.ui.components.Icon
|
||||||
import ru.stenfredd.movies.ui.theme.AppColors
|
import ru.stenfredd.sleepyowl.ui.components.OwlMark
|
||||||
import ru.stenfredd.movies.ui.theme.AppDimens
|
import ru.stenfredd.sleepyowl.ui.components.Wordmark
|
||||||
import ru.stenfredd.movies.ui.theme.AppType
|
import ru.stenfredd.sleepyowl.ui.theme.AppColors
|
||||||
|
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
|
||||||
|
import ru.stenfredd.sleepyowl.ui.theme.AppType
|
||||||
import java.time.LocalTime
|
import java.time.LocalTime
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -161,7 +162,7 @@ private fun Rail(
|
|||||||
.padding(horizontal = 9.dp, vertical = 28.dp),
|
.padding(horizontal = 9.dp, vertical = 28.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(5.dp),
|
verticalArrangement = Arrangement.spacedBy(5.dp),
|
||||||
) {
|
) {
|
||||||
Logo(progress, Modifier.padding(start = 13.dp, bottom = 20.dp))
|
Logo(progress, Modifier.padding(start = 1.dp, bottom = 16.dp))
|
||||||
@Composable
|
@Composable
|
||||||
fun item(tab: Tab) = RailItem(
|
fun item(tab: Tab) = RailItem(
|
||||||
label = tab.label,
|
label = tab.label,
|
||||||
@@ -198,25 +199,12 @@ private fun Rail(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Neutral placeholder logo until the app has a name: a glowing dot and the working title. */
|
/** The owl, centred over the items' icons; the wordmark shows with the open rail. */
|
||||||
@Composable
|
@Composable
|
||||||
private fun Logo(progress: State<Float>, modifier: Modifier = Modifier) {
|
private fun Logo(progress: State<Float>, modifier: Modifier = Modifier) {
|
||||||
Row(modifier.height(32.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(10.dp)) {
|
Row(modifier, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||||
Box(
|
OwlMark()
|
||||||
Modifier
|
Wordmark(Modifier.graphicsLayer { alpha = progress.value })
|
||||||
.size(11.dp)
|
|
||||||
.drawBehind {
|
|
||||||
drawCircle(AppColors.AccentStrong.copy(alpha = 0.35f), radius = size.minDimension)
|
|
||||||
drawCircle(AppColors.AccentStrong)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
BasicText(
|
|
||||||
"movies",
|
|
||||||
Modifier.graphicsLayer { alpha = progress.value },
|
|
||||||
style = AppType.Rail.copy(fontSize = AppType.Section.fontSize, fontWeight = FontWeight.Bold),
|
|
||||||
maxLines = 1,
|
|
||||||
softWrap = false,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.theme
|
package ru.stenfredd.sleepyowl.ui.theme
|
||||||
|
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.tv.material3.MaterialTheme
|
import androidx.tv.material3.MaterialTheme
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.ui.theme
|
package ru.stenfredd.sleepyowl.ui.theme
|
||||||
|
|
||||||
import androidx.compose.runtime.Immutable
|
import androidx.compose.runtime.Immutable
|
||||||
import androidx.compose.ui.graphics.Brush
|
import androidx.compose.ui.graphics.Brush
|
||||||
@@ -10,7 +10,7 @@ import androidx.compose.ui.text.font.FontWeight
|
|||||||
import androidx.compose.ui.text.style.LineHeightStyle
|
import androidx.compose.ui.text.style.LineHeightStyle
|
||||||
import androidx.compose.ui.unit.em
|
import androidx.compose.ui.unit.em
|
||||||
import androidx.compose.ui.unit.sp
|
import androidx.compose.ui.unit.sp
|
||||||
import ru.stenfredd.movies.R
|
import ru.stenfredd.sleepyowl.R
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Design tokens from `design/…/Jellyfin TV.dc.html`. The mockup is drawn at 1920×1080 px,
|
* Design tokens from `design/…/Jellyfin TV.dc.html`. The mockup is drawn at 1920×1080 px,
|
||||||
BIN
app/src/main/res/drawable-xhdpi/banner.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 96 KiB |
BIN
app/src/main/res/drawable-xhdpi/logo_owl.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/logo_owl.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
app/src/main/res/drawable-xhdpi/logo_wordmark.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/logo_wordmark.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_launcher_owl.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_launcher_owl.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<!-- Нейтральный баннер Android TV (320×180), пока нет названия и логотипа: фиолетовый круг с «play». -->
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="320dp"
|
|
||||||
android:height="180dp"
|
|
||||||
android:viewportWidth="320"
|
|
||||||
android:viewportHeight="180">
|
|
||||||
<path android:fillColor="#0A0B10" android:pathData="M0,0h320v180h-320z" />
|
|
||||||
<path android:fillColor="#408F6BFF" android:pathData="M160,90m-62,0a62,62 0,1 1,124 0a62,62 0,1 1,-124 0" />
|
|
||||||
<path android:fillColor="#8F6BFF" android:pathData="M160,90m-40,0a40,40 0,1 1,80 0a40,40 0,1 1,-80 0" />
|
|
||||||
<path android:fillColor="#FFFFFF" android:pathData="M148,68 L148,112 L184,90 Z" />
|
|
||||||
</vector>
|
|
||||||
7
app/src/main/res/mipmap-anydpi/ic_launcher.xml
Normal file
7
app/src/main/res/mipmap-anydpi/ic_launcher.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Иконка приложения (настройки ТВ, список приложений): сова из логотипа на его тёмно-синем фоне.
|
||||||
|
Картинки делает tools/logo/make_assets.py. -->
|
||||||
|
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<background android:drawable="@color/ic_launcher_background" />
|
||||||
|
<foreground android:drawable="@drawable/ic_launcher_owl" />
|
||||||
|
</adaptive-icon>
|
||||||
@@ -1,4 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<color name="background">#0A0B10</color>
|
<color name="background">#0A0B10</color>
|
||||||
|
<!-- Фон логотипа: под совой в иконке приложения. -->
|
||||||
|
<color name="ic_launcher_background">#050927</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<!-- Рабочее название, пока нет настоящего. Меняется здесь и в логотипе (drawable/banner.xml, Shell.Logo). -->
|
<!-- Название приложения. Логотип — design/logo/sleepyowl.png, картинки из него делает tools/logo/make_assets.py. -->
|
||||||
<string name="app_name">Movies</string>
|
<string name="app_name">SleepyOwl</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<!-- Фон приложения — фон окна: без белой вспышки до первого кадра Compose, и экраны не рисуют свой фон.
|
<!-- Фон приложения — фон окна: без белой вспышки до первого кадра Compose, и экраны не рисуют свой фон.
|
||||||
Сплошной цвет: GPU заливает его почти бесплатно. Сетка точек из макета стоила ~5 мс каждого кадра
|
Сплошной цвет: GPU заливает его почти бесплатно. Сетка точек из макета стоила ~5 мс каждого кадра
|
||||||
на тестовом ТВ (он перерисовывает весь экран на каждом кадре) — убрана. -->
|
на тестовом ТВ (он перерисовывает весь экран на каждом кадре) — убрана. -->
|
||||||
<style name="Theme.Movies" parent="@android:style/Theme.DeviceDefault.NoActionBar">
|
<style name="Theme.SleepyOwl" parent="@android:style/Theme.DeviceDefault.NoActionBar">
|
||||||
<item name="android:windowBackground">@color/background</item>
|
<item name="android:windowBackground">@color/background</item>
|
||||||
<item name="android:colorBackground">@color/background</item>
|
<item name="android:colorBackground">@color/background</item>
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ plugins {
|
|||||||
// Generates the app's baseline profile on a connected device (the test TV, logged in):
|
// Generates the app's baseline profile on a connected device (the test TV, logged in):
|
||||||
// ./gradlew :app:generateReleaseBaselineProfile
|
// ./gradlew :app:generateReleaseBaselineProfile
|
||||||
android {
|
android {
|
||||||
namespace = "ru.stenfredd.movies.baselineprofile"
|
namespace = "ru.stenfredd.sleepyowl.baselineprofile"
|
||||||
compileSdk = 37
|
compileSdk = 37
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdk = 28
|
minSdk = 28
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.baselineprofile
|
package ru.stenfredd.sleepyowl.baselineprofile
|
||||||
|
|
||||||
import androidx.benchmark.macro.junit4.BaselineProfileRule
|
import androidx.benchmark.macro.junit4.BaselineProfileRule
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
@@ -147,7 +147,7 @@ class BaselineProfileGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val PACKAGE = "ru.stenfredd.movies"
|
const val PACKAGE = "ru.stenfredd.sleepyowl"
|
||||||
const val ROWS = 6
|
const val ROWS = 6
|
||||||
const val LIBRARY_ROWS = 14
|
const val LIBRARY_ROWS = 14
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "ru.stenfredd.movies.core.data"
|
namespace = "ru.stenfredd.sleepyowl.core.data"
|
||||||
compileSdk = 37
|
compileSdk = 37
|
||||||
defaultConfig { minSdk = 26 }
|
defaultConfig { minSdk = 26 }
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.data
|
package ru.stenfredd.sleepyowl.core.data
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
@@ -18,11 +18,11 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import ru.stenfredd.movies.core.data.model.ItemQuery
|
import ru.stenfredd.sleepyowl.core.data.model.ItemQuery
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSummary
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
|
||||||
import ru.stenfredd.movies.core.data.model.LibraryView
|
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
|
||||||
import ru.stenfredd.movies.core.data.model.itemKinds
|
import ru.stenfredd.sleepyowl.core.data.model.itemKinds
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package ru.stenfredd.movies.core.data
|
package ru.stenfredd.sleepyowl.core.data
|
||||||
|
|
||||||
import org.jellyfin.sdk.api.client.extensions.imageApi
|
import org.jellyfin.sdk.api.client.extensions.imageApi
|
||||||
import org.jellyfin.sdk.model.api.ImageType
|
import org.jellyfin.sdk.model.api.ImageType
|
||||||
import ru.stenfredd.movies.core.data.model.ImageKind
|
import ru.stenfredd.sleepyowl.core.data.model.ImageKind
|
||||||
import ru.stenfredd.movies.core.data.model.ImageRef
|
import ru.stenfredd.sleepyowl.core.data.model.ImageRef
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.data
|
package ru.stenfredd.sleepyowl.core.data
|
||||||
|
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
@@ -11,19 +11,19 @@ import org.jellyfin.sdk.model.api.BaseItemKind
|
|||||||
import org.jellyfin.sdk.model.api.ItemFilter
|
import org.jellyfin.sdk.model.api.ItemFilter
|
||||||
import org.jellyfin.sdk.model.api.ItemSortBy
|
import org.jellyfin.sdk.model.api.ItemSortBy
|
||||||
import org.jellyfin.sdk.model.api.SortOrder
|
import org.jellyfin.sdk.model.api.SortOrder
|
||||||
import ru.stenfredd.movies.core.data.SessionCache.Kind
|
import ru.stenfredd.sleepyowl.core.data.SessionCache.Kind
|
||||||
import ru.stenfredd.movies.core.data.model.ItemDetails
|
import ru.stenfredd.sleepyowl.core.data.model.ItemDetails
|
||||||
import ru.stenfredd.movies.core.data.model.ItemKind
|
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
|
||||||
import ru.stenfredd.movies.core.data.model.ItemQuery
|
import ru.stenfredd.sleepyowl.core.data.model.ItemQuery
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSort
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSort
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSummary
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
|
||||||
import ru.stenfredd.movies.core.data.model.LibraryType
|
import ru.stenfredd.sleepyowl.core.data.model.LibraryType
|
||||||
import ru.stenfredd.movies.core.data.model.LibraryView
|
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
|
||||||
import ru.stenfredd.movies.core.data.model.MediaSegment
|
import ru.stenfredd.sleepyowl.core.data.model.MediaSegment
|
||||||
import ru.stenfredd.movies.core.data.model.Page
|
import ru.stenfredd.sleepyowl.core.data.model.Page
|
||||||
import ru.stenfredd.movies.core.data.model.Person
|
import ru.stenfredd.sleepyowl.core.data.model.Person
|
||||||
import ru.stenfredd.movies.core.data.model.itemKinds
|
import ru.stenfredd.sleepyowl.core.data.model.itemKinds
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.data
|
package ru.stenfredd.sleepyowl.core.data
|
||||||
|
|
||||||
import org.jellyfin.sdk.model.api.AudioSpatialFormat
|
import org.jellyfin.sdk.model.api.AudioSpatialFormat
|
||||||
import org.jellyfin.sdk.model.api.BaseItemDto
|
import org.jellyfin.sdk.model.api.BaseItemDto
|
||||||
@@ -13,24 +13,24 @@ import org.jellyfin.sdk.model.api.MediaSourceInfo
|
|||||||
import org.jellyfin.sdk.model.api.MediaStream
|
import org.jellyfin.sdk.model.api.MediaStream
|
||||||
import org.jellyfin.sdk.model.api.MediaStreamType
|
import org.jellyfin.sdk.model.api.MediaStreamType
|
||||||
import org.jellyfin.sdk.model.api.VideoRangeType
|
import org.jellyfin.sdk.model.api.VideoRangeType
|
||||||
import ru.stenfredd.movies.core.data.model.AudioTrack
|
import ru.stenfredd.sleepyowl.core.data.model.AudioTrack
|
||||||
import ru.stenfredd.movies.core.data.model.Chapter
|
import ru.stenfredd.sleepyowl.core.data.model.Chapter
|
||||||
import ru.stenfredd.movies.core.data.model.ImageKind
|
import ru.stenfredd.sleepyowl.core.data.model.ImageKind
|
||||||
import ru.stenfredd.movies.core.data.model.ImageRef
|
import ru.stenfredd.sleepyowl.core.data.model.ImageRef
|
||||||
import ru.stenfredd.movies.core.data.model.ItemDetails
|
import ru.stenfredd.sleepyowl.core.data.model.ItemDetails
|
||||||
import ru.stenfredd.movies.core.data.model.ItemKind
|
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSummary
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
|
||||||
import ru.stenfredd.movies.core.data.model.LibraryType
|
import ru.stenfredd.sleepyowl.core.data.model.LibraryType
|
||||||
import ru.stenfredd.movies.core.data.model.LibraryView
|
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
|
||||||
import ru.stenfredd.movies.core.data.model.MediaInfo
|
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
|
||||||
import ru.stenfredd.movies.core.data.model.MediaSegment
|
import ru.stenfredd.sleepyowl.core.data.model.MediaSegment
|
||||||
import ru.stenfredd.movies.core.data.model.Person
|
import ru.stenfredd.sleepyowl.core.data.model.Person
|
||||||
import ru.stenfredd.movies.core.data.model.PersonKind
|
import ru.stenfredd.sleepyowl.core.data.model.PersonKind
|
||||||
import ru.stenfredd.movies.core.data.model.SegmentKind
|
import ru.stenfredd.sleepyowl.core.data.model.SegmentKind
|
||||||
import ru.stenfredd.movies.core.data.model.SubtitleTrack
|
import ru.stenfredd.sleepyowl.core.data.model.SubtitleTrack
|
||||||
import ru.stenfredd.movies.core.data.model.UserState
|
import ru.stenfredd.sleepyowl.core.data.model.UserState
|
||||||
import ru.stenfredd.movies.core.data.model.VideoRange
|
import ru.stenfredd.sleepyowl.core.data.model.VideoRange
|
||||||
import ru.stenfredd.movies.core.data.model.VideoTrack
|
import ru.stenfredd.sleepyowl.core.data.model.VideoTrack
|
||||||
import java.time.LocalDateTime
|
import java.time.LocalDateTime
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.data
|
package ru.stenfredd.sleepyowl.core.data
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.datastore.preferences.core.edit
|
import androidx.datastore.preferences.core.edit
|
||||||
@@ -8,7 +8,7 @@ import dagger.hilt.android.qualifiers.ApplicationContext
|
|||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.map
|
import kotlinx.coroutines.flow.map
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.data
|
package ru.stenfredd.sleepyowl.core.data
|
||||||
|
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import kotlinx.coroutines.CancellationException
|
import kotlinx.coroutines.CancellationException
|
||||||
@@ -15,7 +15,7 @@ import kotlinx.coroutines.flow.distinctUntilChangedBy
|
|||||||
import kotlinx.coroutines.flow.drop
|
import kotlinx.coroutines.flow.drop
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package ru.stenfredd.movies.core.data
|
package ru.stenfredd.sleepyowl.core.data
|
||||||
|
|
||||||
import org.jellyfin.sdk.api.client.extensions.systemApi
|
import org.jellyfin.sdk.api.client.extensions.systemApi
|
||||||
import org.jellyfin.sdk.api.client.extensions.userApi
|
import org.jellyfin.sdk.api.client.extensions.userApi
|
||||||
import org.jellyfin.sdk.model.api.SubtitlePlaybackMode
|
import org.jellyfin.sdk.model.api.SubtitlePlaybackMode
|
||||||
import org.jellyfin.sdk.model.api.UserConfiguration
|
import org.jellyfin.sdk.model.api.UserConfiguration
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.data
|
package ru.stenfredd.sleepyowl.core.data
|
||||||
|
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.coroutineScope
|
import kotlinx.coroutines.coroutineScope
|
||||||
@@ -6,15 +6,15 @@ import org.jellyfin.sdk.api.client.extensions.libraryApi
|
|||||||
import org.jellyfin.sdk.api.client.extensions.showApi
|
import org.jellyfin.sdk.api.client.extensions.showApi
|
||||||
import org.jellyfin.sdk.api.client.extensions.userDataApi
|
import org.jellyfin.sdk.api.client.extensions.userDataApi
|
||||||
import org.jellyfin.sdk.model.api.MediaType
|
import org.jellyfin.sdk.model.api.MediaType
|
||||||
import ru.stenfredd.movies.core.data.SessionCache.Kind
|
import ru.stenfredd.sleepyowl.core.data.SessionCache.Kind
|
||||||
import ru.stenfredd.movies.core.data.model.ItemKind
|
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
|
||||||
import ru.stenfredd.movies.core.data.model.ItemQuery
|
import ru.stenfredd.sleepyowl.core.data.model.ItemQuery
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSort
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSort
|
||||||
import ru.stenfredd.movies.core.data.model.ItemSummary
|
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
|
||||||
import ru.stenfredd.movies.core.data.model.LibraryView
|
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
|
||||||
import ru.stenfredd.movies.core.data.model.Page
|
import ru.stenfredd.sleepyowl.core.data.model.Page
|
||||||
import ru.stenfredd.movies.core.data.model.itemKinds
|
import ru.stenfredd.sleepyowl.core.data.model.itemKinds
|
||||||
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
|
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
@file:UseSerializers(UUIDSerializer::class)
|
@file:UseSerializers(UUIDSerializer::class)
|
||||||
|
|
||||||
package ru.stenfredd.movies.core.data.model
|
package ru.stenfredd.sleepyowl.core.data.model
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@@ -5,7 +5,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "ru.stenfredd.movies.core.jellyfin"
|
namespace = "ru.stenfredd.sleepyowl.core.jellyfin"
|
||||||
compileSdk = 37
|
compileSdk = 37
|
||||||
defaultConfig { minSdk = 26 }
|
defaultConfig { minSdk = 26 }
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.jellyfin
|
package ru.stenfredd.sleepyowl.core.jellyfin
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.datastore.preferences.core.Preferences
|
import androidx.datastore.preferences.core.Preferences
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.jellyfin
|
package ru.stenfredd.sleepyowl.core.jellyfin
|
||||||
|
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.jellyfin
|
package ru.stenfredd.sleepyowl.core.jellyfin
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@@ -253,7 +253,7 @@ class JellyfinSession @Inject constructor(
|
|||||||
private fun deviceInfo(id: String) = DeviceInfo(id = id, name = "${Build.MANUFACTURER} ${Build.MODEL}")
|
private fun deviceInfo(id: String) = DeviceInfo(id = id, name = "${Build.MANUFACTURER} ${Build.MODEL}")
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val CLIENT_NAME = "Movies"
|
const val CLIENT_NAME = "SleepyOwl"
|
||||||
const val CLIENT_VERSION = "0.1.0"
|
const val CLIENT_VERSION = "0.1.0"
|
||||||
const val LOCAL_RECHECK_MS = 10 * 60_000L
|
const val LOCAL_RECHECK_MS = 10 * 60_000L
|
||||||
const val REVOKE_TIMEOUT_MS = 3_000L
|
const val REVOKE_TIMEOUT_MS = 3_000L
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.jellyfin
|
package ru.stenfredd.sleepyowl.core.jellyfin
|
||||||
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.jellyfin
|
package ru.stenfredd.sleepyowl.core.jellyfin
|
||||||
|
|
||||||
import android.os.SystemClock
|
import android.os.SystemClock
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.core.jellyfin
|
package ru.stenfredd.sleepyowl.core.jellyfin
|
||||||
|
|
||||||
import okhttp3.HttpUrl
|
import okhttp3.HttpUrl
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
BIN
design/logo/sleepyowl.png
Normal file
BIN
design/logo/sleepyowl.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
@@ -3,7 +3,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "ru.stenfredd.movies.playback.api"
|
namespace = "ru.stenfredd.sleepyowl.playback.api"
|
||||||
compileSdk = 37
|
compileSdk = 37
|
||||||
defaultConfig { minSdk = 26 }
|
defaultConfig { minSdk = 26 }
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
package ru.stenfredd.movies.playback.api
|
package ru.stenfredd.sleepyowl.playback.api
|
||||||
|
|
||||||
import android.media.AudioFormat
|
import android.media.AudioFormat
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user