Compare commits
3 Commits
jetpack/to
...
v0.8.3
Author | SHA1 | Date | |
---|---|---|---|
|
3f461792e5 | ||
|
4738c317cc | ||
|
3997b38120 |
@@ -8,9 +8,9 @@ android {
|
|||||||
applicationId "org.libre.agosto.p2play"
|
applicationId "org.libre.agosto.p2play"
|
||||||
compileSdk 35
|
compileSdk 35
|
||||||
minSdkVersion 26
|
minSdkVersion 26
|
||||||
targetSdkVersion 33
|
targetSdkVersion 32
|
||||||
versionCode 15
|
versionCode 14
|
||||||
versionName "0.8.4"
|
versionName "0.8.3"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,6 @@ android {
|
|||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
viewBinding = true
|
viewBinding = true
|
||||||
compose true
|
|
||||||
}
|
}
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_18
|
sourceCompatibility JavaVersion.VERSION_18
|
||||||
@@ -36,29 +35,19 @@ android {
|
|||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = '18'
|
jvmTarget = '18'
|
||||||
}
|
}
|
||||||
composeOptions {
|
|
||||||
kotlinCompilerExtensionVersion '1.5.4'
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation 'com.squareup.picasso:picasso:2.71828'
|
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||||
implementation 'androidx.appcompat:appcompat:1.7.0'
|
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
implementation 'com.android.support:appcompat-v7:28.0.0'
|
implementation 'com.android.support:appcompat-v7:28.0.0'
|
||||||
implementation 'com.google.android.material:material:1.12.0'
|
implementation 'com.google.android.material:material:1.12.0'
|
||||||
implementation 'androidx.preference:preference-ktx:1.2.1'
|
implementation 'androidx.preference:preference-ktx:1.2.1'
|
||||||
implementation 'androidx.activity:activity-ktx:1.10.0'
|
implementation 'androidx.activity:activity:1.8.0'
|
||||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.8.7'
|
|
||||||
implementation 'androidx.activity:activity-compose:1.10.0'
|
|
||||||
implementation platform('androidx.compose:compose-bom:2025.01.01')
|
|
||||||
implementation 'androidx.compose.ui:ui'
|
|
||||||
implementation 'androidx.compose.ui:ui-graphics'
|
|
||||||
implementation 'androidx.compose.ui:ui-tooling-preview'
|
|
||||||
implementation 'androidx.navigation:navigation-compose:2.8.6'
|
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test:runner:1.5.2'
|
androidTestImplementation 'androidx.test:runner:1.5.2'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
@@ -67,20 +56,5 @@ dependencies {
|
|||||||
implementation 'androidx.media3:media3-ui:1.3.1'
|
implementation 'androidx.media3:media3-ui:1.3.1'
|
||||||
implementation 'androidx.media3:media3-exoplayer-hls:1.3.1'
|
implementation 'androidx.media3:media3-exoplayer-hls:1.3.1'
|
||||||
implementation "androidx.media3:media3-session:1.3.1"
|
implementation "androidx.media3:media3-session:1.3.1"
|
||||||
implementation 'com.google.code.gson:gson:2.10.1'
|
implementation 'com.google.code.gson:gson:2.8.8'
|
||||||
implementation "androidx.compose.material3:material3:1.3.1"
|
|
||||||
androidTestImplementation platform('androidx.compose:compose-bom:2025.01.01')
|
|
||||||
androidTestImplementation 'androidx.compose.ui:ui-test-junit4'
|
|
||||||
debugImplementation 'androidx.compose.ui:ui-tooling'
|
|
||||||
debugImplementation 'androidx.compose.ui:ui-test-manifest'
|
|
||||||
implementation "androidx.compose.runtime:runtime"
|
|
||||||
implementation "androidx.compose.ui:ui"
|
|
||||||
implementation "androidx.compose.foundation:foundation"
|
|
||||||
implementation "androidx.compose.foundation:foundation-layout"
|
|
||||||
implementation "androidx.compose.material3:material3"
|
|
||||||
implementation "androidx.compose.runtime:runtime-livedata"
|
|
||||||
implementation "androidx.compose.ui:ui-tooling"
|
|
||||||
implementation "androidx.constraintlayout:constraintlayout-compose:1.1.0"
|
|
||||||
implementation "io.coil-kt.coil3:coil-compose:3.0.4"
|
|
||||||
implementation "io.coil-kt.coil3:coil-network-okhttp:3.0.4"
|
|
||||||
}
|
}
|
||||||
|
@@ -13,10 +13,7 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.P2play">
|
android:theme="@style/Theme.P2play">
|
||||||
<activity
|
|
||||||
android:name=".activities.MainActivity"
|
|
||||||
android:exported="false"
|
|
||||||
android:theme="@style/Theme.P2play" />
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".AccountActivity"
|
android:name=".AccountActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
@@ -68,11 +65,6 @@
|
|||||||
android:name=".AboutActivity"
|
android:name=".AboutActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|
||||||
<activity
|
|
||||||
android:name=".activities.HostActivityV2"
|
|
||||||
android:exported="true"
|
|
||||||
android:theme="@style/Theme.P2play" />
|
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".services.PlaybackService"
|
android:name=".services.PlaybackService"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
@@ -13,7 +13,6 @@ object ManagerSingleton {
|
|||||||
var videosCount: Int = 0
|
var videosCount: Int = 0
|
||||||
lateinit var settings: SharedPreferences
|
lateinit var settings: SharedPreferences
|
||||||
lateinit var db: Database
|
lateinit var db: Database
|
||||||
|
|
||||||
fun toast(text: String?, context: Context) {
|
fun toast(text: String?, context: Context) {
|
||||||
android.widget.Toast.makeText(context, text, android.widget.Toast.LENGTH_SHORT).show()
|
android.widget.Toast.makeText(context, text, android.widget.Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
@@ -22,8 +21,6 @@ object ManagerSingleton {
|
|||||||
db.logout()
|
db.logout()
|
||||||
user = UserModel()
|
user = UserModel()
|
||||||
token = TokenModel()
|
token = TokenModel()
|
||||||
|
|
||||||
// TODO: Close the session in the user instance
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reloadSettings() {
|
fun reloadSettings() {
|
||||||
@@ -39,8 +36,4 @@ object ManagerSingleton {
|
|||||||
nfsw = settings.getBoolean("show_nsfw", false)
|
nfsw = settings.getBoolean("show_nsfw", false)
|
||||||
videosCount = settings.getString("videos_count", "15")!!.toInt()
|
videosCount = settings.getString("videos_count", "15")!!.toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isLogged (): Boolean {
|
|
||||||
return token.token !== ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -140,10 +140,7 @@ class ReproductorActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AsyncTask.execute {
|
AsyncTask.execute {
|
||||||
videoPlayback = if (ManagerSingleton.token.status == 1)
|
videoPlayback = this.clientVideo.getVideo(this.video.uuid, ManagerSingleton.token.token)
|
||||||
this.clientVideo.getVideo(this.video.uuid, ManagerSingleton.token.token)
|
|
||||||
else
|
|
||||||
this.clientVideo.getVideo(this.video.uuid)
|
|
||||||
// TODO: Make this configurable
|
// TODO: Make this configurable
|
||||||
// val bufferSize = 1024 * 1024 // 1mb
|
// val bufferSize = 1024 * 1024 // 1mb
|
||||||
// val allocator = DefaultAllocator(true, bufferSize)
|
// val allocator = DefaultAllocator(true, bufferSize)
|
||||||
|
@@ -2,10 +2,13 @@ package org.libre.agosto.p2play
|
|||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import android.os.AsyncTask
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import android.util.Log
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
import org.libre.agosto.p2play.activities.MainActivity
|
|
||||||
import org.libre.agosto.p2play.ajax.Auth
|
import org.libre.agosto.p2play.ajax.Auth
|
||||||
import org.libre.agosto.p2play.helpers.TaskManager
|
import org.libre.agosto.p2play.helpers.TaskManager
|
||||||
import org.libre.agosto.p2play.models.TokenModel
|
import org.libre.agosto.p2play.models.TokenModel
|
||||||
|
@@ -1,69 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.activities
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.compose.setContent
|
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TextField
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.constraintlayout.compose.ChainStyle
|
|
||||||
import androidx.constraintlayout.compose.ConstraintLayout
|
|
||||||
import org.libre.agosto.p2play.MainActivity
|
|
||||||
import org.libre.agosto.p2play.activities.ui.theme.P2playTheme
|
|
||||||
|
|
||||||
class HostActivityV2: ComponentActivity() {
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
enableEdgeToEdge()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
setContent {
|
|
||||||
P2playTheme {
|
|
||||||
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
|
|
||||||
ConstraintLayout(modifier = Modifier.padding(innerPadding).fillMaxSize()) {
|
|
||||||
val (textLabel, emailField, passwordField) = createRefs()
|
|
||||||
Text("Iniciar session", modifier = Modifier.constrainAs(textLabel) {
|
|
||||||
top.linkTo(parent.top)
|
|
||||||
start.linkTo(parent.start)
|
|
||||||
end.linkTo(parent.end)
|
|
||||||
bottom.linkTo(emailField.top)
|
|
||||||
})
|
|
||||||
TextField("", {}, label = { Text("Email") }, modifier = Modifier.padding(10.dp).constrainAs(emailField) {
|
|
||||||
top.linkTo(textLabel.bottom)
|
|
||||||
start.linkTo(parent.start)
|
|
||||||
end.linkTo(parent.end)
|
|
||||||
bottom.linkTo(passwordField.top)
|
|
||||||
})
|
|
||||||
TextField("", {}, label = { Text("Password") }, modifier = Modifier.constrainAs(passwordField) {
|
|
||||||
top.linkTo(emailField.bottom)
|
|
||||||
start.linkTo(parent.start)
|
|
||||||
end.linkTo(parent.end)
|
|
||||||
bottom.linkTo(parent.bottom)
|
|
||||||
})
|
|
||||||
|
|
||||||
createVerticalChain(textLabel, emailField, passwordField, chainStyle = ChainStyle.Packed)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun instanceSelected () {
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun startApp() {
|
|
||||||
runOnUiThread {
|
|
||||||
val intent = Intent(this, MainActivity::class.java)
|
|
||||||
startActivity(intent)
|
|
||||||
this.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,58 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.activities
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import androidx.activity.ComponentActivity
|
|
||||||
import androidx.activity.compose.setContent
|
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.material3.Scaffold
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
|
||||||
import androidx.navigation.compose.NavHost
|
|
||||||
import androidx.navigation.compose.composable
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import androidx.navigation.compose.rememberNavController
|
|
||||||
import org.libre.agosto.p2play.ui.Routes
|
|
||||||
import org.libre.agosto.p2play.viewModels.VideosViewModel
|
|
||||||
import org.libre.agosto.p2play.activities.ui.theme.P2playTheme
|
|
||||||
import org.libre.agosto.p2play.ui.bars.MainNavigationBar
|
|
||||||
import org.libre.agosto.p2play.ui.bars.MainTopAppBar
|
|
||||||
import org.libre.agosto.p2play.ui.bars.SearchTopBar
|
|
||||||
import org.libre.agosto.p2play.ui.views.SearchView
|
|
||||||
import org.libre.agosto.p2play.ui.views.SubscriptionsView
|
|
||||||
import org.libre.agosto.p2play.ui.views.VideosView
|
|
||||||
import org.libre.agosto.p2play.viewModels.SubscriptionsViewModel
|
|
||||||
|
|
||||||
class MainActivity : ComponentActivity() {
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
enableEdgeToEdge()
|
|
||||||
setContent {
|
|
||||||
val videoViewModel: VideosViewModel = viewModel()
|
|
||||||
val subscriptionsViewModel: SubscriptionsViewModel = viewModel()
|
|
||||||
val navController = rememberNavController()
|
|
||||||
val currentRoute = navController.currentBackStackEntryAsState().value?.destination?.route
|
|
||||||
P2playTheme {
|
|
||||||
Scaffold(
|
|
||||||
modifier = Modifier.fillMaxSize(),
|
|
||||||
topBar = {
|
|
||||||
when(currentRoute) {
|
|
||||||
Routes.Videos.route -> MainTopAppBar(navController)
|
|
||||||
Routes.Search.route -> SearchTopBar()
|
|
||||||
else -> MainTopAppBar(navController)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
bottomBar = { MainNavigationBar(navController) }
|
|
||||||
) { innerPadding ->
|
|
||||||
NavHost(navController, startDestination = Routes.Videos.route, modifier = Modifier.padding(innerPadding)) {
|
|
||||||
composable(Routes.Videos.route) { VideosView(videoViewModel) }
|
|
||||||
composable(Routes.Subscriptions.route) { SubscriptionsView(subscriptionsViewModel) }
|
|
||||||
composable(Routes.Search.route) { SearchView() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,226 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.activities.ui.theme
|
|
||||||
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
|
|
||||||
val primaryLight = Color(0xFF8A5022)
|
|
||||||
val onPrimaryLight = Color(0xFFFFFFFF)
|
|
||||||
val primaryContainerLight = Color(0xFFFFDCC6)
|
|
||||||
val onPrimaryContainerLight = Color(0xFF6D390C)
|
|
||||||
val secondaryLight = Color(0xFF755845)
|
|
||||||
val onSecondaryLight = Color(0xFFFFFFFF)
|
|
||||||
val secondaryContainerLight = Color(0xFFFFDCC6)
|
|
||||||
val onSecondaryContainerLight = Color(0xFF5B412F)
|
|
||||||
val tertiaryLight = Color(0xFF5F6135)
|
|
||||||
val onTertiaryLight = Color(0xFFFFFFFF)
|
|
||||||
val tertiaryContainerLight = Color(0xFFE4E6AE)
|
|
||||||
val onTertiaryContainerLight = Color(0xFF47491F)
|
|
||||||
val errorLight = Color(0xFFBA1A1A)
|
|
||||||
val onErrorLight = Color(0xFFFFFFFF)
|
|
||||||
val errorContainerLight = Color(0xFFFFDAD6)
|
|
||||||
val onErrorContainerLight = Color(0xFF93000A)
|
|
||||||
val backgroundLight = Color(0xFFFFF8F5)
|
|
||||||
val onBackgroundLight = Color(0xFF221A15)
|
|
||||||
val surfaceLight = Color(0xFFFFF8F5)
|
|
||||||
val onSurfaceLight = Color(0xFF221A15)
|
|
||||||
val surfaceVariantLight = Color(0xFFF3DED2)
|
|
||||||
val onSurfaceVariantLight = Color(0xFF52443B)
|
|
||||||
val outlineLight = Color(0xFF84746A)
|
|
||||||
val outlineVariantLight = Color(0xFFD7C3B7)
|
|
||||||
val scrimLight = Color(0xFF000000)
|
|
||||||
val inverseSurfaceLight = Color(0xFF382F29)
|
|
||||||
val inverseOnSurfaceLight = Color(0xFFFEEDE4)
|
|
||||||
val inversePrimaryLight = Color(0xFFFFB784)
|
|
||||||
val surfaceDimLight = Color(0xFFE7D7CE)
|
|
||||||
val surfaceBrightLight = Color(0xFFFFF8F5)
|
|
||||||
val surfaceContainerLowestLight = Color(0xFFFFFFFF)
|
|
||||||
val surfaceContainerLowLight = Color(0xFFFFF1EA)
|
|
||||||
val surfaceContainerLight = Color(0xFFFBEBE2)
|
|
||||||
val surfaceContainerHighLight = Color(0xFFF6E5DC)
|
|
||||||
val surfaceContainerHighestLight = Color(0xFFF0DFD6)
|
|
||||||
|
|
||||||
val primaryLightMediumContrast = Color(0xFF582900)
|
|
||||||
val onPrimaryLightMediumContrast = Color(0xFFFFFFFF)
|
|
||||||
val primaryContainerLightMediumContrast = Color(0xFF9C5E2F)
|
|
||||||
val onPrimaryContainerLightMediumContrast = Color(0xFFFFFFFF)
|
|
||||||
val secondaryLightMediumContrast = Color(0xFF493120)
|
|
||||||
val onSecondaryLightMediumContrast = Color(0xFFFFFFFF)
|
|
||||||
val secondaryContainerLightMediumContrast = Color(0xFF856753)
|
|
||||||
val onSecondaryContainerLightMediumContrast = Color(0xFFFFFFFF)
|
|
||||||
val tertiaryLightMediumContrast = Color(0xFF363810)
|
|
||||||
val onTertiaryLightMediumContrast = Color(0xFFFFFFFF)
|
|
||||||
val tertiaryContainerLightMediumContrast = Color(0xFF6E7042)
|
|
||||||
val onTertiaryContainerLightMediumContrast = Color(0xFFFFFFFF)
|
|
||||||
val errorLightMediumContrast = Color(0xFF740006)
|
|
||||||
val onErrorLightMediumContrast = Color(0xFFFFFFFF)
|
|
||||||
val errorContainerLightMediumContrast = Color(0xFFCF2C27)
|
|
||||||
val onErrorContainerLightMediumContrast = Color(0xFFFFFFFF)
|
|
||||||
val backgroundLightMediumContrast = Color(0xFFFFF8F5)
|
|
||||||
val onBackgroundLightMediumContrast = Color(0xFF221A15)
|
|
||||||
val surfaceLightMediumContrast = Color(0xFFFFF8F5)
|
|
||||||
val onSurfaceLightMediumContrast = Color(0xFF17100B)
|
|
||||||
val surfaceVariantLightMediumContrast = Color(0xFFF3DED2)
|
|
||||||
val onSurfaceVariantLightMediumContrast = Color(0xFF40342B)
|
|
||||||
val outlineLightMediumContrast = Color(0xFF5E5047)
|
|
||||||
val outlineVariantLightMediumContrast = Color(0xFF7A6A60)
|
|
||||||
val scrimLightMediumContrast = Color(0xFF000000)
|
|
||||||
val inverseSurfaceLightMediumContrast = Color(0xFF382F29)
|
|
||||||
val inverseOnSurfaceLightMediumContrast = Color(0xFFFEEDE4)
|
|
||||||
val inversePrimaryLightMediumContrast = Color(0xFFFFB784)
|
|
||||||
val surfaceDimLightMediumContrast = Color(0xFFD3C3BB)
|
|
||||||
val surfaceBrightLightMediumContrast = Color(0xFFFFF8F5)
|
|
||||||
val surfaceContainerLowestLightMediumContrast = Color(0xFFFFFFFF)
|
|
||||||
val surfaceContainerLowLightMediumContrast = Color(0xFFFFF1EA)
|
|
||||||
val surfaceContainerLightMediumContrast = Color(0xFFF6E5DC)
|
|
||||||
val surfaceContainerHighLightMediumContrast = Color(0xFFEADAD1)
|
|
||||||
val surfaceContainerHighestLightMediumContrast = Color(0xFFDECFC6)
|
|
||||||
|
|
||||||
val primaryLightHighContrast = Color(0xFF492100)
|
|
||||||
val onPrimaryLightHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val primaryContainerLightHighContrast = Color(0xFF703B0E)
|
|
||||||
val onPrimaryContainerLightHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val secondaryLightHighContrast = Color(0xFF3D2717)
|
|
||||||
val onSecondaryLightHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val secondaryContainerLightHighContrast = Color(0xFF5E4432)
|
|
||||||
val onSecondaryContainerLightHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val tertiaryLightHighContrast = Color(0xFF2C2E07)
|
|
||||||
val onTertiaryLightHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val tertiaryContainerLightHighContrast = Color(0xFF494C22)
|
|
||||||
val onTertiaryContainerLightHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val errorLightHighContrast = Color(0xFF600004)
|
|
||||||
val onErrorLightHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val errorContainerLightHighContrast = Color(0xFF98000A)
|
|
||||||
val onErrorContainerLightHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val backgroundLightHighContrast = Color(0xFFFFF8F5)
|
|
||||||
val onBackgroundLightHighContrast = Color(0xFF221A15)
|
|
||||||
val surfaceLightHighContrast = Color(0xFFFFF8F5)
|
|
||||||
val onSurfaceLightHighContrast = Color(0xFF000000)
|
|
||||||
val surfaceVariantLightHighContrast = Color(0xFFF3DED2)
|
|
||||||
val onSurfaceVariantLightHighContrast = Color(0xFF000000)
|
|
||||||
val outlineLightHighContrast = Color(0xFF362A22)
|
|
||||||
val outlineVariantLightHighContrast = Color(0xFF54463E)
|
|
||||||
val scrimLightHighContrast = Color(0xFF000000)
|
|
||||||
val inverseSurfaceLightHighContrast = Color(0xFF382F29)
|
|
||||||
val inverseOnSurfaceLightHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val inversePrimaryLightHighContrast = Color(0xFFFFB784)
|
|
||||||
val surfaceDimLightHighContrast = Color(0xFFC5B6AD)
|
|
||||||
val surfaceBrightLightHighContrast = Color(0xFFFFF8F5)
|
|
||||||
val surfaceContainerLowestLightHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val surfaceContainerLowLightHighContrast = Color(0xFFFEEDE4)
|
|
||||||
val surfaceContainerLightHighContrast = Color(0xFFF0DFD6)
|
|
||||||
val surfaceContainerHighLightHighContrast = Color(0xFFE1D1C9)
|
|
||||||
val surfaceContainerHighestLightHighContrast = Color(0xFFD3C3BB)
|
|
||||||
|
|
||||||
val primaryDark = Color(0xFFFFB784)
|
|
||||||
val onPrimaryDark = Color(0xFF4F2500)
|
|
||||||
val primaryContainerDark = Color(0xFF6D390C)
|
|
||||||
val onPrimaryContainerDark = Color(0xFFFFDCC6)
|
|
||||||
val secondaryDark = Color(0xFFE4BFA8)
|
|
||||||
val onSecondaryDark = Color(0xFF422B1B)
|
|
||||||
val secondaryContainerDark = Color(0xFF5B412F)
|
|
||||||
val onSecondaryContainerDark = Color(0xFFFFDCC6)
|
|
||||||
val tertiaryDark = Color(0xFFC8CA94)
|
|
||||||
val onTertiaryDark = Color(0xFF30330B)
|
|
||||||
val tertiaryContainerDark = Color(0xFF47491F)
|
|
||||||
val onTertiaryContainerDark = Color(0xFFE4E6AE)
|
|
||||||
val errorDark = Color(0xFFFFB4AB)
|
|
||||||
val onErrorDark = Color(0xFF690005)
|
|
||||||
val errorContainerDark = Color(0xFF93000A)
|
|
||||||
val onErrorContainerDark = Color(0xFFFFDAD6)
|
|
||||||
val backgroundDark = Color(0xFF19120D)
|
|
||||||
val onBackgroundDark = Color(0xFFF0DFD6)
|
|
||||||
val surfaceDark = Color(0xFF19120D)
|
|
||||||
val onSurfaceDark = Color(0xFFF0DFD6)
|
|
||||||
val surfaceVariantDark = Color(0xFF52443B)
|
|
||||||
val onSurfaceVariantDark = Color(0xFFD7C3B7)
|
|
||||||
val outlineDark = Color(0xFF9F8D83)
|
|
||||||
val outlineVariantDark = Color(0xFF52443B)
|
|
||||||
val scrimDark = Color(0xFF000000)
|
|
||||||
val inverseSurfaceDark = Color(0xFFF0DFD6)
|
|
||||||
val inverseOnSurfaceDark = Color(0xFF382F29)
|
|
||||||
val inversePrimaryDark = Color(0xFF8A5022)
|
|
||||||
val surfaceDimDark = Color(0xFF19120D)
|
|
||||||
val surfaceBrightDark = Color(0xFF413731)
|
|
||||||
val surfaceContainerLowestDark = Color(0xFF140D08)
|
|
||||||
val surfaceContainerLowDark = Color(0xFF221A15)
|
|
||||||
val surfaceContainerDark = Color(0xFF261E18)
|
|
||||||
val surfaceContainerHighDark = Color(0xFF312822)
|
|
||||||
val surfaceContainerHighestDark = Color(0xFF3C332D)
|
|
||||||
|
|
||||||
val primaryDarkMediumContrast = Color(0xFFFFD4B8)
|
|
||||||
val onPrimaryDarkMediumContrast = Color(0xFF3F1C00)
|
|
||||||
val primaryContainerDarkMediumContrast = Color(0xFFC5814F)
|
|
||||||
val onPrimaryContainerDarkMediumContrast = Color(0xFF000000)
|
|
||||||
val secondaryDarkMediumContrast = Color(0xFFFBD5BC)
|
|
||||||
val onSecondaryDarkMediumContrast = Color(0xFF362111)
|
|
||||||
val secondaryContainerDarkMediumContrast = Color(0xFFAB8A75)
|
|
||||||
val onSecondaryContainerDarkMediumContrast = Color(0xFF000000)
|
|
||||||
val tertiaryDarkMediumContrast = Color(0xFFDEE0A8)
|
|
||||||
val onTertiaryDarkMediumContrast = Color(0xFF262802)
|
|
||||||
val tertiaryContainerDarkMediumContrast = Color(0xFF929462)
|
|
||||||
val onTertiaryContainerDarkMediumContrast = Color(0xFF000000)
|
|
||||||
val errorDarkMediumContrast = Color(0xFFFFD2CC)
|
|
||||||
val onErrorDarkMediumContrast = Color(0xFF540003)
|
|
||||||
val errorContainerDarkMediumContrast = Color(0xFFFF5449)
|
|
||||||
val onErrorContainerDarkMediumContrast = Color(0xFF000000)
|
|
||||||
val backgroundDarkMediumContrast = Color(0xFF19120D)
|
|
||||||
val onBackgroundDarkMediumContrast = Color(0xFFF0DFD6)
|
|
||||||
val surfaceDarkMediumContrast = Color(0xFF19120D)
|
|
||||||
val onSurfaceDarkMediumContrast = Color(0xFFFFFFFF)
|
|
||||||
val surfaceVariantDarkMediumContrast = Color(0xFF52443B)
|
|
||||||
val onSurfaceVariantDarkMediumContrast = Color(0xFFEDD8CC)
|
|
||||||
val outlineDarkMediumContrast = Color(0xFFC1AEA3)
|
|
||||||
val outlineVariantDarkMediumContrast = Color(0xFF9E8D82)
|
|
||||||
val scrimDarkMediumContrast = Color(0xFF000000)
|
|
||||||
val inverseSurfaceDarkMediumContrast = Color(0xFFF0DFD6)
|
|
||||||
val inverseOnSurfaceDarkMediumContrast = Color(0xFF312822)
|
|
||||||
val inversePrimaryDarkMediumContrast = Color(0xFF6F3A0D)
|
|
||||||
val surfaceDimDarkMediumContrast = Color(0xFF19120D)
|
|
||||||
val surfaceBrightDarkMediumContrast = Color(0xFF4D423C)
|
|
||||||
val surfaceContainerLowestDarkMediumContrast = Color(0xFF0C0603)
|
|
||||||
val surfaceContainerLowDarkMediumContrast = Color(0xFF241C17)
|
|
||||||
val surfaceContainerDarkMediumContrast = Color(0xFF2F2620)
|
|
||||||
val surfaceContainerHighDarkMediumContrast = Color(0xFF3A312B)
|
|
||||||
val surfaceContainerHighestDarkMediumContrast = Color(0xFF463C35)
|
|
||||||
|
|
||||||
val primaryDarkHighContrast = Color(0xFFFFECE2)
|
|
||||||
val onPrimaryDarkHighContrast = Color(0xFF000000)
|
|
||||||
val primaryContainerDarkHighContrast = Color(0xFFFEB17B)
|
|
||||||
val onPrimaryContainerDarkHighContrast = Color(0xFF180700)
|
|
||||||
val secondaryDarkHighContrast = Color(0xFFFFECE2)
|
|
||||||
val onSecondaryDarkHighContrast = Color(0xFF000000)
|
|
||||||
val secondaryContainerDarkHighContrast = Color(0xFFE0BBA4)
|
|
||||||
val onSecondaryContainerDarkHighContrast = Color(0xFF170700)
|
|
||||||
val tertiaryDarkHighContrast = Color(0xFFF2F4BB)
|
|
||||||
val onTertiaryDarkHighContrast = Color(0xFF000000)
|
|
||||||
val tertiaryContainerDarkHighContrast = Color(0xFFC4C690)
|
|
||||||
val onTertiaryContainerDarkHighContrast = Color(0xFF0B0C00)
|
|
||||||
val errorDarkHighContrast = Color(0xFFFFECE9)
|
|
||||||
val onErrorDarkHighContrast = Color(0xFF000000)
|
|
||||||
val errorContainerDarkHighContrast = Color(0xFFFFAEA4)
|
|
||||||
val onErrorContainerDarkHighContrast = Color(0xFF220001)
|
|
||||||
val backgroundDarkHighContrast = Color(0xFF19120D)
|
|
||||||
val onBackgroundDarkHighContrast = Color(0xFFF0DFD6)
|
|
||||||
val surfaceDarkHighContrast = Color(0xFF19120D)
|
|
||||||
val onSurfaceDarkHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val surfaceVariantDarkHighContrast = Color(0xFF52443B)
|
|
||||||
val onSurfaceVariantDarkHighContrast = Color(0xFFFFFFFF)
|
|
||||||
val outlineDarkHighContrast = Color(0xFFFFECE2)
|
|
||||||
val outlineVariantDarkHighContrast = Color(0xFFD2BFB3)
|
|
||||||
val scrimDarkHighContrast = Color(0xFF000000)
|
|
||||||
val inverseSurfaceDarkHighContrast = Color(0xFFF0DFD6)
|
|
||||||
val inverseOnSurfaceDarkHighContrast = Color(0xFF000000)
|
|
||||||
val inversePrimaryDarkHighContrast = Color(0xFF6F3A0D)
|
|
||||||
val surfaceDimDarkHighContrast = Color(0xFF19120D)
|
|
||||||
val surfaceBrightDarkHighContrast = Color(0xFF594E47)
|
|
||||||
val surfaceContainerLowestDarkHighContrast = Color(0xFF000000)
|
|
||||||
val surfaceContainerLowDarkHighContrast = Color(0xFF261E18)
|
|
||||||
val surfaceContainerDarkHighContrast = Color(0xFF382F29)
|
|
||||||
val surfaceContainerHighDarkHighContrast = Color(0xFF433933)
|
|
||||||
val surfaceContainerHighestDarkHighContrast = Color(0xFF4F453E)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -1,278 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.activities.ui.theme
|
|
||||||
|
|
||||||
import android.os.Build
|
|
||||||
import androidx.compose.foundation.isSystemInDarkTheme
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.lightColorScheme
|
|
||||||
import androidx.compose.material3.darkColorScheme
|
|
||||||
import androidx.compose.material3.dynamicDarkColorScheme
|
|
||||||
import androidx.compose.material3.dynamicLightColorScheme
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.Immutable
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
|
|
||||||
private val lightScheme = lightColorScheme(
|
|
||||||
primary = primaryLight,
|
|
||||||
onPrimary = onPrimaryLight,
|
|
||||||
primaryContainer = primaryContainerLight,
|
|
||||||
onPrimaryContainer = onPrimaryContainerLight,
|
|
||||||
secondary = secondaryLight,
|
|
||||||
onSecondary = onSecondaryLight,
|
|
||||||
secondaryContainer = secondaryContainerLight,
|
|
||||||
onSecondaryContainer = onSecondaryContainerLight,
|
|
||||||
tertiary = tertiaryLight,
|
|
||||||
onTertiary = onTertiaryLight,
|
|
||||||
tertiaryContainer = tertiaryContainerLight,
|
|
||||||
onTertiaryContainer = onTertiaryContainerLight,
|
|
||||||
error = errorLight,
|
|
||||||
onError = onErrorLight,
|
|
||||||
errorContainer = errorContainerLight,
|
|
||||||
onErrorContainer = onErrorContainerLight,
|
|
||||||
background = backgroundLight,
|
|
||||||
onBackground = onBackgroundLight,
|
|
||||||
surface = surfaceLight,
|
|
||||||
onSurface = onSurfaceLight,
|
|
||||||
surfaceVariant = surfaceVariantLight,
|
|
||||||
onSurfaceVariant = onSurfaceVariantLight,
|
|
||||||
outline = outlineLight,
|
|
||||||
outlineVariant = outlineVariantLight,
|
|
||||||
scrim = scrimLight,
|
|
||||||
inverseSurface = inverseSurfaceLight,
|
|
||||||
inverseOnSurface = inverseOnSurfaceLight,
|
|
||||||
inversePrimary = inversePrimaryLight,
|
|
||||||
surfaceDim = surfaceDimLight,
|
|
||||||
surfaceBright = surfaceBrightLight,
|
|
||||||
surfaceContainerLowest = surfaceContainerLowestLight,
|
|
||||||
surfaceContainerLow = surfaceContainerLowLight,
|
|
||||||
surfaceContainer = surfaceContainerLight,
|
|
||||||
surfaceContainerHigh = surfaceContainerHighLight,
|
|
||||||
surfaceContainerHighest = surfaceContainerHighestLight,
|
|
||||||
)
|
|
||||||
|
|
||||||
private val darkScheme = darkColorScheme(
|
|
||||||
primary = primaryDark,
|
|
||||||
onPrimary = onPrimaryDark,
|
|
||||||
primaryContainer = primaryContainerDark,
|
|
||||||
onPrimaryContainer = onPrimaryContainerDark,
|
|
||||||
secondary = secondaryDark,
|
|
||||||
onSecondary = onSecondaryDark,
|
|
||||||
secondaryContainer = secondaryContainerDark,
|
|
||||||
onSecondaryContainer = onSecondaryContainerDark,
|
|
||||||
tertiary = tertiaryDark,
|
|
||||||
onTertiary = onTertiaryDark,
|
|
||||||
tertiaryContainer = tertiaryContainerDark,
|
|
||||||
onTertiaryContainer = onTertiaryContainerDark,
|
|
||||||
error = errorDark,
|
|
||||||
onError = onErrorDark,
|
|
||||||
errorContainer = errorContainerDark,
|
|
||||||
onErrorContainer = onErrorContainerDark,
|
|
||||||
background = backgroundDark,
|
|
||||||
onBackground = onBackgroundDark,
|
|
||||||
surface = surfaceDark,
|
|
||||||
onSurface = onSurfaceDark,
|
|
||||||
surfaceVariant = surfaceVariantDark,
|
|
||||||
onSurfaceVariant = onSurfaceVariantDark,
|
|
||||||
outline = outlineDark,
|
|
||||||
outlineVariant = outlineVariantDark,
|
|
||||||
scrim = scrimDark,
|
|
||||||
inverseSurface = inverseSurfaceDark,
|
|
||||||
inverseOnSurface = inverseOnSurfaceDark,
|
|
||||||
inversePrimary = inversePrimaryDark,
|
|
||||||
surfaceDim = surfaceDimDark,
|
|
||||||
surfaceBright = surfaceBrightDark,
|
|
||||||
surfaceContainerLowest = surfaceContainerLowestDark,
|
|
||||||
surfaceContainerLow = surfaceContainerLowDark,
|
|
||||||
surfaceContainer = surfaceContainerDark,
|
|
||||||
surfaceContainerHigh = surfaceContainerHighDark,
|
|
||||||
surfaceContainerHighest = surfaceContainerHighestDark,
|
|
||||||
)
|
|
||||||
|
|
||||||
private val mediumContrastLightColorScheme = lightColorScheme(
|
|
||||||
primary = primaryLightMediumContrast,
|
|
||||||
onPrimary = onPrimaryLightMediumContrast,
|
|
||||||
primaryContainer = primaryContainerLightMediumContrast,
|
|
||||||
onPrimaryContainer = onPrimaryContainerLightMediumContrast,
|
|
||||||
secondary = secondaryLightMediumContrast,
|
|
||||||
onSecondary = onSecondaryLightMediumContrast,
|
|
||||||
secondaryContainer = secondaryContainerLightMediumContrast,
|
|
||||||
onSecondaryContainer = onSecondaryContainerLightMediumContrast,
|
|
||||||
tertiary = tertiaryLightMediumContrast,
|
|
||||||
onTertiary = onTertiaryLightMediumContrast,
|
|
||||||
tertiaryContainer = tertiaryContainerLightMediumContrast,
|
|
||||||
onTertiaryContainer = onTertiaryContainerLightMediumContrast,
|
|
||||||
error = errorLightMediumContrast,
|
|
||||||
onError = onErrorLightMediumContrast,
|
|
||||||
errorContainer = errorContainerLightMediumContrast,
|
|
||||||
onErrorContainer = onErrorContainerLightMediumContrast,
|
|
||||||
background = backgroundLightMediumContrast,
|
|
||||||
onBackground = onBackgroundLightMediumContrast,
|
|
||||||
surface = surfaceLightMediumContrast,
|
|
||||||
onSurface = onSurfaceLightMediumContrast,
|
|
||||||
surfaceVariant = surfaceVariantLightMediumContrast,
|
|
||||||
onSurfaceVariant = onSurfaceVariantLightMediumContrast,
|
|
||||||
outline = outlineLightMediumContrast,
|
|
||||||
outlineVariant = outlineVariantLightMediumContrast,
|
|
||||||
scrim = scrimLightMediumContrast,
|
|
||||||
inverseSurface = inverseSurfaceLightMediumContrast,
|
|
||||||
inverseOnSurface = inverseOnSurfaceLightMediumContrast,
|
|
||||||
inversePrimary = inversePrimaryLightMediumContrast,
|
|
||||||
surfaceDim = surfaceDimLightMediumContrast,
|
|
||||||
surfaceBright = surfaceBrightLightMediumContrast,
|
|
||||||
surfaceContainerLowest = surfaceContainerLowestLightMediumContrast,
|
|
||||||
surfaceContainerLow = surfaceContainerLowLightMediumContrast,
|
|
||||||
surfaceContainer = surfaceContainerLightMediumContrast,
|
|
||||||
surfaceContainerHigh = surfaceContainerHighLightMediumContrast,
|
|
||||||
surfaceContainerHighest = surfaceContainerHighestLightMediumContrast,
|
|
||||||
)
|
|
||||||
|
|
||||||
private val highContrastLightColorScheme = lightColorScheme(
|
|
||||||
primary = primaryLightHighContrast,
|
|
||||||
onPrimary = onPrimaryLightHighContrast,
|
|
||||||
primaryContainer = primaryContainerLightHighContrast,
|
|
||||||
onPrimaryContainer = onPrimaryContainerLightHighContrast,
|
|
||||||
secondary = secondaryLightHighContrast,
|
|
||||||
onSecondary = onSecondaryLightHighContrast,
|
|
||||||
secondaryContainer = secondaryContainerLightHighContrast,
|
|
||||||
onSecondaryContainer = onSecondaryContainerLightHighContrast,
|
|
||||||
tertiary = tertiaryLightHighContrast,
|
|
||||||
onTertiary = onTertiaryLightHighContrast,
|
|
||||||
tertiaryContainer = tertiaryContainerLightHighContrast,
|
|
||||||
onTertiaryContainer = onTertiaryContainerLightHighContrast,
|
|
||||||
error = errorLightHighContrast,
|
|
||||||
onError = onErrorLightHighContrast,
|
|
||||||
errorContainer = errorContainerLightHighContrast,
|
|
||||||
onErrorContainer = onErrorContainerLightHighContrast,
|
|
||||||
background = backgroundLightHighContrast,
|
|
||||||
onBackground = onBackgroundLightHighContrast,
|
|
||||||
surface = surfaceLightHighContrast,
|
|
||||||
onSurface = onSurfaceLightHighContrast,
|
|
||||||
surfaceVariant = surfaceVariantLightHighContrast,
|
|
||||||
onSurfaceVariant = onSurfaceVariantLightHighContrast,
|
|
||||||
outline = outlineLightHighContrast,
|
|
||||||
outlineVariant = outlineVariantLightHighContrast,
|
|
||||||
scrim = scrimLightHighContrast,
|
|
||||||
inverseSurface = inverseSurfaceLightHighContrast,
|
|
||||||
inverseOnSurface = inverseOnSurfaceLightHighContrast,
|
|
||||||
inversePrimary = inversePrimaryLightHighContrast,
|
|
||||||
surfaceDim = surfaceDimLightHighContrast,
|
|
||||||
surfaceBright = surfaceBrightLightHighContrast,
|
|
||||||
surfaceContainerLowest = surfaceContainerLowestLightHighContrast,
|
|
||||||
surfaceContainerLow = surfaceContainerLowLightHighContrast,
|
|
||||||
surfaceContainer = surfaceContainerLightHighContrast,
|
|
||||||
surfaceContainerHigh = surfaceContainerHighLightHighContrast,
|
|
||||||
surfaceContainerHighest = surfaceContainerHighestLightHighContrast,
|
|
||||||
)
|
|
||||||
|
|
||||||
private val mediumContrastDarkColorScheme = darkColorScheme(
|
|
||||||
primary = primaryDarkMediumContrast,
|
|
||||||
onPrimary = onPrimaryDarkMediumContrast,
|
|
||||||
primaryContainer = primaryContainerDarkMediumContrast,
|
|
||||||
onPrimaryContainer = onPrimaryContainerDarkMediumContrast,
|
|
||||||
secondary = secondaryDarkMediumContrast,
|
|
||||||
onSecondary = onSecondaryDarkMediumContrast,
|
|
||||||
secondaryContainer = secondaryContainerDarkMediumContrast,
|
|
||||||
onSecondaryContainer = onSecondaryContainerDarkMediumContrast,
|
|
||||||
tertiary = tertiaryDarkMediumContrast,
|
|
||||||
onTertiary = onTertiaryDarkMediumContrast,
|
|
||||||
tertiaryContainer = tertiaryContainerDarkMediumContrast,
|
|
||||||
onTertiaryContainer = onTertiaryContainerDarkMediumContrast,
|
|
||||||
error = errorDarkMediumContrast,
|
|
||||||
onError = onErrorDarkMediumContrast,
|
|
||||||
errorContainer = errorContainerDarkMediumContrast,
|
|
||||||
onErrorContainer = onErrorContainerDarkMediumContrast,
|
|
||||||
background = backgroundDarkMediumContrast,
|
|
||||||
onBackground = onBackgroundDarkMediumContrast,
|
|
||||||
surface = surfaceDarkMediumContrast,
|
|
||||||
onSurface = onSurfaceDarkMediumContrast,
|
|
||||||
surfaceVariant = surfaceVariantDarkMediumContrast,
|
|
||||||
onSurfaceVariant = onSurfaceVariantDarkMediumContrast,
|
|
||||||
outline = outlineDarkMediumContrast,
|
|
||||||
outlineVariant = outlineVariantDarkMediumContrast,
|
|
||||||
scrim = scrimDarkMediumContrast,
|
|
||||||
inverseSurface = inverseSurfaceDarkMediumContrast,
|
|
||||||
inverseOnSurface = inverseOnSurfaceDarkMediumContrast,
|
|
||||||
inversePrimary = inversePrimaryDarkMediumContrast,
|
|
||||||
surfaceDim = surfaceDimDarkMediumContrast,
|
|
||||||
surfaceBright = surfaceBrightDarkMediumContrast,
|
|
||||||
surfaceContainerLowest = surfaceContainerLowestDarkMediumContrast,
|
|
||||||
surfaceContainerLow = surfaceContainerLowDarkMediumContrast,
|
|
||||||
surfaceContainer = surfaceContainerDarkMediumContrast,
|
|
||||||
surfaceContainerHigh = surfaceContainerHighDarkMediumContrast,
|
|
||||||
surfaceContainerHighest = surfaceContainerHighestDarkMediumContrast,
|
|
||||||
)
|
|
||||||
|
|
||||||
private val highContrastDarkColorScheme = darkColorScheme(
|
|
||||||
primary = primaryDarkHighContrast,
|
|
||||||
onPrimary = onPrimaryDarkHighContrast,
|
|
||||||
primaryContainer = primaryContainerDarkHighContrast,
|
|
||||||
onPrimaryContainer = onPrimaryContainerDarkHighContrast,
|
|
||||||
secondary = secondaryDarkHighContrast,
|
|
||||||
onSecondary = onSecondaryDarkHighContrast,
|
|
||||||
secondaryContainer = secondaryContainerDarkHighContrast,
|
|
||||||
onSecondaryContainer = onSecondaryContainerDarkHighContrast,
|
|
||||||
tertiary = tertiaryDarkHighContrast,
|
|
||||||
onTertiary = onTertiaryDarkHighContrast,
|
|
||||||
tertiaryContainer = tertiaryContainerDarkHighContrast,
|
|
||||||
onTertiaryContainer = onTertiaryContainerDarkHighContrast,
|
|
||||||
error = errorDarkHighContrast,
|
|
||||||
onError = onErrorDarkHighContrast,
|
|
||||||
errorContainer = errorContainerDarkHighContrast,
|
|
||||||
onErrorContainer = onErrorContainerDarkHighContrast,
|
|
||||||
background = backgroundDarkHighContrast,
|
|
||||||
onBackground = onBackgroundDarkHighContrast,
|
|
||||||
surface = surfaceDarkHighContrast,
|
|
||||||
onSurface = onSurfaceDarkHighContrast,
|
|
||||||
surfaceVariant = surfaceVariantDarkHighContrast,
|
|
||||||
onSurfaceVariant = onSurfaceVariantDarkHighContrast,
|
|
||||||
outline = outlineDarkHighContrast,
|
|
||||||
outlineVariant = outlineVariantDarkHighContrast,
|
|
||||||
scrim = scrimDarkHighContrast,
|
|
||||||
inverseSurface = inverseSurfaceDarkHighContrast,
|
|
||||||
inverseOnSurface = inverseOnSurfaceDarkHighContrast,
|
|
||||||
inversePrimary = inversePrimaryDarkHighContrast,
|
|
||||||
surfaceDim = surfaceDimDarkHighContrast,
|
|
||||||
surfaceBright = surfaceBrightDarkHighContrast,
|
|
||||||
surfaceContainerLowest = surfaceContainerLowestDarkHighContrast,
|
|
||||||
surfaceContainerLow = surfaceContainerLowDarkHighContrast,
|
|
||||||
surfaceContainer = surfaceContainerDarkHighContrast,
|
|
||||||
surfaceContainerHigh = surfaceContainerHighDarkHighContrast,
|
|
||||||
surfaceContainerHighest = surfaceContainerHighestDarkHighContrast,
|
|
||||||
)
|
|
||||||
|
|
||||||
@Immutable
|
|
||||||
data class ColorFamily(
|
|
||||||
val color: Color,
|
|
||||||
val onColor: Color,
|
|
||||||
val colorContainer: Color,
|
|
||||||
val onColorContainer: Color
|
|
||||||
)
|
|
||||||
|
|
||||||
val unspecified_scheme = ColorFamily(
|
|
||||||
Color.Unspecified, Color.Unspecified, Color.Unspecified, Color.Unspecified
|
|
||||||
)
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun P2playTheme(
|
|
||||||
darkTheme: Boolean = isSystemInDarkTheme(),
|
|
||||||
// Dynamic color is available on Android 12+
|
|
||||||
dynamicColor: Boolean = true,
|
|
||||||
content: @Composable() () -> Unit
|
|
||||||
) {
|
|
||||||
val colorScheme = when {
|
|
||||||
// dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> {
|
|
||||||
// val context = LocalContext.current
|
|
||||||
// if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context)
|
|
||||||
//}
|
|
||||||
|
|
||||||
darkTheme -> darkScheme
|
|
||||||
else -> lightScheme
|
|
||||||
}
|
|
||||||
|
|
||||||
MaterialTheme(
|
|
||||||
colorScheme = colorScheme,
|
|
||||||
typography = AppTypography,
|
|
||||||
content = content
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
@@ -1,9 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.activities.ui.theme
|
|
||||||
|
|
||||||
import androidx.compose.material3.Typography
|
|
||||||
import androidx.compose.ui.text.TextStyle
|
|
||||||
import androidx.compose.ui.text.font.FontFamily
|
|
||||||
import androidx.compose.ui.text.font.FontWeight
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
|
|
||||||
val AppTypography = Typography()
|
|
@@ -1,10 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.domain.data
|
|
||||||
|
|
||||||
enum class VideoFilterEnum(val filter: String) {
|
|
||||||
TRENDING("trending"),
|
|
||||||
HOT("hot"),
|
|
||||||
LOCAL("local"),
|
|
||||||
RECENT("recent"),
|
|
||||||
LIKES("likes"),
|
|
||||||
POPULAR("popular")
|
|
||||||
}
|
|
@@ -1,23 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.helpers
|
|
||||||
|
|
||||||
import androidx.compose.foundation.lazy.LazyListState
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.snapshotFlow
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun InfiniteScrollHandler(
|
|
||||||
lazyState: LazyListState,
|
|
||||||
buffer: Int = 1,
|
|
||||||
onLoadMore: () -> Unit
|
|
||||||
) {
|
|
||||||
LaunchedEffect(lazyState) {
|
|
||||||
snapshotFlow { lazyState.layoutInfo.visibleItemsInfo }
|
|
||||||
.collect { visibleItems ->
|
|
||||||
val items = lazyState.layoutInfo.totalItemsCount
|
|
||||||
if (visibleItems.isNotEmpty() && items > buffer && visibleItems.last().index >= items - 1) {
|
|
||||||
onLoadMore()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,9 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.ui
|
|
||||||
|
|
||||||
import org.libre.agosto.p2play.R
|
|
||||||
|
|
||||||
sealed class Routes (val route: String, val title: Int?) {
|
|
||||||
data object Videos: Routes("videos", R.string.app_name)
|
|
||||||
data object Subscriptions: Routes("subscriptions", R.string.title_subscriptions)
|
|
||||||
data object Search: Routes("search", null)
|
|
||||||
}
|
|
@@ -1,80 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.ui.bars
|
|
||||||
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.AccountCircle
|
|
||||||
import androidx.compose.material.icons.filled.Home
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.NavigationBar
|
|
||||||
import androidx.compose.material3.NavigationBarItem
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.ui.res.painterResource
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import org.libre.agosto.p2play.R
|
|
||||||
import org.libre.agosto.p2play.ui.Routes
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun MainNavigationBar (navController: NavController) {
|
|
||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
|
||||||
val currentDestination = navBackStackEntry?.destination
|
|
||||||
|
|
||||||
NavigationBar {
|
|
||||||
NavigationBarItem(
|
|
||||||
icon = { Icon(Icons.Filled.Home, "home") },
|
|
||||||
label = { Text(text = stringResource(R.string.nav_menu_videos), fontSize = 11.sp) },
|
|
||||||
selected = currentDestination?.route == Routes.Videos.route,
|
|
||||||
onClick = {
|
|
||||||
navController.navigate(Routes.Videos.route) {
|
|
||||||
// Pop up to the start destination of the graph to
|
|
||||||
// avoid building up a large stack of destinations
|
|
||||||
// on the back stack as users select items
|
|
||||||
popUpTo(navController.graph.findStartDestination().id) {
|
|
||||||
saveState = true
|
|
||||||
}
|
|
||||||
// Avoid multiple copies of the same destination when
|
|
||||||
// reselecting the same item
|
|
||||||
launchSingleTop = true
|
|
||||||
// Restore state when reselecting a previously selected item
|
|
||||||
restoreState = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
NavigationBarItem(
|
|
||||||
icon = { Icon(painterResource(R.drawable.ic_live_tv_black_24dp), "home") },
|
|
||||||
label = { Text(stringResource(R.string.nav_subscriptions), fontSize = 11.sp) },
|
|
||||||
selected = currentDestination?.route == Routes.Subscriptions.route,
|
|
||||||
onClick = {
|
|
||||||
navController.navigate(Routes.Subscriptions.route) {
|
|
||||||
// Pop up to the start destination of the graph to
|
|
||||||
// avoid building up a large stack of destinations
|
|
||||||
// on the back stack as users select items
|
|
||||||
popUpTo(navController.graph.findStartDestination().id) {
|
|
||||||
saveState = true
|
|
||||||
}
|
|
||||||
// Avoid multiple copies of the same destination when
|
|
||||||
// reselecting the same item
|
|
||||||
launchSingleTop = true
|
|
||||||
// Restore state when reselecting a previously selected item
|
|
||||||
restoreState = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
// NavigationBarItem(
|
|
||||||
// icon = { Icon(painterResource(R.drawable.ic_menu_slideshow), "home") },
|
|
||||||
// label = { Text(stringResource(R.string.playlists), fontSize = 11.sp) },
|
|
||||||
// selected = false,
|
|
||||||
// onClick = {}
|
|
||||||
// )
|
|
||||||
NavigationBarItem(
|
|
||||||
icon = { Icon(Icons.Filled.AccountCircle, "home") },
|
|
||||||
label = { Text(stringResource(R.string.you), fontSize = 11.sp) },
|
|
||||||
selected = false,
|
|
||||||
onClick = {}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,89 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.ui.bars
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.MoreVert
|
|
||||||
import androidx.compose.material.icons.filled.Search
|
|
||||||
import androidx.compose.material3.DropdownMenu
|
|
||||||
import androidx.compose.material3.DropdownMenuItem
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.material3.TopAppBar
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.navigation.NavController
|
|
||||||
import androidx.navigation.NavGraph.Companion.findStartDestination
|
|
||||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
|
||||||
import org.libre.agosto.p2play.AboutActivity
|
|
||||||
import org.libre.agosto.p2play.LoginActivity
|
|
||||||
import org.libre.agosto.p2play.ManagerSingleton
|
|
||||||
import org.libre.agosto.p2play.R
|
|
||||||
import org.libre.agosto.p2play.ui.Routes
|
|
||||||
import org.libre.agosto.p2play.SettingsActivity2
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun MainTopAppBar(navController: NavController, modifier: Modifier = Modifier) {
|
|
||||||
var isMenuOpen by remember { mutableStateOf(false) }
|
|
||||||
val context = LocalContext.current
|
|
||||||
|
|
||||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
|
||||||
val currentDestination = navBackStackEntry?.destination
|
|
||||||
|
|
||||||
val title = when (currentDestination?.route) {
|
|
||||||
Routes.Subscriptions.route -> stringResource(Routes.Subscriptions.title!!)
|
|
||||||
else -> stringResource(R.string.app_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
TopAppBar(
|
|
||||||
{ Text(title) },
|
|
||||||
modifier,
|
|
||||||
actions = {
|
|
||||||
IconButton({
|
|
||||||
navController.navigate(Routes.Search.route) {
|
|
||||||
popUpTo(navController.graph.findStartDestination().id) {
|
|
||||||
saveState = true
|
|
||||||
}
|
|
||||||
launchSingleTop = true
|
|
||||||
restoreState = true
|
|
||||||
}
|
|
||||||
}) { Icon(Icons.Default.Search, "More") }
|
|
||||||
// IconButton({}) { Icon(Icons.Default.Notifications, "More") }
|
|
||||||
IconButton({ isMenuOpen = true }) {
|
|
||||||
Icon(Icons.Default.MoreVert, "More")
|
|
||||||
DropdownMenu(isMenuOpen, { isMenuOpen = false }) {
|
|
||||||
if (ManagerSingleton.isLogged()) {
|
|
||||||
DropdownMenuItem({ Text(stringResource(R.string.action_logout))}, {
|
|
||||||
isMenuOpen = false
|
|
||||||
ManagerSingleton.logout()
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
DropdownMenuItem({ Text(stringResource(R.string.action_login))}, {
|
|
||||||
isMenuOpen = false
|
|
||||||
val intent = Intent(context, LoginActivity::class.java)
|
|
||||||
context.startActivity(intent)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
DropdownMenuItem({ Text(stringResource(R.string.action_settings))}, {
|
|
||||||
isMenuOpen = false
|
|
||||||
val intent = Intent(context, SettingsActivity2::class.java)
|
|
||||||
context.startActivity(intent)
|
|
||||||
})
|
|
||||||
DropdownMenuItem({ Text(stringResource(R.string.nav_about))}, {
|
|
||||||
isMenuOpen = false
|
|
||||||
val intent = Intent(context, AboutActivity::class.java)
|
|
||||||
context.startActivity(intent)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
@@ -1,52 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.ui.bars
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
|
||||||
import androidx.compose.material.icons.filled.Close
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.IconButton
|
|
||||||
import androidx.compose.material3.SearchBar
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun SearchTopBar () {
|
|
||||||
var searchText by remember { mutableStateOf("") }
|
|
||||||
var active by remember { mutableStateOf(true) }
|
|
||||||
|
|
||||||
SearchBar(
|
|
||||||
query = searchText,
|
|
||||||
onQueryChange = { searchText = it },
|
|
||||||
onSearch = { active = false },
|
|
||||||
active = active,
|
|
||||||
onActiveChange = { active = it },
|
|
||||||
modifier = Modifier.fillMaxWidth(),
|
|
||||||
placeholder = { Text("Buscar...") },
|
|
||||||
leadingIcon = {
|
|
||||||
IconButton (onClick = {}) {
|
|
||||||
Icon(Icons.Default.ArrowBack, contentDescription = "Volver")
|
|
||||||
}
|
|
||||||
},
|
|
||||||
trailingIcon = {
|
|
||||||
if (searchText.isNotEmpty()) {
|
|
||||||
IconButton(onClick = { searchText = "" }) {
|
|
||||||
Icon(Icons.Default.Close, contentDescription = "Limpiar")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}) {
|
|
||||||
|
|
||||||
if (searchText.isNotEmpty()) {
|
|
||||||
Text("Resultados para: $searchText")
|
|
||||||
} else {
|
|
||||||
Text("Ingresa un término de búsqueda")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,47 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.ui.components.molecules
|
|
||||||
|
|
||||||
import android.graphics.drawable.Icon
|
|
||||||
import androidx.compose.foundation.horizontalScroll
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.Spacer
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.foundation.rememberScrollState
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.Check
|
|
||||||
import androidx.compose.material3.FilterChip
|
|
||||||
import androidx.compose.material3.Icon
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
interface ChipValues<T> {
|
|
||||||
val text: String
|
|
||||||
val value: T
|
|
||||||
val icon: ImageVector?
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun <T> ChipSelector (values: ArrayList<ChipValues<T>>, value: T? = null, modifier: Modifier = Modifier, callback: (T) -> Unit) {
|
|
||||||
Row (modifier.horizontalScroll(rememberScrollState())) {
|
|
||||||
Spacer(modifier.width(10.dp))
|
|
||||||
for (v in values) {
|
|
||||||
val isSelected = value == v.value
|
|
||||||
FilterChip(
|
|
||||||
selected = isSelected,
|
|
||||||
{ callback(v.value) },
|
|
||||||
label = { Text(v.text) },
|
|
||||||
leadingIcon = {
|
|
||||||
if (isSelected) {
|
|
||||||
Icon(Icons.Default.Check, "", Modifier.height(20.dp))
|
|
||||||
} else if (v.icon !== null) {
|
|
||||||
Icon(v.icon!!, "", Modifier.height(20.dp))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
Spacer(modifier.width(10.dp))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,113 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.ui.components.organisms
|
|
||||||
|
|
||||||
import android.content.Intent
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.clickable
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.aspectRatio
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.layout.size
|
|
||||||
import androidx.compose.foundation.shape.CircleShape
|
|
||||||
import androidx.compose.material3.Card
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.draw.alpha
|
|
||||||
import androidx.compose.ui.draw.clip
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.layout.ContentScale
|
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.text.style.TextAlign
|
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.compose.ui.unit.sp
|
|
||||||
import androidx.constraintlayout.compose.ConstraintLayout
|
|
||||||
import coil3.compose.AsyncImage
|
|
||||||
import org.libre.agosto.p2play.ChannelActivity
|
|
||||||
import org.libre.agosto.p2play.ManagerSingleton
|
|
||||||
import org.libre.agosto.p2play.R
|
|
||||||
import org.libre.agosto.p2play.ReproductorActivity
|
|
||||||
import org.libre.agosto.p2play.activities.ui.theme.AppTypography
|
|
||||||
import org.libre.agosto.p2play.helpers.mapSeconds
|
|
||||||
import org.libre.agosto.p2play.models.VideoModel
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun VideoItem (
|
|
||||||
videoData: VideoModel
|
|
||||||
) {
|
|
||||||
val context = LocalContext.current
|
|
||||||
val userImgSource = if (videoData.userImageUrl !== "") {
|
|
||||||
"https://${ManagerSingleton.url}${videoData.userImageUrl}"
|
|
||||||
} else {
|
|
||||||
R.drawable.default_avatar
|
|
||||||
}
|
|
||||||
|
|
||||||
Card({
|
|
||||||
val intent = Intent(context, ReproductorActivity::class.java)
|
|
||||||
intent.putExtra("video", videoData)
|
|
||||||
context.startActivity(intent)
|
|
||||||
}, modifier = Modifier.padding(vertical = 10.dp)) {
|
|
||||||
ConstraintLayout() {
|
|
||||||
val (thumbailImg, durationTxt, titleTxt, infoBox, userImg) = createRefs()
|
|
||||||
Box(modifier = Modifier.fillMaxWidth().aspectRatio(16f / 9f).constrainAs(thumbailImg) {
|
|
||||||
top.linkTo(parent.top)
|
|
||||||
start.linkTo(parent.start)
|
|
||||||
end.linkTo(parent.end)
|
|
||||||
}) {
|
|
||||||
AsyncImage(
|
|
||||||
"https://${ManagerSingleton.url}${videoData.thumbUrl}",
|
|
||||||
videoData.name,
|
|
||||||
contentScale = ContentScale.Crop,
|
|
||||||
modifier = Modifier.matchParentSize()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Text(mapSeconds(videoData.duration.toInt()), color = Color.Black, modifier = Modifier.alpha(0.5F).padding(5.dp).background(Color.White).constrainAs(durationTxt) {
|
|
||||||
end.linkTo(thumbailImg.end)
|
|
||||||
bottom.linkTo(thumbailImg.bottom)
|
|
||||||
})
|
|
||||||
|
|
||||||
Box(modifier = Modifier.constrainAs(userImg) {
|
|
||||||
top.linkTo(thumbailImg.bottom)
|
|
||||||
start.linkTo(parent.start)
|
|
||||||
bottom.linkTo(parent.bottom)
|
|
||||||
}.clickable {
|
|
||||||
val intent = Intent(context, ChannelActivity::class.java)
|
|
||||||
intent.putExtra("channel", videoData.getChannel())
|
|
||||||
context.startActivity(intent)
|
|
||||||
}) {
|
|
||||||
AsyncImage(
|
|
||||||
userImgSource,
|
|
||||||
"Profile photo",
|
|
||||||
contentScale = ContentScale.Fit,
|
|
||||||
modifier = Modifier.padding(10.dp).size(40.dp).clip(CircleShape),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
Text(
|
|
||||||
videoData.name,
|
|
||||||
style = AppTypography.titleMedium,
|
|
||||||
overflow = TextOverflow.Ellipsis,
|
|
||||||
lineHeight = 19.sp,
|
|
||||||
textAlign = TextAlign.Left,
|
|
||||||
modifier = Modifier.constrainAs(titleTxt) {
|
|
||||||
top.linkTo(thumbailImg.bottom)
|
|
||||||
start.linkTo(userImg.end)
|
|
||||||
}.padding(top = 12.dp, end = 70.dp)
|
|
||||||
)
|
|
||||||
|
|
||||||
Row (modifier = Modifier.constrainAs(infoBox) {
|
|
||||||
top.linkTo(titleTxt.bottom)
|
|
||||||
start.linkTo(userImg.end)
|
|
||||||
}.padding(bottom = 5.dp)) {
|
|
||||||
Text(videoData.nameChannel, style = AppTypography.labelSmall)
|
|
||||||
Text(" - ", style = AppTypography.labelSmall)
|
|
||||||
Text("${videoData.views.toString()} ${stringResource(R.string.view_text)}", style = AppTypography.labelSmall)
|
|
||||||
}
|
|
||||||
|
|
||||||
// createVerticalChain(thumbailImg, titleTxt, infoBox, chainStyle = ChainStyle.Packed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,77 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.ui.lists
|
|
||||||
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.snapshotFlow
|
|
||||||
import org.libre.agosto.p2play.ui.components.organisms.VideoItem
|
|
||||||
import org.libre.agosto.p2play.models.VideoModel
|
|
||||||
import androidx.compose.material3.CircularProgressIndicator
|
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
|
||||||
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import org.libre.agosto.p2play.helpers.InfiniteScrollHandler
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
|
||||||
@Composable
|
|
||||||
fun VideoList (videos: ArrayList<VideoModel>, header: @Composable (() -> Unit)? = null, isLoading: Boolean = false, onRefresh: (() -> Unit)? = null, onLoadMore: (() -> Unit)? = null) {
|
|
||||||
var isRefreshing by remember { mutableStateOf(false) }
|
|
||||||
val lazyState = rememberLazyListState()
|
|
||||||
|
|
||||||
PullToRefreshBox(
|
|
||||||
isRefreshing,
|
|
||||||
{
|
|
||||||
if (onRefresh !== null) {
|
|
||||||
onRefresh()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
LazyColumn(state = lazyState) {
|
|
||||||
if (header !== null) {
|
|
||||||
item(key = "header") { header() }
|
|
||||||
}
|
|
||||||
items(videos, key = { it.id }) {
|
|
||||||
VideoItem(it)
|
|
||||||
}
|
|
||||||
if (isLoading) {
|
|
||||||
item(key = "loading") {
|
|
||||||
Box(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(vertical = 20.dp),
|
|
||||||
contentAlignment = Alignment.Center
|
|
||||||
) {
|
|
||||||
CircularProgressIndicator()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onLoadMore !== null) {
|
|
||||||
LaunchedEffect (isLoading) {
|
|
||||||
snapshotFlow { isLoading }
|
|
||||||
.collect {
|
|
||||||
if (!it) {
|
|
||||||
isRefreshing = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InfiniteScrollHandler(lazyState, 2) {
|
|
||||||
onLoadMore()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.ui.views
|
|
||||||
|
|
||||||
import androidx.compose.foundation.background
|
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.height
|
|
||||||
import androidx.compose.foundation.layout.width
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.Color
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun SearchView (modifier: Modifier = Modifier) {
|
|
||||||
Box(modifier = modifier.background(Color.Red).width(100.dp).height(100.dp))
|
|
||||||
}
|
|
@@ -1,60 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.ui.views
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.Star
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
|
||||||
import androidx.compose.runtime.mutableStateOf
|
|
||||||
import androidx.compose.runtime.remember
|
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.runtime.setValue
|
|
||||||
import androidx.compose.runtime.snapshotFlow
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.res.vectorResource
|
|
||||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
|
||||||
import org.libre.agosto.p2play.R
|
|
||||||
import org.libre.agosto.p2play.ajax.Videos
|
|
||||||
import org.libre.agosto.p2play.ui.lists.VideoList
|
|
||||||
import org.libre.agosto.p2play.ui.components.molecules.ChipSelector
|
|
||||||
import org.libre.agosto.p2play.ui.components.molecules.ChipValues
|
|
||||||
import org.libre.agosto.p2play.helpers.TaskManager
|
|
||||||
import org.libre.agosto.p2play.models.VideoModel
|
|
||||||
import org.libre.agosto.p2play.viewModels.SubscriptionsViewModel
|
|
||||||
import java.util.ArrayList
|
|
||||||
|
|
||||||
@SuppressLint("MutableCollectionMutableState")
|
|
||||||
@Composable
|
|
||||||
fun SubscriptionsView (subscriptionsViewModel: SubscriptionsViewModel, modifier: Modifier = Modifier) {
|
|
||||||
val videos by subscriptionsViewModel.videos.observeAsState(initial = listOf())
|
|
||||||
val isLoading: Boolean by subscriptionsViewModel.isLoading.observeAsState(initial = false)
|
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
if (videos.isEmpty()) {
|
|
||||||
subscriptionsViewModel.loadVideos()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column (modifier) {
|
|
||||||
VideoList(
|
|
||||||
ArrayList(videos),
|
|
||||||
isLoading = isLoading,
|
|
||||||
onRefresh = {
|
|
||||||
if (!isLoading) {
|
|
||||||
subscriptionsViewModel.refresh()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLoadMore = {
|
|
||||||
if (!isLoading) {
|
|
||||||
subscriptionsViewModel.loadVideos()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,83 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.ui.views
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.material.icons.Icons
|
|
||||||
import androidx.compose.material.icons.filled.Star
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.runtime.LaunchedEffect
|
|
||||||
import androidx.compose.runtime.getValue
|
|
||||||
import androidx.compose.runtime.livedata.observeAsState
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.graphics.vector.ImageVector
|
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.res.vectorResource
|
|
||||||
import org.libre.agosto.p2play.R
|
|
||||||
import org.libre.agosto.p2play.viewModels.VideosViewModel
|
|
||||||
import org.libre.agosto.p2play.ui.lists.VideoList
|
|
||||||
import org.libre.agosto.p2play.ui.components.molecules.ChipSelector
|
|
||||||
import org.libre.agosto.p2play.ui.components.molecules.ChipValues
|
|
||||||
import org.libre.agosto.p2play.domain.data.VideoFilterEnum
|
|
||||||
import java.util.ArrayList
|
|
||||||
|
|
||||||
@SuppressLint("MutableCollectionMutableState")
|
|
||||||
@Composable
|
|
||||||
fun VideosView (videosViewModel: VideosViewModel,modifier: Modifier = Modifier) {
|
|
||||||
val chips = arrayListOf(
|
|
||||||
object : ChipValues<VideoFilterEnum> {
|
|
||||||
override val text = stringResource(R.string.nav_trending)
|
|
||||||
override val value = VideoFilterEnum.TRENDING
|
|
||||||
override val icon = ImageVector.vectorResource(R.drawable.ic_trending_up_black_24dp)
|
|
||||||
},
|
|
||||||
object : ChipValues<VideoFilterEnum> {
|
|
||||||
override val text = stringResource(R.string.nav_likes)
|
|
||||||
override val value = VideoFilterEnum.LIKES
|
|
||||||
override val icon = ImageVector.vectorResource(R.drawable.ic_thumb_up_black_24dp)
|
|
||||||
},
|
|
||||||
object : ChipValues<VideoFilterEnum> {
|
|
||||||
override val text = stringResource(R.string.nav_popular)
|
|
||||||
override val value = VideoFilterEnum.POPULAR
|
|
||||||
override val icon = Icons.Filled.Star
|
|
||||||
},
|
|
||||||
object : ChipValues<VideoFilterEnum> {
|
|
||||||
override val text = stringResource(R.string.nav_recent)
|
|
||||||
override val value = VideoFilterEnum.RECENT
|
|
||||||
override val icon = ImageVector.vectorResource(R.drawable.ic_add_circle_black_24dp)
|
|
||||||
},
|
|
||||||
object : ChipValues<VideoFilterEnum> {
|
|
||||||
override val text = stringResource(R.string.nav_local)
|
|
||||||
override val value = VideoFilterEnum.LOCAL
|
|
||||||
override val icon = ImageVector.vectorResource(R.drawable.ic_home_black_24dp)
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
val videoFilter by videosViewModel.videoFilter.observeAsState(initial = VideoFilterEnum.TRENDING)
|
|
||||||
val videos by videosViewModel.videos.observeAsState(initial = listOf())
|
|
||||||
val isLoading: Boolean by videosViewModel.isLoading.observeAsState(initial = false)
|
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
|
||||||
if (videos.isEmpty()) {
|
|
||||||
videosViewModel.loadVideos()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column (modifier) {
|
|
||||||
VideoList(
|
|
||||||
ArrayList(videos),
|
|
||||||
header = {
|
|
||||||
ChipSelector(chips, videoFilter) {
|
|
||||||
videosViewModel.changeCategory(it)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
isLoading = isLoading,
|
|
||||||
onRefresh = {
|
|
||||||
videosViewModel.refresh()
|
|
||||||
},
|
|
||||||
onLoadMore = {
|
|
||||||
if (!isLoading) {
|
|
||||||
videosViewModel.loadVideos()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,44 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.viewModels
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.lifecycle.SavedStateHandle
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import org.libre.agosto.p2play.ManagerSingleton
|
|
||||||
import org.libre.agosto.p2play.ajax.Videos
|
|
||||||
import org.libre.agosto.p2play.models.VideoModel
|
|
||||||
|
|
||||||
class SubscriptionsViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {
|
|
||||||
val client = Videos()
|
|
||||||
|
|
||||||
private val _videos = MutableLiveData<List<VideoModel>>()
|
|
||||||
val videos: LiveData<List<VideoModel>> = _videos
|
|
||||||
|
|
||||||
private val _isLoading = MutableLiveData<Boolean>()
|
|
||||||
val isLoading: LiveData<Boolean> = _isLoading
|
|
||||||
|
|
||||||
fun loadVideos() {
|
|
||||||
_isLoading.value = true
|
|
||||||
viewModelScope.launch {
|
|
||||||
val result = withContext(Dispatchers.IO) {
|
|
||||||
client.videoSubscriptions(ManagerSingleton.token.token, videos.value?.size ?: 0)
|
|
||||||
}
|
|
||||||
val data = if (videos.value !== null)
|
|
||||||
ArrayList(videos.value!!)
|
|
||||||
else
|
|
||||||
ArrayList()
|
|
||||||
data.addAll(result)
|
|
||||||
_videos.postValue(data)
|
|
||||||
_isLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun refresh() {
|
|
||||||
_videos.value = arrayListOf()
|
|
||||||
loadVideos()
|
|
||||||
}
|
|
||||||
}
|
|
@@ -1,76 +0,0 @@
|
|||||||
package org.libre.agosto.p2play.viewModels
|
|
||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
|
||||||
import androidx.lifecycle.MutableLiveData
|
|
||||||
import androidx.lifecycle.SavedStateHandle
|
|
||||||
import androidx.lifecycle.ViewModel
|
|
||||||
import androidx.lifecycle.viewModelScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import org.libre.agosto.p2play.ajax.Videos
|
|
||||||
import org.libre.agosto.p2play.domain.data.VideoFilterEnum
|
|
||||||
import org.libre.agosto.p2play.models.VideoModel
|
|
||||||
|
|
||||||
class VideosViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {
|
|
||||||
val client = Videos()
|
|
||||||
|
|
||||||
private val _videos = MutableLiveData<List<VideoModel>>()
|
|
||||||
val videos: LiveData<List<VideoModel>> = _videos
|
|
||||||
|
|
||||||
private val _isLoading = MutableLiveData<Boolean>()
|
|
||||||
val isLoading: LiveData<Boolean> = _isLoading
|
|
||||||
|
|
||||||
private val _videoFilter = MutableLiveData<VideoFilterEnum>()
|
|
||||||
val videoFilter: LiveData<VideoFilterEnum> = _videoFilter
|
|
||||||
|
|
||||||
fun loadVideos() {
|
|
||||||
_isLoading.value = true
|
|
||||||
viewModelScope.launch {
|
|
||||||
val result = withContext(Dispatchers.IO) {
|
|
||||||
getVideoResource()
|
|
||||||
}
|
|
||||||
val data = if (videos.value !== null)
|
|
||||||
ArrayList(videos.value!!)
|
|
||||||
else
|
|
||||||
ArrayList()
|
|
||||||
data.addAll(result)
|
|
||||||
_videos.postValue(data)
|
|
||||||
_isLoading.value = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun changeCategory(category: VideoFilterEnum) {
|
|
||||||
_videoFilter.value = category
|
|
||||||
refresh()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun refresh() {
|
|
||||||
_videos.value = arrayListOf()
|
|
||||||
loadVideos()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getVideoResource(): ArrayList<VideoModel> {
|
|
||||||
val skip = videos.value?.size ?: 0
|
|
||||||
return when (videoFilter.value) {
|
|
||||||
VideoFilterEnum.TRENDING -> {
|
|
||||||
return client.getTrendingVideos(skip)
|
|
||||||
}
|
|
||||||
VideoFilterEnum.POPULAR -> {
|
|
||||||
client.getPopularVideos(skip)
|
|
||||||
}
|
|
||||||
VideoFilterEnum.LIKES -> {
|
|
||||||
client.getMostLikedVideos(skip)
|
|
||||||
}
|
|
||||||
VideoFilterEnum.RECENT -> {
|
|
||||||
client.getLastVideos(skip)
|
|
||||||
}
|
|
||||||
VideoFilterEnum.LOCAL -> {
|
|
||||||
client.getLocalVideos(skip)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
client.getTrendingVideos(skip)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@@ -128,7 +128,7 @@
|
|||||||
<!-- Start Prompt string -->
|
<!-- Start Prompt string -->
|
||||||
<string name="reportDialog">Reason to report this video:</string>
|
<string name="reportDialog">Reason to report this video:</string>
|
||||||
<string name="reportDialogMsg">You reported the video</string>
|
<string name="reportDialogMsg">You reported the video</string>
|
||||||
|
<!-- TODO: Remove or change this placeholder text -->
|
||||||
|
<string name="hello_blank_fragment">Hello blank fragment</string>
|
||||||
<!-- End Prompt strings -->
|
<!-- End Prompt strings -->
|
||||||
<string name="playlists">Playlists</string>
|
|
||||||
<string name="you">You</string>
|
|
||||||
</resources>
|
</resources>
|
||||||
|
Reference in New Issue
Block a user