Rename to SleepyOwl, add logo

This commit is contained in:
2026-10-25 00:53:19 +03:00
parent 33643707f1
commit f63b09a9d3
130 changed files with 8010 additions and 7797 deletions

View File

@@ -7,11 +7,11 @@ plugins {
}
android {
namespace = "ru.stenfredd.movies"
namespace = "ru.stenfredd.sleepyowl"
compileSdk = 37
defaultConfig {
applicationId = "ru.stenfredd.movies"
applicationId = "ru.stenfredd.sleepyowl"
minSdk = 26
targetSdk = 36
versionCode = 1

View File

@@ -12,15 +12,15 @@
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
<application
android:name=".MoviesApp"
android:name=".SleepyOwlApp"
android:allowBackup="false"
android:banner="@drawable/banner"
android:icon="@drawable/banner"
android:icon="@mipmap/ic_launcher"
android:largeHeap="true"
android:label="@string/app_name"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/Theme.Movies">
android:theme="@style/Theme.SleepyOwl">
<activity
android:name=".MainActivity"

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies
package ru.stenfredd.sleepyowl
import android.content.Context
import android.content.Intent
@@ -15,14 +15,14 @@ import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import org.json.JSONArray
import org.json.JSONObject
import ru.stenfredd.movies.core.data.ImageUrls
import ru.stenfredd.movies.core.data.SessionCache
import ru.stenfredd.movies.core.data.WatchRepository
import ru.stenfredd.movies.core.data.model.ItemKind
import ru.stenfredd.movies.core.data.model.ItemSummary
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
import ru.stenfredd.movies.ui.model.landscape
import ru.stenfredd.movies.ui.model.remaining
import ru.stenfredd.sleepyowl.core.data.ImageUrls
import ru.stenfredd.sleepyowl.core.data.SessionCache
import ru.stenfredd.sleepyowl.core.data.WatchRepository
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
import ru.stenfredd.sleepyowl.ui.model.landscape
import ru.stenfredd.sleepyowl.ui.model.remaining
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies
package ru.stenfredd.sleepyowl
import android.content.Intent
import android.os.Bundle
@@ -30,34 +30,34 @@ import androidx.navigation3.ui.NavDisplay
import dagger.hilt.android.AndroidEntryPoint
import androidx.compose.runtime.produceState
import kotlinx.coroutines.channels.Channel
import ru.stenfredd.movies.core.data.LibraryRepository
import ru.stenfredd.movies.core.data.model.LibraryType
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
import ru.stenfredd.movies.playback.api.EngineId
import ru.stenfredd.movies.playback.api.StreamSelection
import ru.stenfredd.movies.ui.ItemsScreen
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.TourScreen
import ru.stenfredd.movies.ui.details.DetailsScreen
import ru.stenfredd.movies.ui.home.HomeScreen
import ru.stenfredd.movies.ui.favorites.FavoritesScreen
import ru.stenfredd.movies.ui.library.LibraryMemory
import ru.stenfredd.movies.ui.library.LibraryScreen
import ru.stenfredd.movies.ui.person.PersonScreen
import ru.stenfredd.movies.ui.search.SearchScreen
import ru.stenfredd.movies.ui.settings.LicenseScreen
import ru.stenfredd.movies.ui.settings.SettingsScreen
import ru.stenfredd.movies.ui.player.PlayerScreen
import ru.stenfredd.movies.ui.series.SeriesScreen
import ru.stenfredd.movies.ui.login.LoginScreen
import ru.stenfredd.movies.ui.menu.WatchMenuHost
import ru.stenfredd.movies.ui.components.AppIcon
import ru.stenfredd.movies.ui.shell.RailLibrary
import ru.stenfredd.movies.ui.shell.Shell
import ru.stenfredd.movies.ui.shell.Tab
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppTheme
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
import ru.stenfredd.sleepyowl.core.data.model.LibraryType
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
import ru.stenfredd.sleepyowl.playback.api.EngineId
import ru.stenfredd.sleepyowl.playback.api.StreamSelection
import ru.stenfredd.sleepyowl.ui.ItemsScreen
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.TourScreen
import ru.stenfredd.sleepyowl.ui.details.DetailsScreen
import ru.stenfredd.sleepyowl.ui.home.HomeScreen
import ru.stenfredd.sleepyowl.ui.favorites.FavoritesScreen
import ru.stenfredd.sleepyowl.ui.library.LibraryMemory
import ru.stenfredd.sleepyowl.ui.library.LibraryScreen
import ru.stenfredd.sleepyowl.ui.person.PersonScreen
import ru.stenfredd.sleepyowl.ui.search.SearchScreen
import ru.stenfredd.sleepyowl.ui.settings.LicenseScreen
import ru.stenfredd.sleepyowl.ui.settings.SettingsScreen
import ru.stenfredd.sleepyowl.ui.player.PlayerScreen
import ru.stenfredd.sleepyowl.ui.series.SeriesScreen
import ru.stenfredd.sleepyowl.ui.login.LoginScreen
import ru.stenfredd.sleepyowl.ui.menu.WatchMenuHost
import ru.stenfredd.sleepyowl.ui.components.AppIcon
import ru.stenfredd.sleepyowl.ui.shell.RailLibrary
import ru.stenfredd.sleepyowl.ui.shell.Shell
import ru.stenfredd.sleepyowl.ui.shell.Tab
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppTheme
import ru.stenfredd.sleepyowl.ui.theme.AppType
import java.util.UUID
import javax.inject.Inject
@@ -230,7 +230,7 @@ class MainActivity : ComponentActivity() {
/**
* 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),
* 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).

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies
package ru.stenfredd.sleepyowl
import android.app.Application
import coil3.ImageLoader
@@ -21,7 +21,7 @@ import timber.log.Timber
import javax.inject.Inject
@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. */
@Inject lateinit var httpClient: OkHttpClient
@Inject lateinit var launcherFeed: Lazy<LauncherFeed>

View File

@@ -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.Box
@@ -39,11 +39,11 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import org.jellyfin.sdk.model.api.BaseItemDto
import org.jellyfin.sdk.model.api.BaseItemKind
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
import ru.stenfredd.movies.ui.components.TextInput
import ru.stenfredd.movies.ui.components.rememberTextInputState
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
import ru.stenfredd.sleepyowl.ui.components.TextInput
import ru.stenfredd.sleepyowl.ui.components.rememberTextInputState
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppType
import javax.inject.Inject
@HiltViewModel

View File

@@ -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.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.ImageType
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 javax.inject.Inject

View File

@@ -1,7 +1,7 @@
package ru.stenfredd.movies.ui
package ru.stenfredd.sleepyowl.ui
import ru.stenfredd.movies.playback.api.EngineId
import ru.stenfredd.movies.playback.api.StreamSelection
import ru.stenfredd.sleepyowl.playback.api.EngineId
import ru.stenfredd.sleepyowl.playback.api.StreamSelection
import java.util.UUID
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.
* [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. */
data class Items(val parentId: UUID, val title: String) : Screen

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui
package ru.stenfredd.sleepyowl.ui
import android.content.Context
import android.view.KeyEvent as AndroidKeyEvent
@@ -34,9 +34,9 @@ import androidx.tv.material3.Text
import java.util.UUID
import kotlinx.coroutines.delay
import org.json.JSONArray
import ru.stenfredd.movies.playback.api.StreamSelection
import ru.stenfredd.movies.ui.player.PlayerScreen
import ru.stenfredd.movies.ui.player.TourInfo
import ru.stenfredd.sleepyowl.playback.api.StreamSelection
import ru.stenfredd.sleepyowl.ui.player.PlayerScreen
import ru.stenfredd.sleepyowl.ui.player.TourInfo
import timber.log.Timber
/**

View File

@@ -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.size

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.components
package ru.stenfredd.sleepyowl.ui.components
import android.graphics.Bitmap
import android.graphics.BitmapShader

View File

@@ -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),
)
}

View File

@@ -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.border
@@ -27,8 +27,8 @@ import androidx.compose.ui.unit.sp
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.foundation.layout.widthIn
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppType
private val PrimaryFocus = FocusStyle(
scale = 1.05f,

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.components
package ru.stenfredd.sleepyowl.ui.components
import android.graphics.Bitmap
import android.graphics.BitmapShader

View File

@@ -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.border
@@ -27,11 +27,11 @@ import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import ru.stenfredd.movies.ui.menu.WatchTarget
import ru.stenfredd.movies.ui.menu.clickableWithMenu
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.menu.WatchTarget
import ru.stenfredd.sleepyowl.ui.menu.clickableWithMenu
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
import ru.stenfredd.sleepyowl.ui.theme.AppType
/** What a poster card shows. Built by view models from server data; composables never see SDK DTOs. */
@Immutable

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.components
package ru.stenfredd.sleepyowl.ui.components
import android.graphics.DashPathEffect
import android.graphics.Paint

View File

@@ -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.tween
@@ -26,7 +26,7 @@ import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
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). */
@Immutable

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.components
package ru.stenfredd.sleepyowl.ui.components
import android.graphics.Bitmap
import android.graphics.BlurMaskFilter
@@ -9,7 +9,7 @@ import android.util.LruCache
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.toArgb
import java.nio.ByteBuffer
import kotlin.math.roundToInt
/**
@@ -46,20 +46,63 @@ object GlowCache {
val margin = key.layers.maxOf { it.blurPx + it.spreadPx }
val w = ((key.w + 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)
val canvas = Canvas(bitmap)
// Each layer's coverage is drawn at full strength (255 levels) and the layers are composited in float:
// 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)
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) {
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.
val radius = ((layer.blurPx / 2 - 0.5f) / 0.57735f).coerceAtLeast(0.5f)
paint.maskFilter = BlurMaskFilter(radius, BlurMaskFilter.Blur.NORMAL)
paint.color = layer.color.toArgb()
val s = layer.spreadPx
val rect = RectF(margin - s, margin - s, margin + key.w + s, margin + key.h + s)
val corner = key.corner + s
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)
}
/** 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
}
}

View File

@@ -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.LazyGridScope

View File

@@ -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.runtime.Composable

View File

@@ -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.layout.Box
@@ -27,7 +27,7 @@ import coil3.request.ImageRequest
import coil3.request.transformations
import kotlinx.coroutines.Dispatchers
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. */
@Immutable

View File

@@ -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.tween

View File

@@ -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.Column
@@ -14,8 +14,8 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.focusRestorer
import androidx.compose.ui.unit.dp
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
import ru.stenfredd.sleepyowl.ui.theme.AppType
/** "Недавно добавлено 12" */
@Composable

View File

@@ -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.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.VisualTransformation
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

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.details
package ru.stenfredd.sleepyowl.ui.details
import android.graphics.Bitmap
import android.graphics.Canvas
@@ -11,7 +11,7 @@ import androidx.compose.ui.graphics.toArgb
import coil3.size.Dimension
import coil3.size.Size
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

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.details
package ru.stenfredd.sleepyowl.ui.details
import android.graphics.RectF
import androidx.compose.foundation.background
@@ -52,32 +52,32 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
import coil3.compose.AsyncImage
import coil3.request.ImageRequest
import coil3.request.transformations
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.AnchoredScrolling
import ru.stenfredd.movies.ui.components.AppIcon
import ru.stenfredd.movies.ui.components.Avatar
import ru.stenfredd.movies.ui.components.Chip
import ru.stenfredd.movies.ui.components.CircleButton
import ru.stenfredd.movies.ui.components.ContentRow
import ru.stenfredd.movies.ui.components.DefaultScrolling
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.FormatBadge
import ru.stenfredd.movies.ui.components.PosterCard
import ru.stenfredd.movies.ui.components.PrimaryButton
import ru.stenfredd.movies.ui.components.RemoteImage
import ru.stenfredd.movies.ui.components.SecondaryButton
import ru.stenfredd.movies.ui.components.SectionTitle
import ru.stenfredd.movies.ui.components.anchorViewport
import ru.stenfredd.movies.ui.components.anchoredRow
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.focus.Restore
import ru.stenfredd.movies.ui.focus.ScreenFocus
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
import ru.stenfredd.movies.ui.focus.remembered
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.movies.ui.details.DetailsLayout as L
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
import ru.stenfredd.sleepyowl.ui.components.AppIcon
import ru.stenfredd.sleepyowl.ui.components.Avatar
import ru.stenfredd.sleepyowl.ui.components.Chip
import ru.stenfredd.sleepyowl.ui.components.CircleButton
import ru.stenfredd.sleepyowl.ui.components.ContentRow
import ru.stenfredd.sleepyowl.ui.components.DefaultScrolling
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.FormatBadge
import ru.stenfredd.sleepyowl.ui.components.PosterCard
import ru.stenfredd.sleepyowl.ui.components.PrimaryButton
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
import ru.stenfredd.sleepyowl.ui.components.SecondaryButton
import ru.stenfredd.sleepyowl.ui.components.SectionTitle
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.focus.Restore
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.remembered
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
import ru.stenfredd.sleepyowl.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.details.DetailsLayout as L
/** Movie (or episode) page, the mockup's "Фильм" screen. Full screen, without the side rail. */
@Composable

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.details
package ru.stenfredd.sleepyowl.ui.details
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
@@ -17,20 +17,20 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.stenfredd.movies.core.data.ImageUrls
import ru.stenfredd.movies.core.data.LibraryRepository
import ru.stenfredd.movies.core.data.SessionCache
import ru.stenfredd.movies.core.data.WatchRepository
import ru.stenfredd.movies.core.data.model.ItemDetails
import ru.stenfredd.movies.core.data.model.ItemKind
import ru.stenfredd.movies.core.data.model.MediaInfo
import ru.stenfredd.movies.core.data.model.PersonKind
import ru.stenfredd.movies.playback.api.StreamSelection
import ru.stenfredd.movies.playback.core.PlaybackPreferences
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.PosterModel
import ru.stenfredd.movies.ui.components.RemoteImageSpec
import ru.stenfredd.movies.ui.model.CardMapper
import ru.stenfredd.sleepyowl.core.data.ImageUrls
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
import ru.stenfredd.sleepyowl.core.data.SessionCache
import ru.stenfredd.sleepyowl.core.data.WatchRepository
import ru.stenfredd.sleepyowl.core.data.model.ItemDetails
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
import ru.stenfredd.sleepyowl.core.data.model.PersonKind
import ru.stenfredd.sleepyowl.playback.api.StreamSelection
import ru.stenfredd.sleepyowl.playback.core.PlaybackPreferences
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.PosterModel
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
import ru.stenfredd.sleepyowl.ui.model.CardMapper
import timber.log.Timber
import java.util.Locale
import java.util.UUID

View File

@@ -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.movies.core.data.model.MediaInfo
import ru.stenfredd.movies.core.data.model.SubtitleTrack
import ru.stenfredd.movies.core.data.model.VideoRange
import ru.stenfredd.sleepyowl.core.data.model.AudioTrack
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
import ru.stenfredd.sleepyowl.core.data.model.SubtitleTrack
import ru.stenfredd.sleepyowl.core.data.model.VideoRange
import java.util.Locale
/** How the item page names languages, codecs and formats: "Русский", "TrueHD Atmos 7.1", "HEVC 2160p HDR10 · 62.4 ГБ". */

View File

@@ -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.movies.playback.core.PlaybackPreferences
import ru.stenfredd.movies.playback.core.TrackPick
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
import ru.stenfredd.sleepyowl.playback.core.PlaybackPreferences
import ru.stenfredd.sleepyowl.playback.core.TrackPick
import java.util.UUID
/** Audio and subtitle choices of a file as the movie page and the series tray show them. */

View File

@@ -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.Box
@@ -22,20 +22,20 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.AnchoredScrolling
import ru.stenfredd.movies.ui.components.Chip
import ru.stenfredd.movies.ui.components.PosterCard
import ru.stenfredd.movies.ui.components.anchorViewport
import ru.stenfredd.movies.ui.components.anchoredRow
import ru.stenfredd.movies.ui.components.fullItem
import ru.stenfredd.movies.ui.focus.ForgetMissing
import ru.stenfredd.movies.ui.focus.Restore
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
import ru.stenfredd.movies.ui.focus.remembered
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
import ru.stenfredd.sleepyowl.ui.components.Chip
import ru.stenfredd.sleepyowl.ui.components.PosterCard
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
import ru.stenfredd.sleepyowl.ui.components.fullItem
import ru.stenfredd.sleepyowl.ui.focus.ForgetMissing
import ru.stenfredd.sleepyowl.ui.focus.Restore
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.remembered
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
import ru.stenfredd.sleepyowl.ui.theme.AppType
/** Favourites tab (mockup screen «Избранное»): title with the count, library filter chips, grid of posters. */
@Composable

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.favorites
package ru.stenfredd.sleepyowl.ui.favorites
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
@@ -15,15 +15,15 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.stenfredd.movies.core.data.LibraryRepository
import ru.stenfredd.movies.core.data.SessionCache
import ru.stenfredd.movies.core.data.WatchRepository
import ru.stenfredd.movies.core.data.model.ItemSummary
import ru.stenfredd.movies.core.data.model.LibraryView
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.PosterModel
import ru.stenfredd.movies.ui.model.CardMapper
import ru.stenfredd.movies.ui.model.plural
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
import ru.stenfredd.sleepyowl.core.data.SessionCache
import ru.stenfredd.sleepyowl.core.data.WatchRepository
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.PosterModel
import ru.stenfredd.sleepyowl.ui.model.CardMapper
import ru.stenfredd.sleepyowl.ui.model.plural
import timber.log.Timber
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap

View File

@@ -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.LaunchedEffect

View File

@@ -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.Box
@@ -20,20 +20,20 @@ import androidx.compose.ui.focus.focusRestorer
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.AnchoredScrolling
import ru.stenfredd.movies.ui.components.anchorViewport
import ru.stenfredd.movies.ui.components.anchoredRow
import ru.stenfredd.movies.ui.components.ContentRow
import ru.stenfredd.movies.ui.components.FeaturedCard
import ru.stenfredd.movies.ui.components.PosterCard
import ru.stenfredd.movies.ui.components.SectionTitle
import ru.stenfredd.movies.ui.components.WideCard
import ru.stenfredd.movies.ui.focus.Restore
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
import ru.stenfredd.movies.ui.focus.remembered
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
import ru.stenfredd.sleepyowl.ui.components.ContentRow
import ru.stenfredd.sleepyowl.ui.components.FeaturedCard
import ru.stenfredd.sleepyowl.ui.components.PosterCard
import ru.stenfredd.sleepyowl.ui.components.SectionTitle
import ru.stenfredd.sleepyowl.ui.components.WideCard
import ru.stenfredd.sleepyowl.ui.focus.Restore
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.remembered
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
import ru.stenfredd.sleepyowl.ui.theme.AppType
@Composable
fun HomeScreen(onOpen: (Screen) -> Unit, vm: HomeViewModel = hiltViewModel()) {
@@ -84,7 +84,7 @@ fun HomeScreen(onOpen: (Screen) -> Unit, vm: HomeViewModel = hiltViewModel()) {
}
@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)) {
state.continueItems.chunked(2).forEach { pair ->
Row(horizontalArrangement = Arrangement.spacedBy(12.dp)) {

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.home
package ru.stenfredd.sleepyowl.ui.home
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
@@ -12,14 +12,14 @@ import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
import ru.stenfredd.movies.core.data.HomeContent
import ru.stenfredd.movies.core.data.HomeRepository
import ru.stenfredd.movies.core.data.model.ItemSummary
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.FeaturedModel
import ru.stenfredd.movies.ui.components.PosterModel
import ru.stenfredd.movies.ui.components.WideModel
import ru.stenfredd.movies.ui.model.CardMapper
import ru.stenfredd.sleepyowl.core.data.HomeContent
import ru.stenfredd.sleepyowl.core.data.HomeRepository
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.FeaturedModel
import ru.stenfredd.sleepyowl.ui.components.PosterModel
import ru.stenfredd.sleepyowl.ui.components.WideModel
import ru.stenfredd.sleepyowl.ui.model.CardMapper
import timber.log.Timber
import javax.inject.Inject

View File

@@ -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.concurrent.ConcurrentHashMap
import javax.inject.Inject

View File

@@ -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.border
@@ -46,27 +46,27 @@ import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.flow.distinctUntilChanged
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.AnchoredScroll
import ru.stenfredd.movies.ui.components.AnchoredScrolling
import ru.stenfredd.movies.ui.components.Chip
import ru.stenfredd.movies.ui.components.ContentRow
import ru.stenfredd.movies.ui.components.DefaultScrolling
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.PosterCard
import ru.stenfredd.movies.ui.components.WideCard
import ru.stenfredd.movies.ui.components.anchorViewport
import ru.stenfredd.movies.ui.components.anchoredRow
import ru.stenfredd.movies.ui.components.bleed
import ru.stenfredd.movies.ui.components.fullItem
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.focus.Restore
import ru.stenfredd.movies.ui.focus.ScreenFocus
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
import ru.stenfredd.movies.ui.focus.remembered
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.AnchoredScroll
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
import ru.stenfredd.sleepyowl.ui.components.Chip
import ru.stenfredd.sleepyowl.ui.components.ContentRow
import ru.stenfredd.sleepyowl.ui.components.DefaultScrolling
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.PosterCard
import ru.stenfredd.sleepyowl.ui.components.WideCard
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
import ru.stenfredd.sleepyowl.ui.components.bleed
import ru.stenfredd.sleepyowl.ui.components.fullItem
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.focus.Restore
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.remembered
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
import ru.stenfredd.sleepyowl.ui.theme.AppType
/**
* The library tab (mockup screen «Медиатека»): library tiles on top; under them, for the selected library,

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.library
package ru.stenfredd.sleepyowl.ui.library
import android.os.SystemClock
import androidx.compose.runtime.Immutable
@@ -18,24 +18,24 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.stenfredd.movies.core.data.LibraryRepository
import ru.stenfredd.movies.core.data.SessionCache
import ru.stenfredd.movies.core.data.WatchRepository
import ru.stenfredd.movies.core.data.model.ItemKind
import ru.stenfredd.movies.core.data.model.ItemQuery
import ru.stenfredd.movies.core.data.model.ItemSort
import ru.stenfredd.movies.core.data.model.ItemSummary
import ru.stenfredd.movies.core.data.model.LibraryType
import ru.stenfredd.movies.core.data.model.LibraryView
import ru.stenfredd.movies.core.data.model.itemKinds
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.PosterModel
import ru.stenfredd.movies.ui.components.WideModel
import ru.stenfredd.movies.ui.model.CardMapper
import ru.stenfredd.movies.ui.model.daysAgo
import ru.stenfredd.movies.ui.model.plural
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
import ru.stenfredd.sleepyowl.core.data.SessionCache
import ru.stenfredd.sleepyowl.core.data.WatchRepository
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
import ru.stenfredd.sleepyowl.core.data.model.ItemQuery
import ru.stenfredd.sleepyowl.core.data.model.ItemSort
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
import ru.stenfredd.sleepyowl.core.data.model.LibraryType
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
import ru.stenfredd.sleepyowl.core.data.model.itemKinds
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.PosterModel
import ru.stenfredd.sleepyowl.ui.components.WideModel
import ru.stenfredd.sleepyowl.ui.model.CardMapper
import ru.stenfredd.sleepyowl.ui.model.daysAgo
import ru.stenfredd.sleepyowl.ui.model.plural
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import timber.log.Timber
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.library
package ru.stenfredd.sleepyowl.ui.library
import android.content.Context
import android.graphics.Bitmap
@@ -31,7 +31,7 @@ import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
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. */
@Immutable

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.login
package ru.stenfredd.sleepyowl.ui.login
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
@@ -31,7 +31,6 @@ import androidx.compose.runtime.setValue
import androidx.compose.runtime.withFrameNanos
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.focus.focusProperties
import androidx.compose.ui.focus.onFocusChanged
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.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.delay
import ru.stenfredd.movies.ui.components.AppIcon
import ru.stenfredd.movies.ui.components.Avatar
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.Icon
import ru.stenfredd.movies.ui.components.KeyboardLift
import ru.stenfredd.movies.ui.components.LocalKeyboardLift
import ru.stenfredd.movies.ui.components.liftForKeyboard
import ru.stenfredd.movies.ui.components.StatusDot
import ru.stenfredd.movies.ui.components.TextInput
import ru.stenfredd.movies.ui.components.dashedBorder
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.components.rememberTextInputState
import ru.stenfredd.movies.ui.focus.Restore
import ru.stenfredd.movies.ui.focus.ScreenFocus
import ru.stenfredd.movies.ui.focus.remembered
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.components.AppIcon
import ru.stenfredd.sleepyowl.ui.components.Avatar
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.Icon
import ru.stenfredd.sleepyowl.ui.components.KeyboardLift
import ru.stenfredd.sleepyowl.ui.components.LocalKeyboardLift
import ru.stenfredd.sleepyowl.ui.components.OwlMark
import ru.stenfredd.sleepyowl.ui.components.liftForKeyboard
import ru.stenfredd.sleepyowl.ui.components.StatusDot
import ru.stenfredd.sleepyowl.ui.components.TextInput
import ru.stenfredd.sleepyowl.ui.components.Wordmark
import ru.stenfredd.sleepyowl.ui.components.dashedBorder
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.components.rememberTextInputState
import ru.stenfredd.sleepyowl.ui.focus.Restore
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
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. */
@Composable
@@ -77,7 +78,7 @@ fun LoginScreen(onDone: () -> Unit, vm: LoginViewModel = hiltViewModel()) {
val lift = remember { KeyboardLift() }
Box(Modifier.fillMaxSize().liftForKeyboard(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))
val focus = vm.focus.getValue(state.step)
key(state.step) {
@@ -105,17 +106,12 @@ private fun hint(state: LoginState) = when (state.step) {
// ---- Header ----
/** Neutral placeholder logo until the app has a name (same as the side rail's). */
/** Same as the open side rail's. */
@Composable
private fun Logo(modifier: Modifier = Modifier) {
Row(modifier, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
Spacer(
Modifier.size(9.dp).drawBehind {
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))
OwlMark()
Wordmark()
}
}

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.login
package ru.stenfredd.sleepyowl.ui.login
import android.os.SystemClock
import androidx.compose.runtime.Immutable
@@ -19,14 +19,14 @@ import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.jellyfin.sdk.api.client.exception.InvalidStatusException
import ru.stenfredd.movies.core.jellyfin.Account
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
import ru.stenfredd.movies.core.jellyfin.PublicUser
import ru.stenfredd.movies.core.jellyfin.QuickConnectExpiredException
import ru.stenfredd.movies.core.jellyfin.Server
import ru.stenfredd.movies.core.jellyfin.ServerLogin
import ru.stenfredd.movies.core.jellyfin.ServerNotFoundException
import ru.stenfredd.movies.ui.focus.ScreenFocus
import ru.stenfredd.sleepyowl.core.jellyfin.Account
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
import ru.stenfredd.sleepyowl.core.jellyfin.PublicUser
import ru.stenfredd.sleepyowl.core.jellyfin.QuickConnectExpiredException
import ru.stenfredd.sleepyowl.core.jellyfin.Server
import ru.stenfredd.sleepyowl.core.jellyfin.ServerLogin
import ru.stenfredd.sleepyowl.core.jellyfin.ServerNotFoundException
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
import timber.log.Timber
import java.time.LocalDate
import java.time.ZoneId

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.login
package ru.stenfredd.sleepyowl.ui.login
import android.graphics.Bitmap
import androidx.compose.ui.graphics.ImageBitmap

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.menu
package ru.stenfredd.sleepyowl.ui.menu
import android.view.KeyEvent as AndroidKeyEvent
import androidx.compose.foundation.background
@@ -49,16 +49,16 @@ import androidx.lifecycle.ViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.launch
import ru.stenfredd.movies.core.data.WatchRepository
import ru.stenfredd.movies.core.data.model.ItemKind
import ru.stenfredd.movies.ui.components.AppIcon
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.Icon
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.model.plural
import ru.stenfredd.movies.ui.player.SidePanel
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.core.data.WatchRepository
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
import ru.stenfredd.sleepyowl.ui.components.AppIcon
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.Icon
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.model.plural
import ru.stenfredd.sleepyowl.ui.player.SidePanel
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppType
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject

View File

@@ -1,18 +1,18 @@
package ru.stenfredd.movies.ui.model
package ru.stenfredd.sleepyowl.ui.model
import android.content.Context
import dagger.hilt.android.qualifiers.ApplicationContext
import ru.stenfredd.movies.core.data.ImageUrls
import ru.stenfredd.movies.core.data.model.ImageRef
import ru.stenfredd.movies.core.data.model.ItemKind
import ru.stenfredd.movies.core.data.model.ItemSummary
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.FeaturedModel
import ru.stenfredd.movies.ui.components.PosterModel
import ru.stenfredd.movies.ui.components.RemoteImageSpec
import ru.stenfredd.movies.ui.components.WideModel
import ru.stenfredd.movies.ui.menu.WatchTarget
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.sleepyowl.core.data.ImageUrls
import ru.stenfredd.sleepyowl.core.data.model.ImageRef
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.FeaturedModel
import ru.stenfredd.sleepyowl.ui.components.PosterModel
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
import ru.stenfredd.sleepyowl.ui.components.WideModel
import ru.stenfredd.sleepyowl.ui.menu.WatchTarget
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
import javax.inject.Inject
import kotlin.math.roundToInt

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.model
package ru.stenfredd.sleepyowl.ui.model
import java.time.Instant
import java.time.LocalDate

View File

@@ -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.Box
@@ -22,20 +22,20 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.AnchoredScrolling
import ru.stenfredd.movies.ui.components.Avatar
import ru.stenfredd.movies.ui.components.PosterCard
import ru.stenfredd.movies.ui.components.RemoteImage
import ru.stenfredd.movies.ui.components.anchorViewport
import ru.stenfredd.movies.ui.components.anchoredRow
import ru.stenfredd.movies.ui.components.fullItem
import ru.stenfredd.movies.ui.focus.Restore
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
import ru.stenfredd.movies.ui.focus.remembered
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
import ru.stenfredd.sleepyowl.ui.components.Avatar
import ru.stenfredd.sleepyowl.ui.components.PosterCard
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
import ru.stenfredd.sleepyowl.ui.components.fullItem
import ru.stenfredd.sleepyowl.ui.focus.Restore
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.remembered
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
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 сериала",

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.person
package ru.stenfredd.sleepyowl.ui.person
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
@@ -16,14 +16,14 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.stenfredd.movies.core.data.LibraryRepository
import ru.stenfredd.movies.core.data.SessionCache
import ru.stenfredd.movies.core.data.model.ItemKind
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.PosterModel
import ru.stenfredd.movies.ui.components.RemoteImageSpec
import ru.stenfredd.movies.ui.model.CardMapper
import ru.stenfredd.movies.ui.model.plural
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
import ru.stenfredd.sleepyowl.core.data.SessionCache
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.PosterModel
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
import ru.stenfredd.sleepyowl.ui.model.CardMapper
import ru.stenfredd.sleepyowl.ui.model.plural
import timber.log.Timber
import java.util.UUID
import java.util.concurrent.ConcurrentHashMap

View File

@@ -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.layout.Arrangement
@@ -21,15 +21,15 @@ import androidx.tv.material3.MaterialTheme
import androidx.tv.material3.Text
import org.jellyfin.sdk.model.api.MediaStreamType
import org.jellyfin.sdk.model.api.PlayMethod
import ru.stenfredd.movies.playback.api.Codecs
import ru.stenfredd.movies.playback.api.DolbyVisionSwitchable
import ru.stenfredd.movies.playback.api.EngineId
import ru.stenfredd.movies.playback.api.VideoPathSwitchable
import ru.stenfredd.movies.playback.core.PlaybackSession
import ru.stenfredd.movies.playback.core.PlaybackUiState
import ru.stenfredd.movies.playback.core.describe
import ru.stenfredd.movies.playback.exo.ExoEngineProvider
import ru.stenfredd.movies.playback.vlc.VlcEngineProvider
import ru.stenfredd.sleepyowl.playback.api.Codecs
import ru.stenfredd.sleepyowl.playback.api.DolbyVisionSwitchable
import ru.stenfredd.sleepyowl.playback.api.EngineId
import ru.stenfredd.sleepyowl.playback.api.VideoPathSwitchable
import ru.stenfredd.sleepyowl.playback.core.PlaybackSession
import ru.stenfredd.sleepyowl.playback.core.PlaybackUiState
import ru.stenfredd.sleepyowl.playback.core.describe
import ru.stenfredd.sleepyowl.playback.exo.ExoEngineProvider
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

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.player
package ru.stenfredd.sleepyowl.ui.player
import android.view.KeyEvent as AndroidKeyEvent
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.em
import androidx.compose.ui.unit.sp
import ru.stenfredd.movies.ui.components.AppIcon
import ru.stenfredd.movies.ui.components.Avatar
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.Icon
import ru.stenfredd.movies.ui.components.ImageShade
import ru.stenfredd.movies.ui.components.ProgressLine
import ru.stenfredd.movies.ui.components.RemoteImage
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.components.AppIcon
import ru.stenfredd.sleepyowl.ui.components.Avatar
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.Icon
import ru.stenfredd.sleepyowl.ui.components.ImageShade
import ru.stenfredd.sleepyowl.ui.components.ProgressLine
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppType
import java.util.UUID
/** Height of the drawer; the controls move up by this much while it is open. */

View File

@@ -1,17 +1,17 @@
package ru.stenfredd.movies.ui.player
package ru.stenfredd.sleepyowl.ui.player
import androidx.compose.runtime.Immutable
import androidx.compose.ui.graphics.Color
import org.jellyfin.sdk.model.api.PlayMethod
import ru.stenfredd.movies.core.data.model.MediaInfo
import ru.stenfredd.movies.core.data.model.VideoRange
import ru.stenfredd.movies.playback.api.DolbyVisionSwitchable
import ru.stenfredd.movies.playback.api.PlaybackEngine
import ru.stenfredd.movies.playback.api.VideoPathSwitchable
import ru.stenfredd.movies.playback.core.PlaybackUiState
import ru.stenfredd.movies.ui.details.MediaLabels
import ru.stenfredd.movies.ui.details.TrackOption
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
import ru.stenfredd.sleepyowl.core.data.model.VideoRange
import ru.stenfredd.sleepyowl.playback.api.DolbyVisionSwitchable
import ru.stenfredd.sleepyowl.playback.api.PlaybackEngine
import ru.stenfredd.sleepyowl.playback.api.VideoPathSwitchable
import ru.stenfredd.sleepyowl.playback.core.PlaybackUiState
import ru.stenfredd.sleepyowl.ui.details.MediaLabels
import ru.stenfredd.sleepyowl.ui.details.TrackOption
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import java.util.Locale
/** Audio and subtitle choices of the file being played. Subtitles start with "Выкл" (index null). */

View File

@@ -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.border
@@ -33,13 +33,13 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
import ru.stenfredd.movies.ui.components.AppIcon
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.Icon
import ru.stenfredd.movies.ui.components.RemoteImage
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.components.AppIcon
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.Icon
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.theme.AppColors
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. */
internal const val NEXT_PROMPT_MS = 30_000L

View File

@@ -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.border
@@ -39,16 +39,16 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
import ru.stenfredd.movies.core.data.model.MediaSegment
import ru.stenfredd.movies.ui.components.AppIcon
import ru.stenfredd.sleepyowl.core.data.model.MediaSegment
import ru.stenfredd.sleepyowl.ui.components.AppIcon
import kotlin.math.roundToInt
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.Icon
import ru.stenfredd.movies.ui.components.StatusDot
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.shell.Clock
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.Icon
import ru.stenfredd.sleepyowl.ui.components.StatusDot
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.shell.Clock
import ru.stenfredd.sleepyowl.ui.theme.AppColors
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.

View File

@@ -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.border
@@ -46,14 +46,14 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.em
import androidx.compose.ui.unit.sp
import ru.stenfredd.movies.playback.api.SubtitleStyle
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.MinimalScrolling
import ru.stenfredd.movies.ui.components.SecondaryButton
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.details.TrackOption
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.MinimalScrolling
import ru.stenfredd.sleepyowl.ui.components.SecondaryButton
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.details.TrackOption
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppType
enum class PlayerPanel { Audio, Subtitles, Quality, Info }

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.player
package ru.stenfredd.sleepyowl.ui.player
import android.view.KeyEvent as AndroidKeyEvent
import android.widget.FrameLayout
@@ -49,24 +49,24 @@ import androidx.lifecycle.Lifecycle
import androidx.lifecycle.compose.LifecycleEventEffect
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.delay
import ru.stenfredd.movies.BuildConfig
import ru.stenfredd.movies.core.data.model.MediaInfo
import ru.stenfredd.movies.core.data.model.MediaSegment
import ru.stenfredd.movies.core.data.model.VideoRange
import ru.stenfredd.movies.core.data.toMediaInfo
import ru.stenfredd.movies.playback.api.DolbyVisionSwitchable
import ru.stenfredd.movies.playback.api.EngineId
import ru.stenfredd.movies.playback.api.EngineState
import ru.stenfredd.movies.playback.api.SubtitleStyle
import ru.stenfredd.movies.playback.api.VideoPathSwitchable
import ru.stenfredd.movies.playback.core.PlaybackSession
import ru.stenfredd.movies.playback.core.PlaybackUiState
import ru.stenfredd.movies.playback.exo.ExoEngineProvider
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.AppIcon
import ru.stenfredd.movies.ui.components.SecondaryButton
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.BuildConfig
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
import ru.stenfredd.sleepyowl.core.data.model.MediaSegment
import ru.stenfredd.sleepyowl.core.data.model.VideoRange
import ru.stenfredd.sleepyowl.core.data.toMediaInfo
import ru.stenfredd.sleepyowl.playback.api.DolbyVisionSwitchable
import ru.stenfredd.sleepyowl.playback.api.EngineId
import ru.stenfredd.sleepyowl.playback.api.EngineState
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
import ru.stenfredd.sleepyowl.playback.api.VideoPathSwitchable
import ru.stenfredd.sleepyowl.playback.core.PlaybackSession
import ru.stenfredd.sleepyowl.playback.core.PlaybackUiState
import ru.stenfredd.sleepyowl.playback.exo.ExoEngineProvider
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.AppIcon
import ru.stenfredd.sleepyowl.ui.components.SecondaryButton
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppType
import java.time.LocalTime
import java.time.format.DateTimeFormatter
import java.util.UUID

View File

@@ -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.border
@@ -24,14 +24,14 @@ import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import ru.stenfredd.movies.core.data.model.MediaSegment
import ru.stenfredd.movies.core.data.model.SegmentKind
import ru.stenfredd.movies.playback.core.PlaybackDefaults
import ru.stenfredd.movies.playback.core.SkipMode
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.core.data.model.MediaSegment
import ru.stenfredd.sleepyowl.core.data.model.SegmentKind
import ru.stenfredd.sleepyowl.playback.core.PlaybackDefaults
import ru.stenfredd.sleepyowl.playback.core.SkipMode
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppType
import java.util.UUID
/** The server's segments of one item (they arrive after the item starts playing). */

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.player
package ru.stenfredd.sleepyowl.ui.player
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
@@ -14,26 +14,26 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.stenfredd.movies.core.data.LibraryRepository
import ru.stenfredd.movies.core.data.model.ItemDetails
import ru.stenfredd.movies.core.data.model.ItemKind
import ru.stenfredd.movies.core.data.model.ItemSummary
import ru.stenfredd.movies.core.data.model.PersonKind
import ru.stenfredd.movies.playback.api.EngineId
import ru.stenfredd.movies.playback.api.StreamSelection
import ru.stenfredd.movies.playback.api.SubtitleStyle
import ru.stenfredd.movies.playback.core.DeviceCapabilitiesProbe
import ru.stenfredd.movies.playback.core.EngineSelector
import ru.stenfredd.movies.playback.core.PlaybackDefaults
import ru.stenfredd.movies.playback.core.PlaybackPreferences
import ru.stenfredd.movies.playback.core.PlaybackSession
import ru.stenfredd.movies.playback.core.PlaybackSessionFactory
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.RemoteImageSpec
import ru.stenfredd.movies.ui.model.plural
import ru.stenfredd.movies.ui.details.CastModel
import ru.stenfredd.movies.ui.details.MediaLabels
import ru.stenfredd.movies.ui.model.CardMapper
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
import ru.stenfredd.sleepyowl.core.data.model.ItemDetails
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
import ru.stenfredd.sleepyowl.core.data.model.PersonKind
import ru.stenfredd.sleepyowl.playback.api.EngineId
import ru.stenfredd.sleepyowl.playback.api.StreamSelection
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
import ru.stenfredd.sleepyowl.playback.core.DeviceCapabilitiesProbe
import ru.stenfredd.sleepyowl.playback.core.EngineSelector
import ru.stenfredd.sleepyowl.playback.core.PlaybackDefaults
import ru.stenfredd.sleepyowl.playback.core.PlaybackPreferences
import ru.stenfredd.sleepyowl.playback.core.PlaybackSession
import ru.stenfredd.sleepyowl.playback.core.PlaybackSessionFactory
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
import ru.stenfredd.sleepyowl.ui.model.plural
import ru.stenfredd.sleepyowl.ui.details.CastModel
import ru.stenfredd.sleepyowl.ui.details.MediaLabels
import ru.stenfredd.sleepyowl.ui.model.CardMapper
import timber.log.Timber
import java.util.Locale
import java.util.UUID

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.search
package ru.stenfredd.sleepyowl.ui.search
import android.view.KeyEvent as NativeKeyEvent
import androidx.compose.foundation.background
@@ -48,26 +48,26 @@ import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.delay
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.AnchoredScrolling
import ru.stenfredd.movies.ui.components.AppIcon
import ru.stenfredd.movies.ui.components.Avatar
import ru.stenfredd.movies.ui.components.Chip
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.Icon
import ru.stenfredd.movies.ui.components.PosterCard
import ru.stenfredd.movies.ui.components.RemoteImage
import ru.stenfredd.movies.ui.components.anchorViewport
import ru.stenfredd.movies.ui.components.anchoredRow
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.components.fullItem
import ru.stenfredd.movies.ui.focus.Restore
import ru.stenfredd.movies.ui.focus.ScreenFocus
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
import ru.stenfredd.movies.ui.focus.remembered
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.AnchoredScrolling
import ru.stenfredd.sleepyowl.ui.components.AppIcon
import ru.stenfredd.sleepyowl.ui.components.Avatar
import ru.stenfredd.sleepyowl.ui.components.Chip
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.Icon
import ru.stenfredd.sleepyowl.ui.components.PosterCard
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
import ru.stenfredd.sleepyowl.ui.components.anchorViewport
import ru.stenfredd.sleepyowl.ui.components.anchoredRow
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.components.fullItem
import ru.stenfredd.sleepyowl.ui.focus.Restore
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.remembered
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
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
@@ -269,10 +269,10 @@ private fun Results(state: SearchState, focus: ScreenFocus, vm: SearchViewModel,
}
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,
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 ->
PosterCard(p, { open(p.key) }, Modifier.padding(bottom = 18.dp).anchoredRow(anchored).remembered(focus, p.key))

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.search
package ru.stenfredd.sleepyowl.ui.search
import androidx.compose.runtime.Immutable
import androidx.lifecycle.ViewModel
@@ -17,13 +17,13 @@ import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.stenfredd.movies.core.data.LibraryRepository
import ru.stenfredd.movies.core.data.SearchHistory
import ru.stenfredd.movies.core.data.model.Person
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.PosterModel
import ru.stenfredd.movies.ui.components.RemoteImageSpec
import ru.stenfredd.movies.ui.model.CardMapper
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
import ru.stenfredd.sleepyowl.core.data.SearchHistory
import ru.stenfredd.sleepyowl.core.data.model.Person
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.PosterModel
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
import ru.stenfredd.sleepyowl.ui.model.CardMapper
import timber.log.Timber
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.series
package ru.stenfredd.sleepyowl.ui.series
import android.view.KeyEvent as AndroidKeyEvent
import androidx.activity.compose.BackHandler
@@ -69,26 +69,26 @@ import androidx.compose.ui.unit.sp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.launch
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.AppIcon
import ru.stenfredd.movies.ui.components.CircleButton
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.FormatBadge
import ru.stenfredd.movies.ui.components.MinimalScrolling
import ru.stenfredd.movies.ui.components.PrimaryButton
import ru.stenfredd.movies.ui.components.ProgressLine
import ru.stenfredd.movies.ui.components.RemoteImage
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.details.Backdrop
import ru.stenfredd.movies.ui.focus.Restore
import ru.stenfredd.movies.ui.focus.ScreenFocus
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
import ru.stenfredd.movies.ui.focus.remembered
import ru.stenfredd.movies.ui.menu.LocalWatchMenu
import ru.stenfredd.movies.ui.menu.clickableWithMenu
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.AppIcon
import ru.stenfredd.sleepyowl.ui.components.CircleButton
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.FormatBadge
import ru.stenfredd.sleepyowl.ui.components.MinimalScrolling
import ru.stenfredd.sleepyowl.ui.components.PrimaryButton
import ru.stenfredd.sleepyowl.ui.components.ProgressLine
import ru.stenfredd.sleepyowl.ui.components.RemoteImage
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.details.Backdrop
import ru.stenfredd.sleepyowl.ui.focus.Restore
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.remembered
import ru.stenfredd.sleepyowl.ui.menu.LocalWatchMenu
import ru.stenfredd.sleepyowl.ui.menu.clickableWithMenu
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
import ru.stenfredd.sleepyowl.ui.theme.AppType
import kotlin.math.floor
import kotlin.math.roundToInt

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.series
package ru.stenfredd.sleepyowl.ui.series
import android.view.KeyEvent as AndroidKeyEvent
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.em
import ru.stenfredd.movies.playback.api.SubtitleStyle
import ru.stenfredd.movies.ui.components.MinimalScrolling
import ru.stenfredd.movies.ui.player.PanelChips
import ru.stenfredd.movies.ui.player.PanelList
import ru.stenfredd.movies.ui.player.PanelSection
import ru.stenfredd.movies.ui.player.SubtitleChoices
import ru.stenfredd.movies.ui.player.toChoices
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
import ru.stenfredd.sleepyowl.ui.components.MinimalScrolling
import ru.stenfredd.sleepyowl.ui.player.PanelChips
import ru.stenfredd.sleepyowl.ui.player.PanelList
import ru.stenfredd.sleepyowl.ui.player.PanelSection
import ru.stenfredd.sleepyowl.ui.player.SubtitleChoices
import ru.stenfredd.sleepyowl.ui.player.toChoices
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppType
/**
* "Аудио и субтитры" tray at the bottom of the series page: audio, subtitles and their look, applied at once and

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.series
package ru.stenfredd.sleepyowl.ui.series
import android.os.SystemClock
import androidx.compose.runtime.Immutable
@@ -20,25 +20,25 @@ import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.stenfredd.movies.core.data.ImageUrls
import ru.stenfredd.movies.core.data.LibraryRepository
import ru.stenfredd.movies.core.data.SessionCache
import ru.stenfredd.movies.core.data.WatchRepository
import ru.stenfredd.movies.core.data.model.ItemDetails
import ru.stenfredd.movies.core.data.model.ItemKind
import ru.stenfredd.movies.core.data.model.ItemSummary
import ru.stenfredd.movies.core.data.model.MediaInfo
import ru.stenfredd.movies.playback.api.SubtitleStyle
import ru.stenfredd.movies.playback.core.PlaybackPreferences
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.RemoteImageSpec
import ru.stenfredd.movies.ui.details.MediaLabels
import ru.stenfredd.movies.ui.details.TrackChoices
import ru.stenfredd.movies.ui.details.TrackOption
import ru.stenfredd.movies.ui.menu.WatchTarget
import ru.stenfredd.movies.ui.model.CardMapper
import ru.stenfredd.movies.ui.player.PlayerLabels
import ru.stenfredd.movies.ui.model.plural
import ru.stenfredd.sleepyowl.core.data.ImageUrls
import ru.stenfredd.sleepyowl.core.data.LibraryRepository
import ru.stenfredd.sleepyowl.core.data.SessionCache
import ru.stenfredd.sleepyowl.core.data.WatchRepository
import ru.stenfredd.sleepyowl.core.data.model.ItemDetails
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
import ru.stenfredd.sleepyowl.playback.core.PlaybackPreferences
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.RemoteImageSpec
import ru.stenfredd.sleepyowl.ui.details.MediaLabels
import ru.stenfredd.sleepyowl.ui.details.TrackChoices
import ru.stenfredd.sleepyowl.ui.details.TrackOption
import ru.stenfredd.sleepyowl.ui.menu.WatchTarget
import ru.stenfredd.sleepyowl.ui.model.CardMapper
import ru.stenfredd.sleepyowl.ui.player.PlayerLabels
import ru.stenfredd.sleepyowl.ui.model.plural
import timber.log.Timber
import java.time.Instant
import java.time.ZoneId

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.settings
package ru.stenfredd.sleepyowl.ui.settings
import android.view.KeyEvent as AndroidKeyEvent
import androidx.compose.foundation.focusable
@@ -34,10 +34,10 @@ import androidx.compose.ui.unit.sp
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.theme.AppColors
import ru.stenfredd.sleepyowl.ui.theme.AppDimens
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). */
@Composable

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.settings
package ru.stenfredd.sleepyowl.ui.settings
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). */
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(
Component("libVLC", "VideoLAN, второй движок воспроизведения", "LGPL-2.1", "LGPL-2.1.txt"),

View File

@@ -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.border
@@ -54,31 +54,33 @@ import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import ru.stenfredd.movies.core.data.LanguageSettings
import ru.stenfredd.movies.core.data.SubtitleMode
import ru.stenfredd.movies.core.jellyfin.Account
import ru.stenfredd.movies.playback.api.SubtitleStyle
import ru.stenfredd.movies.playback.api.VideoPathSwitchable
import ru.stenfredd.movies.playback.core.PlaybackDefaults
import ru.stenfredd.movies.playback.core.SkipMode
import ru.stenfredd.movies.ui.Screen
import ru.stenfredd.movies.ui.components.Avatar
import ru.stenfredd.movies.ui.components.Chip
import ru.stenfredd.movies.ui.components.FocusStyle
import ru.stenfredd.movies.ui.components.MinimalScrolling
import ru.stenfredd.movies.ui.components.SecondaryButton
import ru.stenfredd.movies.ui.components.focusCard
import ru.stenfredd.movies.ui.focus.Restore
import ru.stenfredd.movies.ui.focus.ScreenFocus
import ru.stenfredd.movies.ui.focus.rememberScreenFocus
import ru.stenfredd.movies.ui.focus.remembered
import ru.stenfredd.movies.ui.player.PlayerLabels
import ru.stenfredd.movies.ui.player.QualityCaps
import ru.stenfredd.movies.ui.player.SubtitleChoices
import ru.stenfredd.movies.ui.player.SubtitlePreview
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.core.data.LanguageSettings
import ru.stenfredd.sleepyowl.core.data.SubtitleMode
import ru.stenfredd.sleepyowl.core.jellyfin.Account
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
import ru.stenfredd.sleepyowl.playback.api.VideoPathSwitchable
import ru.stenfredd.sleepyowl.playback.core.PlaybackDefaults
import ru.stenfredd.sleepyowl.playback.core.SkipMode
import ru.stenfredd.sleepyowl.ui.Screen
import ru.stenfredd.sleepyowl.ui.components.Avatar
import ru.stenfredd.sleepyowl.ui.components.Chip
import ru.stenfredd.sleepyowl.ui.components.FocusStyle
import ru.stenfredd.sleepyowl.ui.components.MinimalScrolling
import ru.stenfredd.sleepyowl.ui.components.OwlMark
import ru.stenfredd.sleepyowl.ui.components.SecondaryButton
import ru.stenfredd.sleepyowl.ui.components.Wordmark
import ru.stenfredd.sleepyowl.ui.components.focusCard
import ru.stenfredd.sleepyowl.ui.focus.Restore
import ru.stenfredd.sleepyowl.ui.focus.ScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.rememberScreenFocus
import ru.stenfredd.sleepyowl.ui.focus.remembered
import ru.stenfredd.sleepyowl.ui.player.PlayerLabels
import ru.stenfredd.sleepyowl.ui.player.QualityCaps
import ru.stenfredd.sleepyowl.ui.player.SubtitleChoices
import ru.stenfredd.sleepyowl.ui.player.SubtitlePreview
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. */
private enum class Section(val title: String, val dot: Color) {
@@ -530,7 +532,10 @@ private fun InfoLine(key: String, value: String) {
@Composable
private fun AboutSection(vm: SettingsViewModel, focus: ScreenFocus, onOpen: (Screen) -> Unit) {
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.device, style = AppType.MonoMeta.copy(color = AppColors.TextDim))
}

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.settings
package ru.stenfredd.sleepyowl.ui.settings
import android.content.Context
import android.os.Build
@@ -21,17 +21,17 @@ import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.stenfredd.movies.BuildConfig
import ru.stenfredd.movies.core.data.LanguageSettings
import ru.stenfredd.movies.core.data.ServerInfo
import ru.stenfredd.movies.core.data.UserSettingsRepository
import ru.stenfredd.movies.core.jellyfin.Account
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
import ru.stenfredd.movies.playback.api.SubtitleStyle
import ru.stenfredd.movies.playback.core.DeviceCapabilitiesProbe
import ru.stenfredd.movies.playback.core.PlaybackDefaults
import ru.stenfredd.movies.playback.core.PlaybackPreferences
import ru.stenfredd.movies.ui.TourEntry
import ru.stenfredd.sleepyowl.BuildConfig
import ru.stenfredd.sleepyowl.core.data.LanguageSettings
import ru.stenfredd.sleepyowl.core.data.ServerInfo
import ru.stenfredd.sleepyowl.core.data.UserSettingsRepository
import ru.stenfredd.sleepyowl.core.jellyfin.Account
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
import ru.stenfredd.sleepyowl.playback.api.SubtitleStyle
import ru.stenfredd.sleepyowl.playback.core.DeviceCapabilitiesProbe
import ru.stenfredd.sleepyowl.playback.core.PlaybackDefaults
import ru.stenfredd.sleepyowl.playback.core.PlaybackPreferences
import ru.stenfredd.sleepyowl.ui.TourEntry
import timber.log.Timber
import javax.inject.Inject

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.shell
package ru.stenfredd.sleepyowl.ui.shell
import androidx.activity.compose.BackHandler
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.Color
import androidx.compose.ui.graphics.lerp
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.util.lerp
import androidx.compose.ui.graphics.graphicsLayer
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.zIndex
import kotlinx.coroutines.delay
import ru.stenfredd.movies.ui.components.AppIcon
import ru.stenfredd.movies.ui.components.Avatar
import ru.stenfredd.movies.ui.components.Icon
import ru.stenfredd.movies.ui.theme.AppColors
import ru.stenfredd.movies.ui.theme.AppDimens
import ru.stenfredd.movies.ui.theme.AppType
import ru.stenfredd.sleepyowl.ui.components.AppIcon
import ru.stenfredd.sleepyowl.ui.components.Avatar
import ru.stenfredd.sleepyowl.ui.components.Icon
import ru.stenfredd.sleepyowl.ui.components.OwlMark
import ru.stenfredd.sleepyowl.ui.components.Wordmark
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.format.DateTimeFormatter
import java.util.UUID
@@ -161,7 +162,7 @@ private fun Rail(
.padding(horizontal = 9.dp, vertical = 28.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
fun item(tab: Tab) = RailItem(
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
private fun Logo(progress: State<Float>, modifier: Modifier = Modifier) {
Row(modifier.height(32.dp), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(10.dp)) {
Box(
Modifier
.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,
)
Row(modifier, verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) {
OwlMark()
Wordmark(Modifier.graphicsLayer { alpha = progress.value })
}
}

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.theme
package ru.stenfredd.sleepyowl.ui.theme
import androidx.compose.runtime.Composable
import androidx.tv.material3.MaterialTheme

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.ui.theme
package ru.stenfredd.sleepyowl.ui.theme
import androidx.compose.runtime.Immutable
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.unit.em
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,

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

View File

@@ -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>

View 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>

View File

@@ -1,4 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="background">#0A0B10</color>
<!-- Фон логотипа: под совой в иконке приложения. -->
<color name="ic_launcher_background">#050927</color>
</resources>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Рабочее название, пока нет настоящего. Меняется здесь и в логотипе (drawable/banner.xml, Shell.Logo). -->
<string name="app_name">Movies</string>
<!-- Название приложения. Логотип — design/logo/sleepyowl.png, картинки из него делает tools/logo/make_assets.py. -->
<string name="app_name">SleepyOwl</string>
</resources>

View File

@@ -3,7 +3,7 @@
<!-- Фон приложения — фон окна: без белой вспышки до первого кадра Compose, и экраны не рисуют свой фон.
Сплошной цвет: 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:colorBackground">@color/background</item>
</style>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@ plugins {
// Generates the app's baseline profile on a connected device (the test TV, logged in):
// ./gradlew :app:generateReleaseBaselineProfile
android {
namespace = "ru.stenfredd.movies.baselineprofile"
namespace = "ru.stenfredd.sleepyowl.baselineprofile"
compileSdk = 37
defaultConfig {
minSdk = 28

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.baselineprofile
package ru.stenfredd.sleepyowl.baselineprofile
import androidx.benchmark.macro.junit4.BaselineProfileRule
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -147,7 +147,7 @@ class BaselineProfileGenerator {
}
private companion object {
const val PACKAGE = "ru.stenfredd.movies"
const val PACKAGE = "ru.stenfredd.sleepyowl"
const val ROWS = 6
const val LIBRARY_ROWS = 14
}

View File

@@ -6,7 +6,7 @@ plugins {
}
android {
namespace = "ru.stenfredd.movies.core.data"
namespace = "ru.stenfredd.sleepyowl.core.data"
compileSdk = 37
defaultConfig { minSdk = 26 }
compileOptions {

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.core.data
package ru.stenfredd.sleepyowl.core.data
import android.content.Context
import android.os.SystemClock
@@ -18,11 +18,11 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import ru.stenfredd.movies.core.data.model.ItemQuery
import ru.stenfredd.movies.core.data.model.ItemSummary
import ru.stenfredd.movies.core.data.model.LibraryView
import ru.stenfredd.movies.core.data.model.itemKinds
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
import ru.stenfredd.sleepyowl.core.data.model.ItemQuery
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
import ru.stenfredd.sleepyowl.core.data.model.itemKinds
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
import timber.log.Timber
import java.io.File
import java.util.concurrent.ConcurrentHashMap

View File

@@ -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.model.api.ImageType
import ru.stenfredd.movies.core.data.model.ImageKind
import ru.stenfredd.movies.core.data.model.ImageRef
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
import ru.stenfredd.sleepyowl.core.data.model.ImageKind
import ru.stenfredd.sleepyowl.core.data.model.ImageRef
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
import javax.inject.Inject
import javax.inject.Singleton

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.core.data
package ru.stenfredd.sleepyowl.core.data
import kotlinx.coroutines.async
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.ItemSortBy
import org.jellyfin.sdk.model.api.SortOrder
import ru.stenfredd.movies.core.data.SessionCache.Kind
import ru.stenfredd.movies.core.data.model.ItemDetails
import ru.stenfredd.movies.core.data.model.ItemKind
import ru.stenfredd.movies.core.data.model.ItemQuery
import ru.stenfredd.movies.core.data.model.ItemSort
import ru.stenfredd.movies.core.data.model.ItemSummary
import ru.stenfredd.movies.core.data.model.LibraryType
import ru.stenfredd.movies.core.data.model.LibraryView
import ru.stenfredd.movies.core.data.model.MediaSegment
import ru.stenfredd.movies.core.data.model.Page
import ru.stenfredd.movies.core.data.model.Person
import ru.stenfredd.movies.core.data.model.itemKinds
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
import ru.stenfredd.sleepyowl.core.data.SessionCache.Kind
import ru.stenfredd.sleepyowl.core.data.model.ItemDetails
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
import ru.stenfredd.sleepyowl.core.data.model.ItemQuery
import ru.stenfredd.sleepyowl.core.data.model.ItemSort
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
import ru.stenfredd.sleepyowl.core.data.model.LibraryType
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
import ru.stenfredd.sleepyowl.core.data.model.MediaSegment
import ru.stenfredd.sleepyowl.core.data.model.Page
import ru.stenfredd.sleepyowl.core.data.model.Person
import ru.stenfredd.sleepyowl.core.data.model.itemKinds
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
import java.util.UUID
import javax.inject.Inject
import javax.inject.Singleton

View File

@@ -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.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.MediaStreamType
import org.jellyfin.sdk.model.api.VideoRangeType
import ru.stenfredd.movies.core.data.model.AudioTrack
import ru.stenfredd.movies.core.data.model.Chapter
import ru.stenfredd.movies.core.data.model.ImageKind
import ru.stenfredd.movies.core.data.model.ImageRef
import ru.stenfredd.movies.core.data.model.ItemDetails
import ru.stenfredd.movies.core.data.model.ItemKind
import ru.stenfredd.movies.core.data.model.ItemSummary
import ru.stenfredd.movies.core.data.model.LibraryType
import ru.stenfredd.movies.core.data.model.LibraryView
import ru.stenfredd.movies.core.data.model.MediaInfo
import ru.stenfredd.movies.core.data.model.MediaSegment
import ru.stenfredd.movies.core.data.model.Person
import ru.stenfredd.movies.core.data.model.PersonKind
import ru.stenfredd.movies.core.data.model.SegmentKind
import ru.stenfredd.movies.core.data.model.SubtitleTrack
import ru.stenfredd.movies.core.data.model.UserState
import ru.stenfredd.movies.core.data.model.VideoRange
import ru.stenfredd.movies.core.data.model.VideoTrack
import ru.stenfredd.sleepyowl.core.data.model.AudioTrack
import ru.stenfredd.sleepyowl.core.data.model.Chapter
import ru.stenfredd.sleepyowl.core.data.model.ImageKind
import ru.stenfredd.sleepyowl.core.data.model.ImageRef
import ru.stenfredd.sleepyowl.core.data.model.ItemDetails
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
import ru.stenfredd.sleepyowl.core.data.model.LibraryType
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
import ru.stenfredd.sleepyowl.core.data.model.MediaInfo
import ru.stenfredd.sleepyowl.core.data.model.MediaSegment
import ru.stenfredd.sleepyowl.core.data.model.Person
import ru.stenfredd.sleepyowl.core.data.model.PersonKind
import ru.stenfredd.sleepyowl.core.data.model.SegmentKind
import ru.stenfredd.sleepyowl.core.data.model.SubtitleTrack
import ru.stenfredd.sleepyowl.core.data.model.UserState
import ru.stenfredd.sleepyowl.core.data.model.VideoRange
import ru.stenfredd.sleepyowl.core.data.model.VideoTrack
import java.time.LocalDateTime
import java.time.ZoneId
import java.util.UUID

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.core.data
package ru.stenfredd.sleepyowl.core.data
import android.content.Context
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.map
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.Singleton

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.core.data
package ru.stenfredd.sleepyowl.core.data
import android.os.SystemClock
import kotlinx.coroutines.CancellationException
@@ -15,7 +15,7 @@ import kotlinx.coroutines.flow.distinctUntilChangedBy
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
import timber.log.Timber
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject

View File

@@ -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.userApi
import org.jellyfin.sdk.model.api.SubtitlePlaybackMode
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.Singleton

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.core.data
package ru.stenfredd.sleepyowl.core.data
import kotlinx.coroutines.async
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.userDataApi
import org.jellyfin.sdk.model.api.MediaType
import ru.stenfredd.movies.core.data.SessionCache.Kind
import ru.stenfredd.movies.core.data.model.ItemKind
import ru.stenfredd.movies.core.data.model.ItemQuery
import ru.stenfredd.movies.core.data.model.ItemSort
import ru.stenfredd.movies.core.data.model.ItemSummary
import ru.stenfredd.movies.core.data.model.LibraryView
import ru.stenfredd.movies.core.data.model.Page
import ru.stenfredd.movies.core.data.model.itemKinds
import ru.stenfredd.movies.core.jellyfin.JellyfinSession
import ru.stenfredd.sleepyowl.core.data.SessionCache.Kind
import ru.stenfredd.sleepyowl.core.data.model.ItemKind
import ru.stenfredd.sleepyowl.core.data.model.ItemQuery
import ru.stenfredd.sleepyowl.core.data.model.ItemSort
import ru.stenfredd.sleepyowl.core.data.model.ItemSummary
import ru.stenfredd.sleepyowl.core.data.model.LibraryView
import ru.stenfredd.sleepyowl.core.data.model.Page
import ru.stenfredd.sleepyowl.core.data.model.itemKinds
import ru.stenfredd.sleepyowl.core.jellyfin.JellyfinSession
import java.util.UUID
import javax.inject.Inject
import javax.inject.Singleton

View File

@@ -1,6 +1,6 @@
@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.UseSerializers

View File

@@ -5,7 +5,7 @@ plugins {
}
android {
namespace = "ru.stenfredd.movies.core.jellyfin"
namespace = "ru.stenfredd.sleepyowl.core.jellyfin"
compileSdk = 37
defaultConfig { minSdk = 26 }
compileOptions {

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.core.jellyfin
package ru.stenfredd.sleepyowl.core.jellyfin
import android.content.Context
import androidx.datastore.preferences.core.Preferences

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.core.jellyfin
package ru.stenfredd.sleepyowl.core.jellyfin
import dagger.Module
import dagger.Provides

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.core.jellyfin
package ru.stenfredd.sleepyowl.core.jellyfin
import android.content.Context
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 companion object {
const val CLIENT_NAME = "Movies"
const val CLIENT_NAME = "SleepyOwl"
const val CLIENT_VERSION = "0.1.0"
const val LOCAL_RECHECK_MS = 10 * 60_000L
const val REVOKE_TIMEOUT_MS = 3_000L

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.core.jellyfin
package ru.stenfredd.sleepyowl.core.jellyfin
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.core.jellyfin
package ru.stenfredd.sleepyowl.core.jellyfin
import android.os.SystemClock
import kotlinx.coroutines.Dispatchers

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.core.jellyfin
package ru.stenfredd.sleepyowl.core.jellyfin
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull

BIN
design/logo/sleepyowl.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

@@ -3,7 +3,7 @@ plugins {
}
android {
namespace = "ru.stenfredd.movies.playback.api"
namespace = "ru.stenfredd.sleepyowl.playback.api"
compileSdk = 37
defaultConfig { minSdk = 26 }
compileOptions {

View File

@@ -1,4 +1,4 @@
package ru.stenfredd.movies.playback.api
package ru.stenfredd.sleepyowl.playback.api
import android.media.AudioFormat

Some files were not shown because too many files have changed in this diff Show More