init projects
@@ -0,0 +1,4 @@
|
||||
keystore.properties
|
||||
release.keystore
|
||||
*.keystore
|
||||
build
|
||||
@@ -0,0 +1,37 @@
|
||||
plugins {
|
||||
alias(libs.plugins.convention.android.app)
|
||||
alias(libs.plugins.convention.compose)
|
||||
alias(libs.plugins.convention.koin)
|
||||
alias(libs.plugins.convention.ktor.client)
|
||||
}
|
||||
|
||||
android {
|
||||
buildFeatures { buildConfig = true }
|
||||
namespace = "ru.shadowsparky.videobox.multiplatform"
|
||||
defaultConfig {
|
||||
applicationId = namespace
|
||||
minSdk = libs.versions.proj.min.get().toInt()
|
||||
targetSdk = libs.versions.proj.target.get().toInt()
|
||||
versionCode = 35
|
||||
versionName = "1.18"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(libs.activity.compose)
|
||||
implementation(libs.material)
|
||||
implementation(project(":apps:vbox:client:shared"))
|
||||
implementation(project(":apps:vbox:common"))
|
||||
|
||||
implementation(project(":libs:base"))
|
||||
implementation(project(":libs:ui"))
|
||||
implementation(project(":libs:http-client"))
|
||||
implementation(project(":libs:video-player"))
|
||||
debugImplementation(libs.ui.tooling)
|
||||
compileOnly(libs.ui.tooling.preview.android)
|
||||
testImplementation(libs.koin.test)
|
||||
testImplementation(libs.mockk)
|
||||
testImplementation(kotlin("test-junit"))
|
||||
androidTestImplementation(libs.junit)
|
||||
androidTestImplementation(libs.runner)
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
-dontwarn org.bouncycastle.jsse.BCSSLParameters
|
||||
-dontwarn org.bouncycastle.jsse.BCSSLSocket
|
||||
-dontwarn org.bouncycastle.jsse.provider.BouncyCastleJsseProvider
|
||||
-dontwarn org.conscrypt.Conscrypt$Version
|
||||
-dontwarn org.conscrypt.Conscrypt
|
||||
-dontwarn org.conscrypt.ConscryptHostnameVerifier
|
||||
-dontwarn org.openjsse.javax.net.ssl.SSLParameters
|
||||
-dontwarn org.openjsse.javax.net.ssl.SSLSocket
|
||||
-dontwarn org.openjsse.net.ssl.OpenJSSE
|
||||
-dontwarn org.slf4j.impl.StaticLoggerBinder
|
||||
-dontwarn java.lang.management.ManagementFactory
|
||||
-dontwarn java.lang.management.RuntimeMXBean
|
||||
-dontwarn kotlinx.atomicfu.**
|
||||
-dontwarn io.netty.**
|
||||
-dontwarn com.typesafe.**
|
||||
-dontwarn org.slf4j.**
|
||||
-dontwarn com.sun.nio.file.SensitivityWatchEventModifier
|
||||
-dontwarn org.xmlpull.v1.**
|
||||
-dontwarn javax.xml.namespace.**
|
||||
-dontwarn androidx.test.platform.app.InstrumentationRegistry
|
||||
-dontwarn androidx.window.extensions.WindowExtensions
|
||||
-dontwarn androidx.window.extensions.WindowExtensionsProvider
|
||||
-dontwarn androidx.window.extensions.area.ExtensionWindowAreaPresentation
|
||||
-dontwarn androidx.window.extensions.core.util.function.Consumer
|
||||
-dontwarn androidx.window.extensions.core.util.function.Function
|
||||
-dontwarn androidx.window.extensions.core.util.function.Predicate
|
||||
-dontwarn androidx.window.extensions.layout.DisplayFeature
|
||||
-dontwarn androidx.window.extensions.layout.FoldingFeature
|
||||
-dontwarn androidx.window.extensions.layout.WindowLayoutComponent
|
||||
-dontwarn androidx.window.extensions.layout.WindowLayoutInfo
|
||||
-dontwarn androidx.window.sidecar.SidecarDeviceState
|
||||
-dontwarn androidx.window.sidecar.SidecarDisplayFeature
|
||||
-dontwarn androidx.window.sidecar.SidecarInterface$SidecarCallback
|
||||
-dontwarn androidx.window.sidecar.SidecarInterface
|
||||
-dontwarn androidx.window.sidecar.SidecarProvider
|
||||
-dontwarn androidx.window.sidecar.SidecarWindowLayoutInfo
|
||||
|
||||
-keep class ru.shadowsparky.vbox.shared.domain.RemoteEvent { *; }
|
||||
-keep class ru.shadowsparky.vbox.shared.domain.RemoteEvent$OnSaved { *; }
|
||||
-keep class ru.shadowsparky.vbox.shared.domain.RemoteEvent$OnRecent { *; }
|
||||
-keep class ru.shadowsparky.vbox.shared.domain.RemoteEvent$OnSearch { *; }
|
||||
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<uses-feature
|
||||
android:name="android.software.leanback"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.touchscreen"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
android:banner="@mipmap/ic_banner"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Videobox"
|
||||
tools:ignore="UnusedAttribute">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="screenSize|screenLayout|orientation|smallestScreenSize"
|
||||
android:exported="true"
|
||||
android:supportsPictureInPicture="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="ru.shadowsparky.vbox.action.OPEN_SAVED_MOVIES" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter android:autoVerify="true">
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:scheme="https"
|
||||
android:host="box.shadowsparky.ru" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
After Width: | Height: | Size: 7.7 KiB |
@@ -0,0 +1,34 @@
|
||||
package ru.shadowsparky.videobox.multiplatform
|
||||
|
||||
import android.app.Application
|
||||
import android.os.StrictMode
|
||||
import com.google.android.material.color.DynamicColors
|
||||
import org.koin.android.ext.koin.androidContext
|
||||
import org.koin.core.annotation.KoinApplication
|
||||
import org.koin.core.annotation.Module
|
||||
import org.koin.core.annotation.Single
|
||||
import org.koin.plugin.module.dsl.startKoin
|
||||
import ru.shadowsparky.domain.AppConfig
|
||||
|
||||
@KoinApplication
|
||||
object VBox
|
||||
|
||||
class App : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
DynamicColors.applyToActivitiesIfAvailable(this)
|
||||
startKoin<VBox> { androidContext(this@App) }
|
||||
if (BuildConfig.DEBUG) StrictMode.enableDefaults()
|
||||
}
|
||||
}
|
||||
|
||||
@Module
|
||||
class AppModule {
|
||||
|
||||
@Single
|
||||
fun provideAppConfig(): AppConfig {
|
||||
return object : AppConfig {
|
||||
override fun isDebug(): Boolean = BuildConfig.DEBUG
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package ru.shadowsparky.videobox.multiplatform
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.SystemBarStyle
|
||||
import androidx.activity.compose.setContent
|
||||
import androidx.activity.enableEdgeToEdge
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.arkivanov.decompose.retainedComponent
|
||||
import kotlinx.coroutines.launch
|
||||
import ru.shadowsparky.koin
|
||||
import ru.shadowsparky.vbox.shared.presentation.Nav
|
||||
import ru.shadowsparky.vbox.shared.presentation.RootComponent
|
||||
import ru.shadowsparky.vbox.shared.presentation.RootFactory
|
||||
import ru.shadowsparky.vbox.shared.presentation.UrlRoutes
|
||||
import ru.shadowsparky.vbox.shared.presentation.nav.Route
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
private lateinit var root: RootComponent
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
edgeToEdge(false)
|
||||
super.onCreate(savedInstanceState)
|
||||
root = retainedComponent { componentContext ->
|
||||
val routeFromIntent = obtainRouteOrNull(intent?.data)
|
||||
val route = if (routeFromIntent == null) {
|
||||
listOf(Route.default)
|
||||
} else {
|
||||
listOf(Route.default, routeFromIntent)
|
||||
}
|
||||
koin.get<RootFactory>().create(componentContext, route)
|
||||
}
|
||||
if (openSavedIfNeeded(intent) || openUrlIfNeeded(intent.data)) {
|
||||
intent = Intent(intent)
|
||||
.setData(null)
|
||||
.setAction(null)
|
||||
}
|
||||
setContent {
|
||||
Nav(rootComponent = root)
|
||||
edgeToEdge(isSystemInDarkTheme())
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
root.onFinish.collect {
|
||||
finishAndRemoveTask()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun edgeToEdge(isDarkTheme: Boolean) {
|
||||
enableEdgeToEdge(
|
||||
statusBarStyle = SystemBarStyle.auto(
|
||||
Color.TRANSPARENT,
|
||||
Color.TRANSPARENT,
|
||||
{ isDarkTheme }
|
||||
),
|
||||
navigationBarStyle = SystemBarStyle.light(
|
||||
Color.TRANSPARENT,
|
||||
Color.TRANSPARENT
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
private fun openSavedIfNeeded(intent: Intent?): Boolean {
|
||||
if (intent?.action == "ru.shadowsparky.vbox.action.OPEN_SAVED_MOVIES") {
|
||||
root.nav(Route.Bookmark(), true)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun onNewIntent(intent: Intent) {
|
||||
super.onNewIntent(intent)
|
||||
if (!openSavedIfNeeded(intent)) {
|
||||
val uri = intent.data ?: return
|
||||
val route = obtainRouteOrNull(uri)
|
||||
if (route != null) {
|
||||
root.nav(route, true)
|
||||
} else {
|
||||
openUrlIfNeeded(uri)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun openUrlIfNeeded(uri: Uri?): Boolean {
|
||||
uri ?: return false
|
||||
if (uri.path?.startsWith("/video/") == true) {
|
||||
root.nav(Route.Overview.Player(url = uri.toString()))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun obtainRouteOrNull(uri: Uri?): Route? {
|
||||
uri ?: return null
|
||||
return UrlRoutes.parseUrl(uri.toString(), basePath = "/")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package ru.shadowsparky.videobox.multiplatform.preview
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import ru.shadowsparky.ui.components.TextPreference
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun SwitchPreferencePreview() {
|
||||
TextPreference(Modifier, "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW", "summary")
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
@file:OptIn(ExperimentalMaterial3Api::class)
|
||||
|
||||
package ru.shadowsparky.videobox.multiplatform.preview
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ru.shadowsparky.vbox.shared.presentation.search.AppBarWithSearch
|
||||
import ru.shadowsparky.vbox.shared.presentation.search.OldSearchInfo
|
||||
import ru.shadowsparky.vbox.shared.presentation.search.SearchAppBar
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun AppBarWithSearchPreview() {
|
||||
AppBarWithSearch(
|
||||
title = "TitleWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
|
||||
isDefault = false,
|
||||
onBack = {}
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun AppBarWithSearchWithBackPreview() {
|
||||
AppBarWithSearch(
|
||||
title = "TitleWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
|
||||
onBack = {}
|
||||
)
|
||||
}
|
||||
|
||||
@SuppressLint("RememberInComposition")
|
||||
@Preview
|
||||
@Composable
|
||||
fun InternalAppBarPreview() {
|
||||
SearchAppBar(
|
||||
TextFieldValue(""),
|
||||
FocusRequester(),
|
||||
{},
|
||||
{}
|
||||
)
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun SearchInfoPreview() {
|
||||
OldSearchInfo(
|
||||
modifier = Modifier,
|
||||
info = listOf(
|
||||
"Почему дора дура?",
|
||||
"клиинка",
|
||||
"симпсоны",
|
||||
"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"
|
||||
),
|
||||
PaddingValues(0.dp),
|
||||
onClick = {},
|
||||
onDeleteRequested = {}
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package ru.shadowsparky.videobox.multiplatform.preview
|
||||
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import ru.shadowsparky.vbox.shared.domain.model.Season
|
||||
import ru.shadowsparky.vbox.shared.presentation.overview.season.SeasonsInfo
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun SeasonsInfoPreview() {
|
||||
SeasonsInfo(
|
||||
paddingValues = PaddingValues(0.dp),
|
||||
seasons = listOf(Season(listOf(), 23, "Lalalal"))
|
||||
) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package ru.shadowsparky.videobox.multiplatform.preview
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import ru.shadowsparky.vbox.shared.presentation.list.ErrorAndRetry
|
||||
import ru.shadowsparky.vbox.shared.presentation.list.Loading
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun ErrorPreview() {
|
||||
ErrorAndRetry(
|
||||
errorMsg = "Неизвестная ошибка"
|
||||
) {}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun LoadingPreview() {
|
||||
Loading()
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14zM7.33,12.5l2.14,-1.53 2.14,1.53 -0.83,-2.46 2.15,-1.5h-2.62L9.47,6l-0.84,2.54L6,8.54l2.14,1.49z" />
|
||||
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM12,14.5v-9l6,4.5 -6,4.5z" />
|
||||
</vector>
|
||||
@@ -0,0 +1,16 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:tint="#000000"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group
|
||||
android:scaleX="0.38866666"
|
||||
android:scaleY="0.38866666"
|
||||
android:translateX="7.336"
|
||||
android:translateY="7.336">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM12,14.5v-9l6,4.5 -6,4.5z" />
|
||||
</group>
|
||||
</vector>
|
||||
@@ -0,0 +1,16 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:tint="#000000"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<group
|
||||
android:scaleX="0.38866666"
|
||||
android:scaleY="0.38866666"
|
||||
android:translateX="7.336"
|
||||
android:translateY="7.336">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M4,6L2,6v14c0,1.1 0.9,2 2,2h14v-2L4,20L4,6zM20,2L8,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM12,14.5v-9l6,4.5 -6,4.5z" />
|
||||
</group>
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,6.5c3.79,0 7.17,2.13 8.82,5.5 -1.65,3.37 -5.02,5.5 -8.82,5.5S4.83,15.37 3.18,12C4.83,8.63 8.21,6.5 12,6.5m0,-2C7,4.5 2.73,7.61 1,12c1.73,4.39 6,7.5 11,7.5s9.27,-3.11 11,-7.5c-1.73,-4.39 -6,-7.5 -11,-7.5zM12,9.5c1.38,0 2.5,1.12 2.5,2.5s-1.12,2.5 -2.5,2.5 -2.5,-1.12 -2.5,-2.5 1.12,-2.5 2.5,-2.5m0,-2c-2.48,0 -4.5,2.02 -4.5,4.5s2.02,4.5 4.5,4.5 4.5,-2.02 4.5,-4.5 -2.02,-4.5 -4.5,-4.5z" />
|
||||
</vector>
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.fragment.app.FragmentContainerView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/main_fragment_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".presentation.MainActivity">
|
||||
|
||||
</androidx.fragment.app.FragmentContainerView>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_monochrome" />
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_monochrome" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 867 B |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 10 KiB |
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_banner_background">#FFFFFF</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#FFFFFF</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">Videobox</string>
|
||||
<string name="saved_movies">Сохранённые фильмы</string>
|
||||
<string name="saved_movies_long">Просмотр списка ранее сохранённых фильмов</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
|
||||
<style name="BaseTheme" parent="@style/Theme.Material3.DynamicColors.DayNight.NoActionBar" />
|
||||
|
||||
<style name="Theme.Videobox" parent="BaseTheme" />
|
||||
</resources>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<shortcut
|
||||
android:enabled="true"
|
||||
android:icon="@drawable/baseline_saved_search_24"
|
||||
android:shortcutId="saved_movies"
|
||||
android:shortcutLongLabel="@string/saved_movies_long"
|
||||
android:shortcutShortLabel="@string/saved_movies">
|
||||
<intent
|
||||
android:action="ru.shadowsparky.vbox.action.OPEN_SAVED_MOVIES"
|
||||
android:targetClass="ru.shadowsparky.videobox.multiplatform.MainActivity"
|
||||
android:targetPackage="ru.shadowsparky.videobox.multiplatform" />
|
||||
</shortcut>
|
||||
</shortcuts>
|
||||
@@ -0,0 +1,2 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shortcuts></shortcuts>
|
||||