From c77691edda90b466a889862ab398c03aadd0fff2 Mon Sep 17 00:00:00 2001 From: yourfriendoss Date: Sat, 18 Oct 2025 20:02:25 +0300 Subject: [PATCH] first commit --- .gitignore | 34 +++ LICENSE | 21 ++ app/.gitignore | 1 + app/build.gradle.kts | 60 +++++ app/proguard-rules.pro | 21 ++ app/release/baselineProfiles/0/app-release.dm | Bin 0 -> 7610 bytes app/release/baselineProfiles/1/app-release.dm | Bin 0 -> 7533 bytes .../ovh/sad/bleh/ExampleInstrumentedTest.kt | 24 ++ app/src/main/AndroidManifest.xml | 29 ++ app/src/main/ic_launcher-playstore.png | Bin 0 -> 10031 bytes app/src/main/java/ovh/sad/bleh/Caching.kt | 81 ++++++ .../ovh/sad/bleh/InterceptingWebViewClient.kt | 153 +++++++++++ .../main/java/ovh/sad/bleh/MainActivity.kt | 61 +++++ .../main/java/ovh/sad/bleh/SecretActivity.kt | 124 +++++++++ app/src/main/java/ovh/sad/bleh/Utils.kt | 131 +++++++++ .../main/java/ovh/sad/bleh/WebViewScreen.kt | 194 ++++++++++++++ .../main/java/ovh/sad/bleh/ui/theme/Color.kt | 11 + .../main/java/ovh/sad/bleh/ui/theme/Theme.kt | 95 +++++++ .../main/java/ovh/sad/bleh/ui/theme/Type.kt | 54 ++++ .../res/drawable/ic_launcher_background.xml | 21 ++ .../res/drawable/ic_launcher_foreground.xml | 16 ++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1398 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2960 bytes app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 992 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1932 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1754 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 4162 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2512 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 6362 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3342 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 9144 bytes app/src/main/res/values/colors.xml | 10 + app/src/main/res/values/strings.xml | 3 + app/src/main/res/values/themes.xml | 5 + app/src/main/res/xml/backup_rules.xml | 13 + .../main/res/xml/data_extraction_rules.xml | 19 ++ .../test/java/ovh/sad/bleh/ExampleUnitTest.kt | 17 ++ build.gradle.kts | 6 + gradle.properties | 23 ++ gradle/libs.versions.toml | 32 +++ gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 45457 bytes gradle/wrapper/gradle-wrapper.properties | 8 + gradlew | 251 ++++++++++++++++++ gradlew.bat | 94 +++++++ settings.gradle.kts | 23 ++ 47 files changed, 1645 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 app/.gitignore create mode 100644 app/build.gradle.kts create mode 100644 app/proguard-rules.pro create mode 100644 app/release/baselineProfiles/0/app-release.dm create mode 100644 app/release/baselineProfiles/1/app-release.dm create mode 100644 app/src/androidTest/java/ovh/sad/bleh/ExampleInstrumentedTest.kt create mode 100644 app/src/main/AndroidManifest.xml create mode 100644 app/src/main/ic_launcher-playstore.png create mode 100644 app/src/main/java/ovh/sad/bleh/Caching.kt create mode 100644 app/src/main/java/ovh/sad/bleh/InterceptingWebViewClient.kt create mode 100644 app/src/main/java/ovh/sad/bleh/MainActivity.kt create mode 100644 app/src/main/java/ovh/sad/bleh/SecretActivity.kt create mode 100644 app/src/main/java/ovh/sad/bleh/Utils.kt create mode 100644 app/src/main/java/ovh/sad/bleh/WebViewScreen.kt create mode 100644 app/src/main/java/ovh/sad/bleh/ui/theme/Color.kt create mode 100644 app/src/main/java/ovh/sad/bleh/ui/theme/Theme.kt create mode 100644 app/src/main/java/ovh/sad/bleh/ui/theme/Type.kt create mode 100644 app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 app/src/main/res/values/colors.xml create mode 100644 app/src/main/res/values/strings.xml create mode 100644 app/src/main/res/values/themes.xml create mode 100644 app/src/main/res/xml/backup_rules.xml create mode 100644 app/src/main/res/xml/data_extraction_rules.xml create mode 100644 app/src/test/java/ovh/sad/bleh/ExampleUnitTest.kt create mode 100644 build.gradle.kts create mode 100644 gradle.properties create mode 100644 gradle/libs.versions.toml create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat create mode 100644 settings.gradle.kts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e5cbb64 --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Log/OS Files +*.log + +# Android Studio generated files and folders +captures/ +.externalNativeBuild/ +.cxx/ +*.aab +*.apk +output-metadata.json + +# IntelliJ +*.iml +.idea/ +misc.xml +deploymentTargetDropDown.xml +render.experimental.xml + +# Keystore files +*.jks +*.keystore + +# Google Services (e.g. APIs or Firebase) +google-services.json + +# Android Profiling +*.hprof diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2ef0141 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 sad.ovh + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/app/build.gradle.kts b/app/build.gradle.kts new file mode 100644 index 0000000..b1411cd --- /dev/null +++ b/app/build.gradle.kts @@ -0,0 +1,60 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) +} + +android { + namespace = "ovh.sad.bleh" + compileSdk { + version = release(36) + } + + defaultConfig { + applicationId = "ovh.sad.bleh" + minSdk = 34 + targetSdk = 36 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } + buildFeatures { + compose = true + } +} + +dependencies { + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.compose.ui) + implementation(libs.androidx.compose.ui.graphics) + implementation(libs.androidx.compose.ui.tooling.preview) + implementation(libs.androidx.compose.material3) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.compose.ui.test.junit4) + debugImplementation(libs.androidx.compose.ui.tooling) + debugImplementation(libs.androidx.compose.ui.test.manifest) +} \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/app/release/baselineProfiles/0/app-release.dm b/app/release/baselineProfiles/0/app-release.dm new file mode 100644 index 0000000000000000000000000000000000000000..d437e556dc63529162b678c1191baab9f34c9ea9 GIT binary patch literal 7610 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 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/ic_launcher-playstore.png b/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..ff0e563001d88e57a568c1c632da317b48fdfe5c GIT binary patch literal 10031 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 IeeECr1DUJbK>z>% literal 0 HcmV?d00001 diff --git a/app/src/main/java/ovh/sad/bleh/Caching.kt b/app/src/main/java/ovh/sad/bleh/Caching.kt new file mode 100644 index 0000000..b8cbcee --- /dev/null +++ b/app/src/main/java/ovh/sad/bleh/Caching.kt @@ -0,0 +1,81 @@ +package ovh.sad.bleh + +import android.content.Context +import android.content.Context.MODE_PRIVATE +import android.os.Handler +import android.util.Log + +class Caching { + companion object { + // The logger function, defaults to Android Log + var defaultLogger: (String) -> Unit = { msg -> Log.d("Caching", msg) } + private var logger: (String) -> Unit = defaultLogger + + // Set a custom logger + fun setLog(customLog: (String) -> Unit) { + logger = customLog + } + + // Helper to call logger + private fun log(message: String) { + logger(message) + } + + fun getBranch(context: Context): String? { + val sharedPreferences = context.getSharedPreferences("UserPreferences", MODE_PRIVATE) + return if (sharedPreferences.getString("blehBranch", null) != null) { + sharedPreferences.getString("blehBranch", ""); + } else { + "stable"; + } + } + + fun getCachedJsFile(context: Context): java.io.File { + return java.io.File(context.cacheDir, "bleh.user.js") + } + + fun getCachedVersionFile(context: Context): java.io.File { + return java.io.File(context.cacheDir, "bleh.user.js.version") + } + + fun getBlehJs(context: Context): String? { + val cachedFile = getCachedJsFile(context) + val text = if (cachedFile.exists()) cachedFile.readText() else return null + + return text; + } + + fun checkBlehJsUpdate(handler: Handler, context: Context) { + log("Checking bleh updates..") + val branch = getBranch(context) + val buildUrl = + "https://raw.githubusercontent.com/katelyynn/bleh/refs/heads/${if(branch == "stable") "uwu" else branch}/fm/src/build/build.json?${System.currentTimeMillis()}" + val jsUrl = + "https://raw.githubusercontent.com/katelyynn/bleh/refs/heads/${if(branch == "stable") "uwu" else branch}/fm/bleh.user.js?${System.currentTimeMillis()}" + + val cachedFile = getCachedJsFile(context) + val versionFile = getCachedVersionFile(context) + + try { + val buildResult = Utils.fetchHtml(handler, buildUrl) + + val latestVersion = buildResult.html?.let { + Regex("\"build\"\\s*:\\s*\"([^\"]+)\"").find(it)?.groupValues?.get(1) + } + "-" + branch + + var cachedVersion = if (versionFile.exists()) versionFile.readText() else null + log("Cached version: $cachedVersion, latest version: $latestVersion"); + + if (latestVersion != null && latestVersion != cachedVersion) { + val jsResult = Utils.fetchHtml(handler, jsUrl) + if (jsResult.error == null) { + cachedFile.writeText(jsResult.html.orEmpty()) + versionFile.writeText(latestVersion) + } + } + } catch (e: Exception) { + e.printStackTrace() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ovh/sad/bleh/InterceptingWebViewClient.kt b/app/src/main/java/ovh/sad/bleh/InterceptingWebViewClient.kt new file mode 100644 index 0000000..677d71e --- /dev/null +++ b/app/src/main/java/ovh/sad/bleh/InterceptingWebViewClient.kt @@ -0,0 +1,153 @@ +package ovh.sad.bleh + +import android.content.Context +import android.graphics.Bitmap +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.webkit.WebResourceRequest +import android.webkit.WebResourceResponse +import android.webkit.WebView +import android.webkit.WebViewClient +import android.widget.Toast +import java.io.ByteArrayInputStream +import java.nio.charset.StandardCharsets + +data class FetchResult( + val html: String?, + val error: String? = null, + val statusCode: Int? = null +) + +open class InterceptingWebViewClient(private val context: Context) : WebViewClient() { + open fun log(message: String) { + Log.d("IWVC", message) + } + + private val blockedDomains = arrayOf( + "demdex.net", + "ssa.last.fm", + "googletagmanager.com", + "everestjs.net", + "newrelic.com", + "at.cbsi.com", + "tiqcdn.com", + "siteintercept.qualtrics.com", + "secure-us.imrworldwide.com", + "scorecardresearch.com", + "cookielaw.org", + "cdn.privacy.paramount.com", + "twochihuahuas.com", + "doubleclick.net", + "liadm.com", + "amazon-adsystem.com", + "confiant-integrations.net", + "criteo.com", + "adsrvr.org", + "contextual.media.net", + "adsafeprotected.com", + "merequartz.com", + "googlesyndication.com", + "strangeclocks.com" + ) + + val mainHandler = Handler(Looper.getMainLooper()) + // onPageStarted here exists for one big reason + // + // When logging in for the first time, the client sends a POST request, which we can't really get the response of (cause it's a POST rqeuest, duh!) + // so I set this flag (interceptNextPost), which intercepts the next page load after a POST (which is always the page POST'ed) + private var interceptNextPost = false; + + override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { + if(interceptNextPost) { + val injectedJs = Caching.getBlehJs(context) + if(injectedJs == null) { + mainHandler.post { + Toast.makeText(context, "Something is fucked! injectedJs returned NULL", Toast.LENGTH_SHORT).show() + } + return super.onPageStarted(view, url, favicon) + } + + mainHandler.post { + Toast.makeText(context, "This page load may be slow.", Toast.LENGTH_SHORT).show() + + view?.evaluateJavascript("window.unsafeWindow = window;$injectedJs") { e -> + } + } + + interceptNextPost = false; + } + super.onPageStarted(view, url, favicon) + } + + override fun shouldInterceptRequest( + view: WebView?, + request: WebResourceRequest? + ): WebResourceResponse? { + val req = request ?: return null + val url = req.url.toString() + try { + val host = req.url.host ?: "no host wtf" + + if (blockedDomains.any { host.contains(it, ignoreCase = true) }) { + log("Blocked $host.") + return WebResourceResponse( + "application/javascript", + StandardCharsets.UTF_8.name(), + ByteArrayInputStream.nullInputStream() + ) + } else { + log("Letting past: $host") + } + + if(req.method == "POST" && req.isForMainFrame && (req.url.host == "www.last.fm" || req.url.host == "last.fm")) { + interceptNextPost = true; + } + + if (req.method == "GET" && req.isForMainFrame && (req.url.host == "www.last.fm" || req.url.host == "last.fm")) { + log("Intercepting mainframe..") + + var fetched = Utils.fetchHtml(mainHandler, url, 3, true); + val code = fetched.statusCode + if ((code != 200 && code != 404) || fetched.html == null) { + mainHandler.post { + Toast.makeText(context, "Could not modify HTML. Status code: " + code + ", error: " + fetched.error, Toast.LENGTH_LONG).show() + } + return super.shouldInterceptRequest(view, request) + } + + val injectedJs = Caching.getBlehJs(context); + if(injectedJs == null) { + mainHandler.post { + Toast.makeText(context, "Something is fucked! injectedJs returned NULL", Toast.LENGTH_SHORT).show() + } + return super.shouldInterceptRequest(view, request) + } + val injectedTag = "" + val modifiedHtml = try { + val pattern = Regex("(?i)]*>") + + if (pattern.containsMatchIn(fetched.html)) { + fetched.html.replaceFirst(pattern, "$0$injectedTag") + } else { + injectedTag + fetched.html + } + } catch (_: Exception) { + injectedTag + fetched.html + } + + val bytes = modifiedHtml.toByteArray(StandardCharsets.UTF_8) + return WebResourceResponse( + "text/html", + StandardCharsets.UTF_8.name(), + ByteArrayInputStream(bytes) + ) + } + } catch (e: Exception) { + e.printStackTrace() + } + + return super.shouldInterceptRequest(view, request) + } + +} \ No newline at end of file diff --git a/app/src/main/java/ovh/sad/bleh/MainActivity.kt b/app/src/main/java/ovh/sad/bleh/MainActivity.kt new file mode 100644 index 0000000..973be50 --- /dev/null +++ b/app/src/main/java/ovh/sad/bleh/MainActivity.kt @@ -0,0 +1,61 @@ +package ovh.sad.bleh + +import android.content.Intent +import android.os.Bundle +import android.util.Log +import android.view.MotionEvent +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Scaffold +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.pointerInteropFilter +import ovh.sad.bleh.ui.theme.BlehTheme + +class MainActivity : ComponentActivity() { + + @OptIn(ExperimentalComposeUiApi::class) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + var tapCount = 0 + var lastTapTime = 0L + val multiTapThresholdMs = 200L + val requiredTaps = 30 + + setContent { + BlehTheme { + Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> + LastFmWebView( + modifier = Modifier + .padding(innerPadding) + .pointerInteropFilter { event -> + when (event.action) { + MotionEvent.ACTION_DOWN -> { + val now = System.currentTimeMillis() + if (now - lastTapTime < multiTapThresholdMs) { + tapCount++ + } else { + tapCount = 1 + } + lastTapTime = now + + Log.d("Secret", "Tap #$tapCount") + + if (tapCount >= requiredTaps) { + startActivity(Intent(this@MainActivity, SecretActivity::class.java)) + tapCount = 0 + } + } + } + + false + } + ) + } + } + } + } +} diff --git a/app/src/main/java/ovh/sad/bleh/SecretActivity.kt b/app/src/main/java/ovh/sad/bleh/SecretActivity.kt new file mode 100644 index 0000000..f40a5d8 --- /dev/null +++ b/app/src/main/java/ovh/sad/bleh/SecretActivity.kt @@ -0,0 +1,124 @@ +package ovh.sad.bleh + +import android.content.Context.MODE_PRIVATE +import android.content.Intent +import android.os.Bundle +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.widget.Toast +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.unit.dp +import ovh.sad.bleh.ui.theme.BlehTheme +import androidx.core.content.edit +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch + +class SecretActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + BlehTheme { + SecretScreen(this) + } + } + } +} + +@Composable +fun SecretScreen(activity: SecretActivity) { + val sharedPreferences = activity.getSharedPreferences("UserPreferences", MODE_PRIVATE) + val tempBranch = sharedPreferences.getString("blehBranch", null); + + var selectedOption by remember { mutableStateOf(if(tempBranch != null) "custom" else "stable") } + var customBranch by remember { mutableStateOf(tempBranch ?: "") } + var errorText by remember { mutableStateOf("") } + + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + Text("Select branch", style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.primary) + + RadioButtonRow("Latest stable", MaterialTheme.colorScheme.secondary, "stable", selectedOption) { selectedOption = it } + RadioButtonRow("Custom branch", MaterialTheme.colorScheme.secondary, "custom", selectedOption) { selectedOption = it } + + if (selectedOption == "custom") { + OutlinedTextField( + value = customBranch, + onValueChange = { customBranch = it }, + label = { Text("Input a Custom Branch here", color = MaterialTheme.colorScheme.secondary) }, + singleLine = true, + keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Text) + ) + } + + Button(onClick = { + if (selectedOption == "custom" && customBranch.isBlank()) { + errorText = "Custom branch cannot be empty!" + } else if (selectedOption == "custom" && !isValidBranch(customBranch)) { + errorText = "Custom branch is incorrect!" + } else { + errorText = "" + + val previousState = sharedPreferences.getString("blehBranch", "") + ""; + + sharedPreferences.edit(commit = true) { + if (selectedOption == "custom") { + putString("blehBranch", customBranch) + } else { + if (previousState.isNotEmpty()) { + remove("blehBranch"); + } + } + }; + + if (previousState != sharedPreferences.getString("blehBranch", "")) { + CoroutineScope(Dispatchers.IO).launch { + Caching.checkBlehJsUpdate( + Handler(Looper.getMainLooper()), + activity + ); + } + } + activity.finish(); + } + + }) { + Text("Submit") + } + + if (errorText.isNotEmpty()) { + Text(errorText, color = MaterialTheme.colorScheme.error) + } + } + } +} + +@Composable +fun RadioButtonRow(text: String, textColor: Color, value: String, selected: String, onSelected: (String) -> Unit) { + Row(verticalAlignment = Alignment.CenterVertically) { + RadioButton( + selected = selected == value, + onClick = { onSelected(value) } + ) + Text(text, color = textColor) + } +} + +// Simple branch validation +fun isValidBranch(branch: String) = branch.matches(Regex("^[a-zA-Z0-9_-]+$")) \ No newline at end of file diff --git a/app/src/main/java/ovh/sad/bleh/Utils.kt b/app/src/main/java/ovh/sad/bleh/Utils.kt new file mode 100644 index 0000000..b166b23 --- /dev/null +++ b/app/src/main/java/ovh/sad/bleh/Utils.kt @@ -0,0 +1,131 @@ +package ovh.sad.bleh + +import android.os.Handler +import android.util.Log +import android.webkit.CookieManager +import java.io.BufferedInputStream +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.InputStream +import java.net.HttpURLConnection +import java.net.URL + + +open class Utils { + + companion object { + // The logger function, defaults to Android Log + var defaultLogger: (String) -> Unit = { msg -> Log.d("Utils", msg) } + private var logger: (String) -> Unit = defaultLogger + + // Set a custom logger + fun setLog(customLog: (String) -> Unit) { + logger = customLog + } + + // Helper to call logger + private fun log(message: String) { + logger(message) + } + + fun fetchHtml( + handler: Handler, + urlString: String, + retries: Int = 3, + cookies: Boolean = false + ): FetchResult { + var conn: HttpURLConnection? = null + var input: InputStream? = null + + val retryableCodes = setOf(429, 500, 502, 503, 504, 406) + val cookieHeader = CookieManager.getInstance().getCookie(urlString) ?: "" + + return try { + val url = URL(urlString) + log("URL: $urlString (retries left: $retries)") + + conn = (url.openConnection() as HttpURLConnection).apply { + requestMethod = "GET" + connectTimeout = 25_000 + readTimeout = 25_000 + instanceFollowRedirects = true + setRequestProperty( + "User-Agent", + "Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Mobile Safari/537.36" + ) + setRequestProperty( + "Accept", + "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8" + ) + setRequestProperty("Accept-Language", "en-US,en;q=0.9") + setRequestProperty("Connection", "keep-alive") + setRequestProperty("DNT", "1") + setRequestProperty("Upgrade-Insecure-Requests", "1") + setRequestProperty("X-UA-Device-Type", "mobile") + setRequestProperty("X-UA-Country-Code", "LV") + if (cookies && cookieHeader.isNotEmpty()) { + setRequestProperty("Cookie", cookieHeader) + } + } + + val code = conn.responseCode + + if (cookies) { + conn.headerFields["Set-Cookie"]?.forEach { header -> + handler.post { + CookieManager.getInstance().setCookie(urlString, header) { + CookieManager.getInstance().flush() + } + } + } + } + + if (code in retryableCodes) { + log("Got $code, retrying... ($retries left)") + if (retries > 0) { + Thread.sleep(500) + return fetchHtml(handler, urlString, retries - 1, cookies) + } else { + log("$code persisted after retries.") + return FetchResult(html = null, error = "HTTP $code", statusCode = code) + } + } + + input = if (code in 200..299) { + BufferedInputStream(conn.inputStream) + } else { + BufferedInputStream(conn.errorStream ?: ByteArrayInputStream(ByteArray(0))) + } + + val html = readStreamToString(input) + + if (code !in 200..299) { + log("Code $code") + return FetchResult(html = html, error = "HTTP $code", statusCode = code) + } + + log("Downloaded $urlString.") + FetchResult(html = html, statusCode = code) + + } catch (e: Exception) { + log("Exception: ${e.message}") + FetchResult(html = null, error = e.message) + } finally { + try { + input?.close() + } catch (_: Exception) {} + conn?.disconnect() + } + } + + private fun readStreamToString(input: InputStream): String { + val baos = ByteArrayOutputStream() + val buffer = ByteArray(4096) + var read: Int + while (input.read(buffer).also { read = it } != -1) { + baos.write(buffer, 0, read) + } + return baos.toString() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ovh/sad/bleh/WebViewScreen.kt b/app/src/main/java/ovh/sad/bleh/WebViewScreen.kt new file mode 100644 index 0000000..204acd7 --- /dev/null +++ b/app/src/main/java/ovh/sad/bleh/WebViewScreen.kt @@ -0,0 +1,194 @@ +package ovh.sad.bleh + +import android.annotation.SuppressLint +import android.content.Context +import android.graphics.Bitmap +import android.os.Handler +import android.os.Looper +import android.util.Log +import android.webkit.CookieManager as AndroidCookieManager +import android.webkit.WebChromeClient +import android.webkit.WebResourceRequest +import android.webkit.WebResourceResponse +import android.webkit.WebSettings +import android.webkit.WebView +import android.webkit.WebViewClient +import android.widget.Toast +import androidx.compose.animation.core.LinearEasing +import androidx.compose.animation.core.RepeatMode +import androidx.compose.animation.core.animateFloat +import androidx.compose.animation.core.infiniteRepeatable +import androidx.compose.animation.core.rememberInfiniteTransition +import androidx.compose.animation.core.tween +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.shape.CircleShape +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.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.draw.rotate +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.viewinterop.AndroidView +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat +import androidx.core.view.updatePadding +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import java.io.BufferedInputStream +import java.io.ByteArrayInputStream +import java.io.ByteArrayOutputStream +import java.io.InputStream +import java.net.HttpCookie +import java.net.HttpURLConnection +import java.net.URL +import java.nio.charset.StandardCharsets + + +@SuppressLint("SetJavaScriptEnabled") +@Composable +fun LastFmWebView(modifier: Modifier = Modifier) { + val context = LocalContext.current + var isLoading by remember { mutableStateOf(true) } + var currentLog by remember { mutableStateOf("Loading.. ") } + + val rotation by rememberInfiniteTransition().animateFloat( + initialValue = 0f, + targetValue = 360f, + animationSpec = infiniteRepeatable( + animation = tween(durationMillis = 1500, easing = LinearEasing), + repeatMode = RepeatMode.Restart + ) + ) + + Box(modifier = modifier.fillMaxSize()) { + AndroidView( + factory = { ctx -> + WebView(ctx).apply { + layoutParams = android.view.ViewGroup.LayoutParams( + android.view.ViewGroup.LayoutParams.MATCH_PARENT, + android.view.ViewGroup.LayoutParams.MATCH_PARENT + ) + + AndroidCookieManager.getInstance().setAcceptCookie(true) + AndroidCookieManager.getInstance().setAcceptThirdPartyCookies(this, true) + + settings.javaScriptEnabled = true + settings.domStorageEnabled = true + settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW + fitsSystemWindows = true + + ViewCompat.setOnApplyWindowInsetsListener(this) { v, insets -> + val sys = insets.getInsets(WindowInsetsCompat.Type.systemBars()) + v.updatePadding( + left = sys.left, + top = sys.top, + right = sys.right, + bottom = sys.bottom + ) + insets + } + + ViewCompat.requestApplyInsets(this) + + var iwvc = object : InterceptingWebViewClient(context) { + override fun log(message: String) { + currentLog = "Loading.. (iwvc)\n$message"; + super.log(message) + } + } + + webViewClient = iwvc; + + webChromeClient = object : WebChromeClient() { + override fun onProgressChanged(view: WebView?, newProgress: Int) { + if (newProgress < 100) isLoading = true + if(newProgress == 100) { + isLoading = false; + } + } + } + + Caching.setLog { e -> + Caching.defaultLogger(e); + currentLog = "Loading.. (caching)\n$e"; + } + + Utils.setLog { e -> + Utils.defaultLogger(e); + currentLog = "Loading.. (utils)\n$e"; + } + + WebView.setWebContentsDebuggingEnabled(true) + + CoroutineScope(Dispatchers.IO).launch { + Caching.checkBlehJsUpdate(iwvc.mainHandler, ctx); + ctx.mainExecutor.execute { + loadUrl("https://www.last.fm/login") + } + } + } + }, + update = { } + ) + + if (isLoading) { + Box( + modifier = Modifier + .fillMaxSize() + .background(Color.hsl(0f, 0f, 0.13f)), + contentAlignment = Alignment.Center, + ) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Box( + modifier = Modifier + .size(96.dp) + .rotate(rotation) + .clip(CircleShape) + ) { + Image( + painter = painterResource(id = R.drawable.ic_launcher_background), + contentDescription = null, + modifier = Modifier.matchParentSize() + ) + Image( + painter = painterResource(id = R.drawable.ic_launcher_foreground), + contentDescription = "Loading", + modifier = Modifier.matchParentSize() + ) + } + + Spacer(modifier = Modifier.height(8.dp)) + Text( + modifier = Modifier.widthIn(max = 200.dp), + softWrap = true, + text = currentLog, + textAlign = TextAlign.Center, + color = Color.White + ) + } + } + } + } +} diff --git a/app/src/main/java/ovh/sad/bleh/ui/theme/Color.kt b/app/src/main/java/ovh/sad/bleh/ui/theme/Color.kt new file mode 100644 index 0000000..9ac2658 --- /dev/null +++ b/app/src/main/java/ovh/sad/bleh/ui/theme/Color.kt @@ -0,0 +1,11 @@ +package ovh.sad.bleh.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650A4) +val PurpleGrey40 = Color(0xFF625B71) +val Pink40 = Color(0xFF7D5260) diff --git a/app/src/main/java/ovh/sad/bleh/ui/theme/Theme.kt b/app/src/main/java/ovh/sad/bleh/ui/theme/Theme.kt new file mode 100644 index 0000000..ee6fd7a --- /dev/null +++ b/app/src/main/java/ovh/sad/bleh/ui/theme/Theme.kt @@ -0,0 +1,95 @@ +package ovh.sad.bleh.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext + +// Light theme colors +val LightColors = lightColorScheme( + primary = Purple40, + onPrimary = Color.White, + primaryContainer = Purple80, + onPrimaryContainer = Color.Black, + secondary = PurpleGrey40, + onSecondary = Color.White, + secondaryContainer = PurpleGrey80, + onSecondaryContainer = Color.Black, + tertiary = Pink40, + onTertiary = Color.White, + tertiaryContainer = Pink80, + onTertiaryContainer = Color.Black, + background = Color(0xFFF5F5F5), + onBackground = Color(0xFF1C1B1F), + surface = Color.White, + onSurface = Color(0xFF1C1B1F), + error = Color(0xFFB00020), + onError = Color.White, + surfaceVariant = Color(0xFFE7E0EC), + onSurfaceVariant = Color(0xFF49454F), + outline = Color(0xFF79747E), + inverseOnSurface = Color.White, + inverseSurface = Color(0xFF313033), + inversePrimary = Purple80, + scrim = Color.Black +) + +// Dark theme colors +val DarkColors = darkColorScheme( + primary = Purple80, + onPrimary = Color.Black, + primaryContainer = Purple40, + onPrimaryContainer = Color.White, + secondary = PurpleGrey80, + onSecondary = Color.Black, + secondaryContainer = PurpleGrey40, + onSecondaryContainer = Color.White, + tertiary = Pink80, + onTertiary = Color.Black, + tertiaryContainer = Pink40, + onTertiaryContainer = Color.White, + background = Color(0xFF1C1B1F), + onBackground = Color(0xFFE6E1E5), + surface = Color(0xFF1C1B1F), + onSurface = Color(0xFFE6E1E5), + error = Color(0xFFCF6679), + onError = Color.Black, + surfaceVariant = Color(0xFF49454F), + onSurfaceVariant = Color(0xFFCAC4D0), + outline = Color(0xFF938F99), + inverseOnSurface = Color(0xFF1C1B1F), + inverseSurface = Color(0xFFE6E1E5), + inversePrimary = Purple40, + scrim = Color.Black +) + +@Composable +fun BlehTheme( + 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 -> DarkColors + else -> LightColors + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/app/src/main/java/ovh/sad/bleh/ui/theme/Type.kt b/app/src/main/java/ovh/sad/bleh/ui/theme/Type.kt new file mode 100644 index 0000000..9af3b7d --- /dev/null +++ b/app/src/main/java/ovh/sad/bleh/ui/theme/Type.kt @@ -0,0 +1,54 @@ +package ovh.sad.bleh.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 Typography = Typography( + displayLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Bold, + fontSize = 57.sp, + lineHeight = 64.sp, + letterSpacing = (-0.25).sp + ), + displayMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Bold, + fontSize = 45.sp, + lineHeight = 52.sp + ), + displaySmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Bold, + fontSize = 36.sp, + lineHeight = 44.sp + ), + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.SemiBold, + fontSize = 22.sp, + lineHeight = 28.sp + ), + titleMedium = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 16.sp, + lineHeight = 24.sp + ), + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp + ), + labelLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 14.sp, + lineHeight = 20.sp + ) +) \ No newline at end of file diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..27c77fe --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,21 @@ + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_foreground.xml b/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..7ddce00 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000..bbd3e02 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000..bbd3e02 --- /dev/null +++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..e53f766c11fa44bc2066177022cc4559e6aad71c GIT binary patch literal 1398 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 Oy0FLrj`@dfi-Z!;(%eJ< literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..81a71961761d83605002b5264341d18e566344b4 GIT binary patch literal 1932 zcmV;72XpvRNk&G52LJ$9MM6+kP&iC?2LJ#sFTe{B)ll01Pi-5`Ij^AI-5VVD$jr>U zF0(ZwuqD~@!ikxgdH2Z7OeZ`sGcz;T@?Yb3@DDRhxebG#a3aM|;+0cXc5K^j+Z=$I z$N&-Ez31F3eLLF?s0sDs&L!KnZMAK7IAvyLW@hGwV`jGCqOLBu-_x75zI&d3Fk>X`KhBu%i^0kv2`uv~I{teR} zrtvyGA2W0u^1S1ar!Ym^rsY}sI#N!WG^Hv5wkQWQ)&3?RM}4|PYMrGKJL!{`L7&eCttpYK25)XrYoS~N$C}& z^ic{Q0Cj~zVcmfL-$tJ!50TMzrQx5o6{Pfm%4J&$5c}Pra?i4e9?!_at)S@>8V(H? zr1Z&34#WAC1u3!>&Vz@@((Ps8&~%t=mZpovT*O3iarn*ccN&ttz*qcjOT0td139Y|h4x`dhAcrNTN#;52ft~3Gu{6)R73yqvx)`~K+NYjw z?|G)VYwDOX(Cuth_u`Z<2#|-uzKu!GS7gXxf*d9Sopv<*1xPw`uidU# zRzD9_I>=Jym(gr=(MM!b*OkyzrdgqJRxwx*OCX;dQxxpG!m~Dea*y*7}erO~McI9h@t<#P=zOt&6c{V;yfLsqpnfOCZibfS`Ahv$47ad=^ z3<<;FWoPC_j-az`lFil;pM1vx00x&9B3#ag<1T5 zukk};#F<;GnMU~~qC|vAXo6g|{3Sr&)O(z@RWyOBqD;t6zV5&LZH;*7tI{H)#3z?S zPADBt?K%Hwhq(Xrx1lQWK1wO-G7Lekp8s&@&uYf1AxMwz5@q~hm;QA##Lb4cRW!1q zsH7-mSOK|u`NP(y=R)TVJ2{I=1w9 zo_BBe(w~?i#1Hkd^Vb3oGN3y*r?gHJAnme$!}RDJYcA0x=n`?b1z>C9hWUq<7K_BQ z&l`jgpPvuNwg86pkTF8$ply5gX!3oy+v`{RDB1TGT_Ql8P})Ae943<9yBv4MUUl)h z>6zxP->Nyu-n^Z5BtuX-MKC1EjDBp}zv)JRoSi=M6#3f8MFNy($LNkh&TyX1157e6 zKCVht@lCzQm`JL-Zuun-Y0fV=+V=@i3H{`bnd|ma!x@7-R_6gH9W6gqi$uELt65Js z_Z;pKC|x|76fx?=0k4(S>)h1$zy>(nK=G*15T}Pox&Sd!cl2-kj#+8_TFra3d+Z2C zx*&OzT-f?W({Qk{?Tf}GKSIm!Y7 zq#;Hgqa+TPS2p^t{d(qIuw%_O1)IZGnT8!NQ~ch5+?3 zghD2BS<&-I!#GT+Ka&@!T;w1t!9V&%?r)mh$Y}UGU*6@%;D()m36NzyWTqe8P z3=4$T&GQ6kUbE9jokw%_{$*$3A&4&LDn7{AoOCO<~aRBMpG>YBEamwf5227D zKotVC*>C=_C0yEth6Q>PPWXuuh1N9x`+o1}>iwqgTM5v%JA^`p^X~}5FkM4{+C|vY ze(&Mangv_=zGnSzrU&ATSd1k+mLQQd-sqbQX+HS2;Hci8EW)1lBk8X<&&CP@lp#PZ z0<_w+xixs->GS$I%jWqdTkRPuog%ID-bPFBQz6Gnw`j>;e^$Kj^m%;^0a^$B73BXk zFSCCxLjTN&KpFe?|33~vItx!+3pBpAcyzPXu4eZ0fK~Ds7QUPc-8vsq|6DbWz=S?aZR^P|_mw zS!*SgPDv$5Mj{pAVOylqsqfvli!_2KBG$Ro;fy*!GW=8dFv%F$85neLZd!KV<$vi?mw=&xZ5Ge>r=0Zz6nSrCwL$LallQ^Q3~71#fNXeHl`0|#DrfbM0F zhQA}M4DCDIOoW`Jz61vWVc$qmPtK=ZiZfH3p(xV^cHGk;Ap9L3@j0(LCrIu%N@g~u zIMWz*>-0+az-O^SET%h{F;wzuS z(aZ>m`Q_`zu(SGx4LTj^ZoEfouv?&GiESfyWkqc*YD-jB<;X+L46PKYp?x0knIE$w zOzN!UpScGQ%=G>3+c#fankbIdqnM|AlyenViiC*HMe2N2RBkbETpJsK(gjZrhDqfX zdqmoHd8nHKb)*}wc!VVGCyo!Up0O{D+Y$-ljL1C|8U8TG zjy}869t$HQMw*coEmx_PJdiLpe6$&uQQ?t6!bI`$MbB=inK_F~TXS4m&A6tDjW@ld zs~&#;NJ{^(s*I~O8%X>)GaFf$eAfeD=8MZfm<7SKXV~um)msD!6T`-u9@^+vQB7GEEANN*=DMV&jV*N_?6>#VfWr5b+Lv zG9K5Zq2sSR%S5r!W`H_}3z%HAK+rekOp`Lr3QbC#$ivM9oeNZdn7`0d@;7HXr7h}| zT0}O}*Fd*Gr0yrqH3tzaI4JWf{bKDJQaJ5b+|!mIy?wfG;b9@q@up|8lX%W__=U$W zUszo7Bzcdf7qvTXe{rWdY~7&H zdI~$H>#|3sJ({g5dp@tHa?X@Q;*T?+`N6z>x-WSYIv!b5i>BmAIq^~BkEWT+(+?Jv zTdZf;w=@6#fd|h-TFH^L)Q5K1%xIeS+Dh&=e6{7PwcO0)WvXw)c*S~oIp{LQ%@oHZ zS0N`?ED2fvOIO^!N#I*uh~mKYY9$~c*4i=)P;|Msclr=h%f z9Cvf2`1*By1mpR2x77~%YLj9I)etAUzLKE~?{8O53w_BYP{vkm-}e?6@pt$&D3(}+ z7prCA_Hedo(_U8f7MF3!h||xn1OT!^!^4_If-M$UqES9rq|pg2et7vfS_dF&P9z6F z`u^=ezto?vYHhRNYp}3QDm#dnFR@9(jkUgZd$VKHKMX*|;lInop>Vz3cqrG$pfX>``b?m@q zXzK8OZ2ri8c#iRjmE3t{9Dq&$>PO363;{qa0Lj_AuA+=pa}59u0JH$m%6wg8ThVei w05P~O00{u3<)SGsd)rx@we2j)+P0T6{-&Uuo=Uh?oFQ=N42O zU;;LAboKb74&b4DhnBS3CUR`sRxPEPRvoCq-QPdw+$-=t(o*R=e-EsL9eHWJ?tG=Gizoq>6m$q%&*~m)onOP%AySD8e+g8n;E#ucHKJChZY}>T0s%u-{wr$(CZQHhO+sdA! zZ`;N*vw!wF!-3mKij)lV?BN^aXxnyd&Vp^*if!ArZQHhu>d*f^|9d}s2ugKY!FcLa z>7F>P)sJTh!8Wu3+fF$tjn;O-ux%v8*<-$Y{)O9hC`poG%Zg{)wr$(CZNJ6!pOM>0 zikyLkJAHwN95Vj@ojJqiD(~?3=k`%v9uKz4bB4_$c}DN>vwMM)3r-Q5dT<#6X91jDa4x`k2Imu; z@7htj!R7qenz2o5$Ja4)JmeJ@uc?jhad1jGGK1i3g7X0mKv=reW$?#6MKw4ZM-M;t z`sE^yaF~r}2cjuPGJ)h430U(0FvUO&R&x1rULIiUmghA>adGj32YcVleA;n7@k$0; z8dc5M?0K%_<=p_R#Q`3?(Ep%qA!xM4rml}o z+iPo|F^A%2e+jdKq2RQmd7Wy5F^HrvJ(yxwJxtsAa~3j(Oub6qvnMm2TtWC~s_mZH z6c1OW?Okw6C3CHL7t0-nv!jVjO|>ViPn%}_g!I(y-`OcQ>)V(`R7m=QFo>X1=9%j0 zJgOja{)E{v>ocfqIGIHBk4Wd4Y~PV&63fPn;o#(uDXW8M>SCNx7DRJIuvmS}D!1c2ENmvb;5hL3xnwh&TFvj_?*9chu$P20d;?vSrA)Q4v@ zRvjqHMS&235X3@dqQsS6@>^Oy)Q8tbjwq)+tEJ0EwduI&J_9q4eae|dI2;p&5L9bB zB`VRykSNKs7`eIUDC%Pbt$Ve2(Z@)%F(l0CO3qm=i&Q~u_}`6|o3yk#EFmT8j&A0- z0-Qgh1w0p!Pb3Kf+UHok5gGDVfHjM9S|A=jPhwI+WLg9uC=fo5$uhY^VDvAuD#whS32Twp=lA)V2f`1OUHR{w7J1&ngq|eqOjV{ zb9sg{gR_dw>gRp(@zQ30%0;FB{WC?=k436e6$oHt8(p&+;R$C3C*^;(#!!Cgw!aSI zKGDpHXkkf}epG2>+G;m@I${3ZB}Cv^lW}-G)kr55k&eLZx?dM+nF2`KN*Zl*&ubj+ zf>V4cV6i{cRd>D1ZZ}eGWfw8*8`VY#qn*hm^PcY`3jYs<1$kd&S_mMwtA2Ipp5qQl zTD7xQxWJGIgOZAou=S_LB>`#=cG0aU01Vn;&+ed7a!5Pp{Sv}}tYLIW1)>j2Jqxb@ zFe-|3UG+?2WDI^&Zc!<#T4)P~9i?y4uVU;o6$2uS{w>}1OCl9zqth2Qjx^ENv$krf ze)-=%rB^X>l9YP1Ch*@bMqt(7vc+jO0E0I4K0f)X%4eR^tynmXrpyT8nmXzqm%UDP z_?$KqVIEOoA;Zd9eN9G)(yqC#a`t$yupT}GJ$A6GeQ=1n6(~13z4*|+IVp`tm=`q$ zL@CX!u;psvW^AH**ozJe6$UDdjMLY#Iw+OSLIh_WuGKonZz~VOeb_x}V~c1vbfCiM zEan?>-gn6ATso}iT@qMZYgrwN0>GpbKh}dBR&B*%Xi~WFGa|x5uq!_nFLtGejR2lO z4XcRI)UEAv0L+SlkQ)K8=uN~4MbBb1Qz9bQJ8n9HA~MfX-dA0@5ZG`a9|J|XCZu&! z05}|9O>SI>&o08{^Q{D;W%rpYt~=wi99@iBXh<_0^J|f(ZMT0Y`&Ghv@H#Wk0@yy$ zi_4X*C>iQ2H4Nm#s&9ZgHV2{l$`rpF^DSA3;$M02?Fkt9u!H)NCIRJ<CpLNAw7!8alb)oOACspy#_1*7^|0j4SwwGTx|$>Whn?$Y~5)n zv8dEetMIE>DC$zJkofH16g-(RZ`5T|ZrUzSn@r_}rJ}CY3Xu-Yfr)BS`i!r?YOtB< z_N^%8;+w%0bZFI4KWhQqss$5y254oYYr=c*qu}*zS;_wA%Pl9Jo&^XO&rhR=R;TG_ zLi%LS9Tg>mlWI&5Px8E}p1r`53C)LpClLKG>a@__d!6XzUQAvcAw>q@(K(GDEfndc zud1#5b{cZ$d(UDbl)p+4gG+*1D+NG6hX4N!c1p8h0^m|BKEVqsgObV66`teVQSZ2tu!7v{0n5+uygU(0>gWVhoMW2<6xPaj`1O7S`|P zxn<^+Iz|&&Mwb{(ikGui0=pIqVQ5si(fzS;AIArQ>cwMyubEt-?mR68#K6zOmga#)2!D*%6_{6o`>F69F5{uH8V zj^)Pp?Tmm@Ja_lHh((oeht}Wxx8jIt7Z^k8+{yk=pHh#Z zS}SR(Fgba(A02C~^l?>+y?pfb=SxkY&{;y+v^({;($5VW8x>_E0DJEDFO?~0KQG{s z*~xcI5K-IcDE8#5m4Yfqu6r@>6{5y7WFvj~A*VS-;sE?FJq{7?Daf65jBzFO&I zc(b7<7y3}nX8GpRJX>^|Zz(12#v6SD`l*BRg-#J=ruE5Rt?SI{036A1%IFop8EOov zhH|&r2x#kG%`W@^7>80rLrU{QVs2Mz?OaD_I;I`_)Tzx4%}g$YM-~8k;>S|xXKb%x zaN-xTn_UWFDOK|6?tK~|7fd;+;LDf#M9|cRp4+&4=&9D-hBM;4pT~ea=8%NWp8`<$ zTZ~-!z}@-ZKQty4r&)~i!+7pG^Rq?wP4ZlmciVKg!+!rp`oZFY@Yc%6b$!|D?(EME z8*&Lwoj$k$6jhb#HltB2VltkG*76U9b^RHg?pTDmmfAmSS`1&&r{&6bXqt^-F)pNH zs-)xnZ~cgoYYXw&;!b?JSyj{e@5h^sYvXyjd|Bl)-@1D)@0e*BPt$uAV-ReAqnUIsurH;sgMc2`aT~ubV@t@iD<2Z{5=`pWXR!h>rt?Gxli*fLN;2!+KG@ z^L0mygccLxiaQ3?#`l!R`;EG%DPLTe0|Q{l%5y(};zgIWkz@-r#uyf3vWDpX#W+XZ zI@e*# zb%Ju`oBz` z)za}b05zL#pJ15aNc{FNd?tWuRo3mT+S>kaF#;1zF-}F`LaSxFwo=#D{|d{-&fU*U z{Pr;H9HE;@aDwrjwVE{$|&Xi<| z0Vp@N_%t^=WUIcXx{pl+n}}FNgmI!-&cG~^eZjX1sNJz01o0wbSWO$_jR2ZA(m~CHq+1?dg%5U_&i%Aii z{Qjn`r*etah#c{?%c);~eME~(M!xy`?KB=2XZWR~8)3EfgHR8XLKsi6Ipu)|Y(~TyR561oCa8Msu@)`t zs-T&eBd>DzK++n?j1CRY64ycj(=(Z|4 z&CRZv56=db(i3&N$e>zRjNQkq2*wg@N~o`t`bJ>6SFBYD7DX5pK)0S~+TZlxt@xy7 zK0G_{fe!#wIW{?7$%gB7kda8r9RN5y32xb<@wr<1Qvg-tfEsZ?y&RV(-HNEP$%FJ@i7i^M2b(!boJX?AvNRm|g#>DajNY_{5LLetO$&04g1P z@NJ(S`{NS>w_kPB^|tcKPNf*ob?(dS?UocLkc8WzhO63bxZIH4)_eI}mwhp$3(K-3 M`Rq!PEMwvN7)Wj`lK=n! literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..caefcc434a9f908b9bea7412fea45ec3d0789190 GIT binary patch literal 2512 zcmV;>2`~0iNk&G<2><|BMM6+kP&iDy2><{ukH8}k^@f7Bjhr_8S>OBtAR;C}$DMe% z0eFkrHMj(d@6Xe}}Zhc=bI90dO zOr>SEY}jP^c3x4lgY+_q8D9Wy=xj*r;o$hji0D0PYZZt{I_2e#kz+qP}n zw#N44|EFsHucDo8TYsERwl>eew(ZoF3zls=QDtqRu_d6OAmoNOfchhW z`2PcyWH9dfgCt%I;3%izD`iKHu15aS=TdEH3`y>dvs& zz1i-$xQIRn-2>eRx&$~qI9PwD)xq;_tQOs zwm)|0-${$0j3@+voN?Ku4tWP#qEL6Ha8cb$@1d3GD*_;H-c5GMIkI{NTU_@(1>iWR z5J~#Mw#jN`C%ON9+sA3Cmmu&w zW%zekzR#UX3+}d~p&toXdWXLu|4%(003K{h zG02G=qF|G9X#yowE?hQ*_*?e*@cqpz(n!c$xQZ$OmrlO(Bc8W^<)9{Nh=O-gElow4 z*`w`gnzBLzoqOG(=6jfzx76q}9vTxa0E+{NHyJW}=iAU+u z;$cWgIqK5?pi7%s%EbAc`BL}YjzVG0S&}h(Vqx+7HP!K9JXJ@RS&O#bLWpfHhCysp zzRRfCXu)BkW3-nO9j-)!!-2Vh1@&3D8X8W&I!5G3I=F@mv4OY|MQo)1p1BhR4kzXS zE3yKIg71(AkuY+!r3XQm2{{uXN|hFj(^=XEeC2b^2Q*v9m3q7(nqP24j=%vo7RGp) z_;Rr!=(0v0AVl?4fH7b*u$tfCs}*xFN|v?_@YRl4XzoP%<}Z2Qxn1F|s(4qG&P`d{ znzep|s%}g}o9IN6jDrn|oOPk^W@2wSwotmo*)UCVLLE+zB2OQu7)bSE3R>^o!bZQy z^iv~_b22P+`nHVoQcXE3-S^CL{(z@Gr=WE`9IWP#5~Tw-*6l3UZ@B`3xG+y}M$W*Y z0Vkn#JM1dtDhJC(v2{A#65#BOP}w3c=;$>()t>jo8w+zDZ0U#)!GHiH386fv2h1VV~!C5?R>g`@>mdCYNZ@Ntn^!x z5F-fcWSA1j85~ygThkaN3|cJ}5h37<$Anog46OCb5rH(}m^%XGvErQmIEAmEFU|z4 z69&&)g&={{N?8g4@>&t6FQ*W}dVXmg0gXQ zRR`(05Cya}V=#^(18$Dji5Vy<`a37fg5qddAZf^P7;A1KlqhW!pX zMHExp(?>QxoD5h(IT^VqAayyMP6|;_OBe$=h75`20QXOQan3duz~1Czt9|goe0(4| z*@UBTd#yu&&HQvyrXS{($qijjr&E|QRkqZDQo1xf!Em%J<#SE3r>jlyb2Ai*%hqzO zAVWfzk4Tf!1Pey7X_klb&Xs5ta@A)+ib#3Na2!I2&kZ<%zxtdc0h4GPZRczI&CkGm zE}QGziNepqyzj(kaN^*m?`Fcwt!#Bkh7Y8uz229kE>9$+Yc5&aiml_~q5o!(roXr< zSWzjX4CRopIddh()jO_+7HIu8qolHTl^_{e^RPVbhfOTpHRhPWE@Qn^^1dYrSb}R# z7>#`hB5?pko}OW=T3`-rv2{F|+J;0NRypfj%MgUwlo_+gwBV2jWpcw^i9FnL)tS06 zt;6Xt-BfoY%Ebh7BKZZLB(VxMCmsi9D&HmbIAv8Mj!V_wumBRFsx%|i9FG-@0WJm@ zsPd@RVZ1frvA`I`wHQ2%tIL;AVe*jQNgaD+X{(ZWZRcNqq3QdNa z_;54>lf66SGV=QqT00;mOZ2=i@qUG{~@z~;UcknEy2$0Uo0g)@v{x-s;^y6at z6$t>|h1qk5hF8Go;2au!SOVgZqW!Ig1;qw;0191l z`eJvYnkycF0_21MsCP<4Oiyniy3?oc1_gkdTd8v8d+5Dt2Z%W(A||Uo65Xm*b0_Ur ay$@B62=R literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..399c27a3303e4dc7c39bfd7324dda035523e7126 GIT binary patch literal 6362 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 literal 0 HcmV?d00001 diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..ba2e16e09dd19a21e9a3010527aa66f89cf5a85b GIT binary patch literal 3342 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 CE# + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..483e71d --- /dev/null +++ b/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + bleh + \ No newline at end of file diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..7d22f78 --- /dev/null +++ b/app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +