summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMinteck <contact@minteck.org>2023-01-03 22:01:57 +0100
committerMinteck <contact@minteck.org>2023-01-03 22:01:57 +0100
commit5d7695aa154f294defa17e151d88df0b12c60098 (patch)
tree727ee7068c20ce15cd9652bbe27a8e7f186979e5
downloaddelta-android-5d7695aa154f294defa17e151d88df0b12c60098.tar.gz
delta-android-5d7695aa154f294defa17e151d88df0b12c60098.tar.bz2
delta-android-5d7695aa154f294defa17e151d88df0b12c60098.zip
Initial commit
-rw-r--r--.gitignore16
-rw-r--r--.idea/.gitignore3
-rw-r--r--.idea/.name1
-rw-r--r--.idea/compiler.xml6
-rw-r--r--.idea/deploymentTargetDropDown.xml17
-rw-r--r--.idea/gradle.xml19
-rw-r--r--.idea/jarRepositories.xml25
-rw-r--r--.idea/kotlinc.xml6
-rw-r--r--.idea/misc.xml10
-rw-r--r--TODO.md3
-rw-r--r--app/.gitignore1
-rw-r--r--app/build.gradle.kts61
-rw-r--r--app/proguard-rules.pro21
-rw-r--r--app/release/app-release.apkbin0 -> 5274500 bytes
-rw-r--r--app/release/app-release.apk.zipbin0 -> 4719976 bytes
-rw-r--r--app/release/output-metadata.json20
-rw-r--r--app/src/main/AndroidManifest.xml42
-rw-r--r--app/src/main/ic_launcher-playstore.pngbin0 -> 11606 bytes
-rw-r--r--app/src/main/java/dev/equestria/delta/HTTPRequest.kt61
-rw-r--r--app/src/main/java/dev/equestria/delta/MainActivity.kt510
-rw-r--r--app/src/main/res/drawable-anydpi/ic_stat_name.xml16
-rw-r--r--app/src/main/res/drawable-hdpi/ic_stat_name.pngbin0 -> 369 bytes
-rw-r--r--app/src/main/res/drawable-mdpi/ic_stat_name.pngbin0 -> 312 bytes
-rw-r--r--app/src/main/res/drawable-xhdpi/ic_stat_name.pngbin0 -> 430 bytes
-rw-r--r--app/src/main/res/drawable-xxhdpi/ic_stat_name.pngbin0 -> 976 bytes
-rw-r--r--app/src/main/res/drawable/baseline_home_24.xml10
-rw-r--r--app/src/main/res/drawable/baseline_person_24.xml10
-rw-r--r--app/src/main/res/drawable/baseline_search_24.xml10
-rw-r--r--app/src/main/res/drawable/baseline_text_snippet_24.xml11
-rw-r--r--app/src/main/res/drawable/defaultuser.xml46
-rw-r--r--app/src/main/res/drawable/ic_launcher_foreground.xml33
-rw-r--r--app/src/main/res/drawable/outline_home_24.xml10
-rw-r--r--app/src/main/res/drawable/outline_person_24.xml10
-rw-r--r--app/src/main/res/drawable/outline_search_24.xml10
-rw-r--r--app/src/main/res/drawable/outline_text_snippet_24.xml11
-rw-r--r--app/src/main/res/layout/activity_main.xml77
-rw-r--r--app/src/main/res/menu/action_bar.xml30
-rw-r--r--app/src/main/res/menu/navigation_bar.xml29
-rw-r--r--app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml5
-rw-r--r--app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml5
-rw-r--r--app/src/main/res/mipmap-hdpi/ic_launcher.pngbin0 -> 3593 bytes
-rw-r--r--app/src/main/res/mipmap-hdpi/ic_launcher_round.pngbin0 -> 3593 bytes
-rw-r--r--app/src/main/res/mipmap-mdpi/ic_launcher.pngbin0 -> 2278 bytes
-rw-r--r--app/src/main/res/mipmap-mdpi/ic_launcher_round.pngbin0 -> 2278 bytes
-rw-r--r--app/src/main/res/mipmap-xhdpi/ic_launcher.pngbin0 -> 5255 bytes
-rw-r--r--app/src/main/res/mipmap-xhdpi/ic_launcher_round.pngbin0 -> 5255 bytes
-rw-r--r--app/src/main/res/mipmap-xxhdpi/ic_launcher.pngbin0 -> 8377 bytes
-rw-r--r--app/src/main/res/mipmap-xxhdpi/ic_launcher_round.pngbin0 -> 8377 bytes
-rw-r--r--app/src/main/res/mipmap-xxxhdpi/ic_launcher.pngbin0 -> 12020 bytes
-rw-r--r--app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.pngbin0 -> 12020 bytes
-rw-r--r--app/src/main/res/values-fr/strings.xml26
-rw-r--r--app/src/main/res/values-night/themes.xml3
-rw-r--r--app/src/main/res/values/dimens.xml4
-rw-r--r--app/src/main/res/values/ic_launcher_background.xml4
-rw-r--r--app/src/main/res/values/strings.xml26
-rw-r--r--app/src/main/res/values/themes.xml3
-rw-r--r--app/src/main/res/values/values.xml5
-rw-r--r--app/src/main/res/xml/backup_rules.xml1
-rw-r--r--app/src/main/res/xml/data_extraction_rules.xml3
-rw-r--r--app/src/main/res/xml/locales_config.xml4
-rw-r--r--build.gradle.kts31
-rw-r--r--gradle.properties23
-rw-r--r--gradle/wrapper/gradle-wrapper.jarbin0 -> 59203 bytes
-rw-r--r--gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xgradlew185
-rw-r--r--gradlew.bat89
-rw-r--r--settings.gradle.kts9
67 files changed, 1567 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..93bfc47
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,16 @@
+*.iml
+.gradle
+/local.properties
+/.idea/caches
+/.idea/libraries
+/.idea/modules.xml
+/.idea/workspace.xml
+/.idea/navEditor.xml
+/.idea/assetWizardSettings.xml
+.DS_Store
+/build
+/captures
+.externalNativeBuild
+.cxx
+local.properties
+app/google-services.json
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..26d3352
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,3 @@
+# Default ignored files
+/shelf/
+/workspace.xml
diff --git a/.idea/.name b/.idea/.name
new file mode 100644
index 0000000..dd4648f
--- /dev/null
+++ b/.idea/.name
@@ -0,0 +1 @@
+Delta \ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..b589d56
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="CompilerConfiguration">
+ <bytecodeTargetLevel target="17" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml
new file mode 100644
index 0000000..ab2c519
--- /dev/null
+++ b/.idea/deploymentTargetDropDown.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="deploymentTargetDropDown">
+ <targetSelectedWithDropDown>
+ <Target>
+ <type value="QUICK_BOOT_TARGET" />
+ <deviceKey>
+ <Key>
+ <type value="VIRTUAL_DEVICE_PATH" />
+ <value value="$USER_HOME$/.android/avd/Pixel_4_API_TiramisuPrivacySandbox.avd" />
+ </Key>
+ </deviceKey>
+ </Target>
+ </targetSelectedWithDropDown>
+ <timeTargetWasSelectedWithDropDown value="2022-12-27T21:19:50.930476Z" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/gradle.xml b/.idea/gradle.xml
new file mode 100644
index 0000000..d58262b
--- /dev/null
+++ b/.idea/gradle.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="GradleMigrationSettings" migrationVersion="1" />
+ <component name="GradleSettings">
+ <option name="linkedExternalProjectsSettings">
+ <GradleProjectSettings>
+ <option name="testRunner" value="GRADLE" />
+ <option name="distributionType" value="DEFAULT_WRAPPED" />
+ <option name="externalProjectPath" value="/Volumes/Unicorn/delta-android" />
+ <option name="modules">
+ <set>
+ <option value="/Volumes/Unicorn/delta-android" />
+ <option value="/Volumes/Unicorn/delta-android/app" />
+ </set>
+ </option>
+ </GradleProjectSettings>
+ </option>
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..d2ce72d
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="RemoteRepositoriesConfiguration">
+ <remote-repository>
+ <option name="id" value="central" />
+ <option name="name" value="Maven Central repository" />
+ <option name="url" value="https://repo1.maven.org/maven2" />
+ </remote-repository>
+ <remote-repository>
+ <option name="id" value="jboss.community" />
+ <option name="name" value="JBoss Community repository" />
+ <option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
+ </remote-repository>
+ <remote-repository>
+ <option name="id" value="MavenRepo" />
+ <option name="name" value="MavenRepo" />
+ <option name="url" value="https://repo.maven.apache.org/maven2/" />
+ </remote-repository>
+ <remote-repository>
+ <option name="id" value="Google" />
+ <option name="name" value="Google" />
+ <option name="url" value="https://dl.google.com/dl/android/maven2/" />
+ </remote-repository>
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml
new file mode 100644
index 0000000..0e65cea
--- /dev/null
+++ b/.idea/kotlinc.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="KotlinJpsPluginSettings">
+ <option name="version" value="1.7.21" />
+ </component>
+</project> \ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..1896758
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ExternalStorageConfigurationManager" enabled="true" />
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_17" project-jdk-name="17" project-jdk-type="JavaSDK">
+ <output url="file://$PROJECT_DIR$/build/classes" />
+ </component>
+ <component name="ProjectType">
+ <option name="id" value="Android" />
+ </component>
+</project> \ No newline at end of file
diff --git a/TODO.md b/TODO.md
new file mode 100644
index 0000000..dcd7589
--- /dev/null
+++ b/TODO.md
@@ -0,0 +1,3 @@
+# TODO
+
+- About dialog
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..669068d
--- /dev/null
+++ b/app/build.gradle.kts
@@ -0,0 +1,61 @@
+plugins {
+ id("com.android.application")
+ id("org.jetbrains.kotlin.android")
+ id("com.google.gms.google-services")
+}
+
+android {
+ namespace = "dev.equestria.delta"
+ compileSdk = 33
+
+ defaultConfig {
+ applicationId = "dev.equestria.delta"
+ minSdk = 27
+ targetSdk = 33
+ versionCode = 2
+ versionName = "5.0-8"
+
+ testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+ resConfigs("en", "fr")
+ }
+
+ buildFeatures {
+ buildConfig = true
+ }
+
+ buildTypes {
+ getByName("release") {
+ proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
+ }
+ }
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ targetCompatibility = JavaVersion.VERSION_1_8
+ }
+ kotlinOptions {
+ jvmTarget = "1.8"
+ }
+ buildFeatures {
+ viewBinding = true
+ }
+}
+
+dependencies {
+ implementation("com.android.volley:volley:1.2.1")
+ implementation("androidx.core:core-ktx:1.9.0")
+ implementation("androidx.appcompat:appcompat:1.5.1")
+ implementation("com.google.android.material:material:1.7.0")
+ implementation("androidx.constraintlayout:constraintlayout:2.1.4")
+ implementation("androidx.lifecycle:lifecycle-livedata-ktx:2.5.1")
+ implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1")
+ implementation("androidx.navigation:navigation-fragment-ktx:2.5.3")
+ implementation("androidx.navigation:navigation-ui-ktx:2.5.3")
+ implementation("androidx.core:core-ktx:1.9.0")
+ testImplementation("junit:junit:4.13.2")
+ androidTestImplementation("androidx.test.ext:junit:1.1.4")
+ androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
+ implementation("com.squareup.picasso:picasso:2.8")
+ implementation(platform("com.google.firebase:firebase-bom:31.1.1"))
+ implementation("com.google.firebase:firebase-analytics-ktx")
+ implementation("com.google.firebase:firebase-messaging-ktx")
+} \ No newline at end of file
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..ff59496
--- /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.kts.
+#
+# 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/app-release.apk b/app/release/app-release.apk
new file mode 100644
index 0000000..b53f9dc
--- /dev/null
+++ b/app/release/app-release.apk
Binary files differ
diff --git a/app/release/app-release.apk.zip b/app/release/app-release.apk.zip
new file mode 100644
index 0000000..7cdcd1a
--- /dev/null
+++ b/app/release/app-release.apk.zip
Binary files differ
diff --git a/app/release/output-metadata.json b/app/release/output-metadata.json
new file mode 100644
index 0000000..b6a0617
--- /dev/null
+++ b/app/release/output-metadata.json
@@ -0,0 +1,20 @@
+{
+ "version": 3,
+ "artifactType": {
+ "type": "APK",
+ "kind": "Directory"
+ },
+ "applicationId": "dev.equestria.delta",
+ "variantName": "release",
+ "elements": [
+ {
+ "type": "SINGLE",
+ "filters": [],
+ "attributes": [],
+ "versionCode": 2,
+ "versionName": "5.0-8",
+ "outputFile": "app-release.apk"
+ }
+ ],
+ "elementType": "File"
+} \ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..297d49c
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="dev.equestria.delta">
+
+ <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
+ <uses-permission android:name="android.permission.INTERNET" />
+
+ <application
+ android:allowBackup="true"
+ android:dataExtractionRules="@xml/data_extraction_rules"
+ android:fullBackupContent="@xml/backup_rules"
+ android:icon="@mipmap/ic_launcher"
+ android:label="@string/app_name"
+ android:localeConfig="@xml/locales_config"
+ android:roundIcon="@mipmap/ic_launcher_round"
+ android:supportsRtl="true"
+ android:theme="@style/Theme.Delta"
+ tools:targetApi="33">
+ <activity
+ android:name=".MainActivity"
+ android:exported="true"
+ android:label="@string/app_launch_name">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ <intent-filter android:autoVerify="true">
+ <action android:name="android.intent.action.VIEW" />
+
+ <category android:name="android.intent.category.DEFAULT" />
+ <category android:name="android.intent.category.BROWSABLE" />
+
+ <data android:scheme="http" />
+ <data android:scheme="https" />
+ <data android:host="delta.equestria.dev" />
+ </intent-filter>
+ </activity>
+ </application>
+
+</manifest> \ 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 0000000..118d501
--- /dev/null
+++ b/app/src/main/ic_launcher-playstore.png
Binary files differ
diff --git a/app/src/main/java/dev/equestria/delta/HTTPRequest.kt b/app/src/main/java/dev/equestria/delta/HTTPRequest.kt
new file mode 100644
index 0000000..1bebbc0
--- /dev/null
+++ b/app/src/main/java/dev/equestria/delta/HTTPRequest.kt
@@ -0,0 +1,61 @@
+package dev.equestria.delta
+
+import android.content.Context
+import android.content.res.Resources
+import android.util.Log
+import com.android.volley.Request
+import com.android.volley.toolbox.JsonObjectRequest
+import com.android.volley.toolbox.Volley
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import dev.equestria.delta.databinding.ActivityMainBinding
+import org.json.JSONObject
+import kotlin.system.exitProcess
+
+class HTTPRequest {
+ companion object {
+ fun request(
+ url: String,
+ session: String?,
+ context: Context,
+ resources: Resources,
+ activity: MainActivity,
+ initial: Boolean,
+ binding: ActivityMainBinding,
+ positiveCallback: (JSONObject) -> Unit = { },
+ negativeCallback: (Unit) -> Unit = { }
+ ) {
+ val volleyQueue = Volley.newRequestQueue(context)
+
+ val data = JSONObject()
+ data.put("session", session)
+
+ val jsonObjectRequest = JsonObjectRequest(Request.Method.POST, url, data,
+
+ { response ->
+ Log.i("HTTPRequest", response.toString())
+ positiveCallback(response)
+ },
+
+ { error ->
+ MaterialAlertDialogBuilder(context).setCancelable(false)
+ .setTitle(resources.getString(R.string.offline_title))
+ .setMessage(resources.getString(R.string.offline_message))
+ .setPositiveButton(resources.getString(R.string.offline_retry)) { _, _ ->
+ if (initial) {
+ activity.initialCheck()
+ } else {
+ binding.webView.reload()
+ }
+ }.setNegativeButton(resources.getString(R.string.offline_close)) { _, _ ->
+ activity.moveTaskToBack(true)
+ exitProcess(0)
+ }.setNeutralButton(resources.getString(R.string.offline_status)) { _, _ ->
+ negativeCallback(Unit)
+ }.show()
+ Log.e("HTTPRequest", "Request error: ${error.localizedMessage}")
+ })
+
+ volleyQueue.add(jsonObjectRequest)
+ }
+ }
+} \ No newline at end of file
diff --git a/app/src/main/java/dev/equestria/delta/MainActivity.kt b/app/src/main/java/dev/equestria/delta/MainActivity.kt
new file mode 100644
index 0000000..7e239c6
--- /dev/null
+++ b/app/src/main/java/dev/equestria/delta/MainActivity.kt
@@ -0,0 +1,510 @@
+package dev.equestria.delta
+
+import android.Manifest
+import android.annotation.SuppressLint
+import android.app.NotificationChannel
+import android.app.NotificationManager
+import android.content.Intent
+import android.content.res.Resources.getSystem
+import android.graphics.Bitmap
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.Drawable
+import android.net.Uri
+import android.os.Build
+import android.os.Bundle
+import android.util.Log
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import android.view.ViewGroup
+import android.webkit.CookieManager
+import android.webkit.WebResourceRequest
+import android.webkit.WebResourceResponse
+import android.webkit.WebView
+import android.webkit.WebViewClient
+import androidx.appcompat.app.AppCompatActivity
+import androidx.core.app.ActivityCompat
+import com.google.android.gms.tasks.OnCompleteListener
+import com.google.android.material.color.DynamicColors
+import com.google.android.material.dialog.MaterialAlertDialogBuilder
+import com.google.android.material.elevation.SurfaceColors
+import com.google.firebase.messaging.FirebaseMessaging
+import com.squareup.picasso.Picasso
+import com.squareup.picasso.Target
+import dev.equestria.delta.databinding.ActivityMainBinding
+import org.json.JSONObject
+import java.net.URL
+import kotlin.system.exitProcess
+
+val Int.dp: Int get() = (this / getSystem().displayMetrics.density).toInt()
+
+class MainActivity : AppCompatActivity() {
+
+ private lateinit var binding: ActivityMainBinding
+ private lateinit var appMenu: Menu
+ private lateinit var navigationMenu: Menu
+ private var changedNavItem: Boolean = false
+ private var deltaInformation: JSONObject? = null
+ private var lastRequestLoggedIn: Boolean = false
+
+ override fun onCreateOptionsMenu(menu: Menu?): Boolean {
+ val inflater = menuInflater
+ inflater.inflate(R.menu.action_bar, menu)
+ if (menu != null) {
+ appMenu = menu
+ }
+ return true
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+ when (item.itemId) {
+ R.id.user -> {
+ binding.webView.loadUrl("${getString(R.string.delta_root)}/profile")
+ return true
+ }
+
+ R.id.btn_forward -> {
+ if (binding.webView.canGoForward()) binding.webView.goForward()
+ return true
+ }
+
+ R.id.btn_reload -> {
+ binding.webView.reload()
+ return true
+ }
+
+ R.id.btn_user_logout -> {
+ binding.webView.loadUrl("${getString(R.string.delta_root)}/logout")
+ return true
+ }
+
+ R.id.btn_about -> {
+ MaterialAlertDialogBuilder(binding.root.context).setTitle(
+ getString(
+ R.string.about_title,
+ getString(R.string.app_launch_name)
+ )
+ ).setMessage(
+ getString(
+ R.string.about_message,
+ BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ", " + BuildConfig.BUILD_TYPE + ")",
+ deltaInformation?.get("version") ?: "-",
+ Build.VERSION.RELEASE + " " + Build.VERSION.CODENAME + " (" + Build.VERSION.SDK_INT + ")",
+ System.getProperty("os.version"),
+ Build.DEVICE + "/" + Build.MODEL,
+ Build.VERSION.SECURITY_PATCH,
+ Build.BOARD,
+ Build.BOOTLOADER
+ )
+ ).setPositiveButton(getString(R.string.about_close)) { _, _ -> }.show()
+
+ return true
+ }
+
+ else -> return false
+ }
+ }
+
+ fun getCookie(siteName: String?, CookieName: String?): String? {
+ var cookieValue: String? = null
+ val cookieManager: CookieManager = CookieManager.getInstance()
+ val cookies: String? = cookieManager.getCookie(siteName)
+
+ return if (cookies != null) {
+ val temp = cookies.split(";".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
+ for (ar1 in temp) {
+ if (ar1.contains(CookieName!!)) {
+ val temp1 =
+ ar1.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
+ cookieValue = temp1[1]
+ }
+ }
+ cookieValue
+ } else {
+ ""
+ }
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+ DynamicColors.applyToActivitiesIfAvailable(application)
+
+ val name = getString(R.string.channel_name)
+ val descriptionText = getString(R.string.channel_description)
+ val importance = NotificationManager.IMPORTANCE_DEFAULT
+ val mChannel = NotificationChannel("default", name, importance)
+ mChannel.description = descriptionText
+ val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
+ notificationManager.createNotificationChannel(mChannel)
+
+ if (Build.VERSION.SDK_INT >= 33) {
+ ActivityCompat.requestPermissions(
+ this, arrayOf(Manifest.permission.POST_NOTIFICATIONS), 1
+ )
+ }
+
+ FirebaseMessaging.getInstance().token.addOnCompleteListener(OnCompleteListener { task ->
+ if (!task.isSuccessful) {
+ Log.w("Firebase", "Fetching FCM registration token failed", task.exception)
+ return@OnCompleteListener
+ }
+
+ val token = task.result
+
+ Log.d("Firebase", token)
+
+ HTTPRequest.request(
+ "${getString(R.string.delta_root)}/handoff/fcm/",
+ getCookie(getString(R.string.delta_root), "DeltaSession") + "||||" + token,
+ binding.root.context,
+ resources,
+ this,
+ true,
+ binding
+ ) {
+ val openURL = Intent(Intent.ACTION_VIEW)
+ openURL.data = Uri.parse("https://status.equestria.dev/")
+ startActivity(openURL)
+ }
+ })
+
+ val color = SurfaceColors.SURFACE_2.getColor(this)
+ window.statusBarColor = color
+ window.navigationBarColor = color
+
+ supportActionBar?.setDisplayHomeAsUpEnabled(true)
+
+ binding = ActivityMainBinding.inflate(layoutInflater)
+ setContentView(binding.root)
+
+ navigationMenu = binding.navigationBar.menu
+
+ initialCheck()
+ }
+
+ fun initialCheck() {
+ HTTPRequest.request("${getString(R.string.delta_root)}/handoff/version/",
+ getCookie(getString(R.string.delta_root), "DeltaSession"),
+ binding.root.context,
+ resources,
+ this,
+ true,
+ binding,
+ {
+ deltaInformation = it
+ appMenu.getItem(3).isEnabled = deltaInformation!!.get("loggedIn") as Boolean
+ initialise()
+ }) {
+ val openURL = Intent(Intent.ACTION_VIEW)
+ openURL.data = Uri.parse("https://status.equestria.dev/")
+ startActivity(openURL)
+ }
+ }
+
+ fun routineCheck() {
+ HTTPRequest.request("${getString(R.string.delta_root)}/handoff/version/",
+ getCookie(getString(R.string.delta_root), "DeltaSession"),
+ binding.root.context,
+ resources,
+ this,
+ false,
+ binding,
+ {
+ deltaInformation = it
+ appMenu.getItem(3).isEnabled = deltaInformation!!.get("loggedIn") as Boolean
+
+ if (deltaInformation!!.get("loggedIn") as Boolean || lastRequestLoggedIn) {
+ refreshAvatar(deltaInformation!!)
+ lastRequestLoggedIn = deltaInformation!!.get("loggedIn") as Boolean
+
+ if (lastRequestLoggedIn) {
+ appMenu.getItem(0).title = deltaInformation!!.get("name") as CharSequence?
+ } else {
+ appMenu.getItem(0).title = getString(R.string.navigation_profile)
+ }
+ }
+ }) {
+ val openURL = Intent(Intent.ACTION_VIEW)
+ openURL.data = Uri.parse("https://status.equestria.dev/")
+ startActivity(openURL)
+ }
+ }
+
+ fun refreshAvatar(deltaInformation: JSONObject) {
+ val target = object : Target {
+ override fun onBitmapLoaded(bitmap: Bitmap?, from: Picasso.LoadedFrom?) {
+ try {
+ if (bitmap != null) {
+ appMenu.getItem(0).icon = BitmapDrawable(resources, bitmap)
+ }
+ } catch (ex: IllegalArgumentException) {
+ Log.e("Picasso", ex.toString())
+ }
+ }
+
+ override fun onBitmapFailed(e: Exception?, errorDrawable: Drawable?) {
+ Log.e("Picasso", e.toString())
+ }
+
+ override fun onPrepareLoad(placeHolderDrawable: Drawable?) {}
+ }
+
+ Picasso.get().load(
+ "${getString(R.string.delta_root)}/handoff/avatar/?token=" + deltaInformation.get("session")
+ ).into(target)
+ }
+
+ @SuppressLint("SetJavaScriptEnabled")
+ fun initialise() {
+ binding.webView.webViewClient = object : WebViewClient() {
+ override fun onPageFinished(view: WebView?, url: String?) {
+ appMenu.getItem(2).isEnabled = true
+ binding.progressBar.visibility = View.INVISIBLE
+ binding.webView.visibility = View.VISIBLE
+
+ val pageTitle = binding.webView.title?.split("·")?.get(0)?.trim() ?: ""
+
+ if (pageTitle.startsWith("(") && pageTitle.split(") ").count() > 1) {
+ title = pageTitle.split(")")[1].trim()
+ binding.navigationBar.getOrCreateBadge(R.id.navigation_profile).isVisible = true
+ } else {
+ title = pageTitle
+ binding.navigationBar.getOrCreateBadge(R.id.navigation_profile).isVisible =
+ false
+ }
+
+ if (URL(url).path.startsWith("/login")) {
+ binding.navigationBar.visibility = View.GONE
+ val params = binding.webView.layoutParams as ViewGroup.MarginLayoutParams
+ params.setMargins(0, 0, 0, 80.dp)
+ supportActionBar?.hide()
+
+ val color = SurfaceColors.SURFACE_0.getColor(binding.root.context)
+ window.statusBarColor = color
+ window.navigationBarColor = color
+ } else {
+ val params = binding.webView.layoutParams as ViewGroup.MarginLayoutParams
+ params.setMargins(0, 0, 0, 0)
+ binding.navigationBar.visibility = View.VISIBLE
+ supportActionBar?.show()
+
+ val color = SurfaceColors.SURFACE_2.getColor(binding.root.context)
+ window.statusBarColor = color
+ window.navigationBarColor = color
+ }
+
+ routineCheck()
+ appMenu.getItem(1).isEnabled = binding.webView.canGoForward()
+ }
+
+ override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
+ appMenu.getItem(2).isEnabled = false
+ binding.progressBar.visibility = View.VISIBLE
+
+ if (!changedNavItem) {
+ if (URL(url).path.startsWith("/articles/") || URL(url).path === "/articles" || URL(
+ url
+ ).path.startsWith("/edit/") || URL(url).path === "/edit" || URL(url).path.startsWith(
+ "/request/"
+ ) || URL(url).path === "/request" || URL(url).path.startsWith("/people/") || URL(
+ url
+ ).path === "/people" || URL(url).path.startsWith("/gallery/") || URL(url).path === "/gallery"
+ ) {
+ changedNavItem = true
+ binding.navigationBar.selectedItemId = R.id.navigation_content
+ } else if (URL(url).path.startsWith("/search/") || URL(url).path === "/search") {
+ changedNavItem = true
+ binding.navigationBar.selectedItemId = R.id.navigation_search
+ } else if (URL(url).path.startsWith("/admin/") || URL(url).path === "/admin" || URL(
+ url
+ ).path.startsWith("/profile/") || URL(url).path === "/profile" || URL(url).path.startsWith(
+ "/requests/"
+ ) || URL(url).path === "/requests" || URL(url).path.startsWith("/plus/") || URL(
+ url
+ ).path === "/plus" || URL(url).path.startsWith("/alerts/") || URL(url).path === "/alerts" || URL(
+ url
+ ).path.startsWith("/support/") || URL(url).path === "/support" || URL(url).path.startsWith(
+ "/mobile_profile/"
+ ) || URL(url).path === "/mobile_profile"
+ ) {
+ changedNavItem = true
+ binding.navigationBar.selectedItemId = R.id.navigation_profile
+ } else {
+ changedNavItem = true
+ binding.navigationBar.selectedItemId = R.id.navigation_dashboard
+ }
+ }
+
+ appMenu.getItem(1).isEnabled = binding.webView.canGoForward()
+ changedNavItem = false
+ }
+
+ override fun shouldInterceptRequest(
+ view: WebView, request: WebResourceRequest
+ ): WebResourceResponse? {
+ request.url.host?.let { Log.i("MainActivity", '"' + it + '"') }
+
+ if (request.url.host != getString(R.string.delta_root).split("/")[2]) {
+ val openURL = Intent(Intent.ACTION_VIEW)
+ openURL.data = request.url
+ startActivity(openURL)
+
+ return WebResourceResponse("text/javascript", "UTF-8", null)
+ }
+
+ return null
+ }
+ }
+
+ binding.navigationBar.setOnItemSelectedListener { item ->
+ when (item.itemId) {
+ R.id.navigation_dashboard -> {
+ setNavigationBarSelected(item.itemId)
+
+ if (!changedNavItem) {
+ changedNavItem = true
+ binding.webView.loadUrl("${getString(R.string.delta_root)}/")
+ }
+
+ true
+ }
+
+ R.id.navigation_search -> {
+ setNavigationBarSelected(item.itemId)
+
+ if (!changedNavItem) {
+ changedNavItem = true
+ binding.webView.loadUrl("${getString(R.string.delta_root)}/search")
+ }
+
+ true
+ }
+
+ R.id.navigation_content -> {
+ setNavigationBarSelected(item.itemId)
+
+ if (!changedNavItem) {
+ changedNavItem = true
+ binding.webView.loadUrl("${getString(R.string.delta_root)}/content")
+ }
+
+ true
+ }
+
+ R.id.navigation_profile -> {
+ setNavigationBarSelected(item.itemId)
+
+ if (!changedNavItem) {
+ changedNavItem = true
+ binding.webView.loadUrl("${getString(R.string.delta_root)}/profile")
+ }
+
+ true
+ }
+
+ else -> false
+ }
+ }
+
+ binding.navigationBar.menu.findItem(R.id.navigation_profile).iconTintList = null
+
+ binding.webView.settings.javaScriptEnabled = true
+
+ handoffApi31()
+ }
+
+ fun setNavigationBarSelected(id: Int) {
+ binding.navigationBar.menu.findItem(R.id.navigation_dashboard)
+ .setIcon(R.drawable.outline_home_24)
+ binding.navigationBar.menu.findItem(R.id.navigation_content)
+ .setIcon(R.drawable.outline_text_snippet_24)
+ binding.navigationBar.menu.findItem(R.id.navigation_search)
+ .setIcon(R.drawable.outline_search_24)
+ binding.navigationBar.menu.findItem(R.id.navigation_profile)
+ .setIcon(R.drawable.outline_person_24)
+
+ when (id) {
+ R.id.navigation_dashboard -> {
+ binding.navigationBar.menu.findItem(R.id.navigation_dashboard)
+ .setIcon(R.drawable.baseline_home_24)
+ }
+
+ R.id.navigation_content -> {
+ binding.navigationBar.menu.findItem(R.id.navigation_content)
+ .setIcon(R.drawable.baseline_text_snippet_24)
+ }
+
+ R.id.navigation_search -> {
+ binding.navigationBar.menu.findItem(R.id.navigation_search)
+ .setIcon(R.drawable.baseline_search_24)
+ }
+
+ R.id.navigation_profile -> {
+ binding.navigationBar.menu.findItem(R.id.navigation_profile)
+ .setIcon(R.drawable.baseline_person_24)
+ }
+
+ else -> {}
+ }
+ }
+
+ fun handoffApi31() {
+ val colors: ArrayList<Int> = arrayListOf(
+ SurfaceColors.SURFACE_0.getColor(this),
+ SurfaceColors.SURFACE_1.getColor(this),
+ SurfaceColors.SURFACE_2.getColor(this),
+ SurfaceColors.SURFACE_3.getColor(this),
+ SurfaceColors.SURFACE_4.getColor(this),
+ SurfaceColors.SURFACE_5.getColor(this),
+ binding.textView.currentTextColor,
+ binding.textView.currentHintTextColor,
+ binding.button.currentTextColor,
+ binding.button.highlightColor
+ )
+
+ val appLinkAction = intent.action
+ val appLinkData: Uri? = intent.data
+ if (Intent.ACTION_VIEW == appLinkAction) {
+ if (appLinkData != null) {
+ binding.webView.loadUrl(
+ "${getString(R.string.delta_root)}/handoff/?version=" + BuildConfig.VERSION_CODE + "&colors=" + colors.joinToString(
+ ","
+ ) + "&return=" + java.net.URLEncoder.encode(appLinkData.path, "utf-8")
+ )
+ } else {
+ binding.webView.loadUrl(
+ "${getString(R.string.delta_root)}/handoff/?version=" + BuildConfig.VERSION_CODE + "&colors=" + colors.joinToString(
+ ","
+ ) + "&return=/"
+ )
+ }
+ } else {
+ binding.webView.loadUrl(
+ "${getString(R.string.delta_root)}/handoff/?version=" + BuildConfig.VERSION_CODE + "&colors=" + colors.joinToString(
+ ","
+ ) + "&return=/"
+ )
+ }
+ }
+
+ @Deprecated("Deprecated in Java")
+ override fun onBackPressed() {
+ if (binding.webView.canGoBack()) {
+ binding.webView.goBack()
+ } else {
+ moveTaskToBack(true)
+ exitProcess(0)
+ }
+ }
+
+ override fun onSupportNavigateUp(): Boolean {
+ if (binding.webView.canGoBack()) {
+ binding.webView.goBack()
+ } else {
+ moveTaskToBack(true)
+ exitProcess(0)
+ }
+
+ return true
+ }
+} \ No newline at end of file
diff --git a/app/src/main/res/drawable-anydpi/ic_stat_name.xml b/app/src/main/res/drawable-anydpi/ic_stat_name.xml
new file mode 100644
index 0000000..e34aed3
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_stat_name.xml
@@ -0,0 +1,16 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="#FFFFFF"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+ <group
+ android:scaleX="0.92"
+ android:scaleY="0.92"
+ android:translateX="20.48"
+ android:translateY="20.48">
+ <path
+ android:fillColor="#FF000000"
+ android:pathData="M255.6,100.4l175,350.6H80.5L255.6,100.4M255.6,13.3c-7.1,0 -14.2,3.7 -17.9,11L14.1,472.1C7.5,485.4 17.2,501 32,501h447.1c14.9,0 24.5,-15.6 17.9,-28.9L273.5,24.3C269.8,16.9 262.7,13.3 255.6,13.3L255.6,13.3z" />
+ </group>
+</vector>
diff --git a/app/src/main/res/drawable-hdpi/ic_stat_name.png b/app/src/main/res/drawable-hdpi/ic_stat_name.png
new file mode 100644
index 0000000..ac129b5
--- /dev/null
+++ b/app/src/main/res/drawable-hdpi/ic_stat_name.png
Binary files differ
diff --git a/app/src/main/res/drawable-mdpi/ic_stat_name.png b/app/src/main/res/drawable-mdpi/ic_stat_name.png
new file mode 100644
index 0000000..9e11a41
--- /dev/null
+++ b/app/src/main/res/drawable-mdpi/ic_stat_name.png
Binary files differ
diff --git a/app/src/main/res/drawable-xhdpi/ic_stat_name.png b/app/src/main/res/drawable-xhdpi/ic_stat_name.png
new file mode 100644
index 0000000..a3bb50b
--- /dev/null
+++ b/app/src/main/res/drawable-xhdpi/ic_stat_name.png
Binary files differ
diff --git a/app/src/main/res/drawable-xxhdpi/ic_stat_name.png b/app/src/main/res/drawable-xxhdpi/ic_stat_name.png
new file mode 100644
index 0000000..e2cf94d
--- /dev/null
+++ b/app/src/main/res/drawable-xxhdpi/ic_stat_name.png
Binary files differ
diff --git a/app/src/main/res/drawable/baseline_home_24.xml b/app/src/main/res/drawable/baseline_home_24.xml
new file mode 100644
index 0000000..993f3ab
--- /dev/null
+++ b/app/src/main/res/drawable/baseline_home_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="#000000"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z" />
+</vector>
diff --git a/app/src/main/res/drawable/baseline_person_24.xml b/app/src/main/res/drawable/baseline_person_24.xml
new file mode 100644
index 0000000..9a48b63
--- /dev/null
+++ b/app/src/main/res/drawable/baseline_person_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="#000000"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z" />
+</vector>
diff --git a/app/src/main/res/drawable/baseline_search_24.xml b/app/src/main/res/drawable/baseline_search_24.xml
new file mode 100644
index 0000000..d3b13cf
--- /dev/null
+++ b/app/src/main/res/drawable/baseline_search_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="#000000"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
+</vector>
diff --git a/app/src/main/res/drawable/baseline_text_snippet_24.xml b/app/src/main/res/drawable/baseline_text_snippet_24.xml
new file mode 100644
index 0000000..99ed06c
--- /dev/null
+++ b/app/src/main/res/drawable/baseline_text_snippet_24.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:autoMirrored="true"
+ android:tint="#000000"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M20.41,8.41l-4.83,-4.83C15.21,3.21 14.7,3 14.17,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V9.83C21,9.3 20.79,8.79 20.41,8.41zM7,7h7v2H7V7zM17,17H7v-2h10V17zM17,13H7v-2h10V13z" />
+</vector>
diff --git a/app/src/main/res/drawable/defaultuser.xml b/app/src/main/res/drawable/defaultuser.xml
new file mode 100644
index 0000000..c6ee512
--- /dev/null
+++ b/app/src/main/res/drawable/defaultuser.xml
@@ -0,0 +1,46 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:width="512dp"
+ android:height="512dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512"
+ tools:ignore="VectorRaster">
+ <path android:pathData="M256,256m-256,0a256,256 0,1 1,512 0a256,256 0,1 1,-512 0">
+ <aapt:attr name="android:fillColor">
+ <gradient
+ android:endX="437.02"
+ android:endY="74.98"
+ android:startX="74.98"
+ android:startY="437.02"
+ android:type="linear">
+ <item
+ android:color="#FFE6E6E6"
+ android:offset="0" />
+ <item
+ android:color="#FFF2F2F2"
+ android:offset="1" />
+ </gradient>
+ </aapt:attr>
+ </path>
+ <path android:pathData="M373.4,296.6c25.4,0 46,20.6 46,45.9c0,0 0,0 0,0v18.8c0,11.7 -3.7,23.1 -10.5,32.7c-31.6,44.2 -83.2,66.1 -153,66.1c-69.9,0 -121.5,-21.9 -153,-66.1c-6.8,-9.5 -10.4,-20.9 -10.4,-32.6v-18.8c0,-25.4 20.6,-46 45.9,-46c0,0 0,0 0,0L373.4,296.6L373.4,296.6zM255.8,51.5c56.4,0 102.2,45.7 102.2,102.1c0,56.4 -45.7,102.2 -102.1,102.2c0,0 0,0 0,0c-56.4,0 -102.2,-45.7 -102.2,-102.2S199.4,51.5 255.8,51.5z">
+ <aapt:attr name="android:fillColor">
+ <gradient
+ android:endX="391"
+ android:endY="414.61"
+ android:startX="120.67"
+ android:startY="144.28"
+ android:type="linear">
+ <item
+ android:color="#E3E3E3"
+ android:offset="0" />
+ <item
+ android:color="#E0E0E0"
+ android:offset="0.5" />
+ <item
+ android:color="#FFFFFF"
+ android:offset="1" />
+ </gradient>
+ </aapt:attr>
+ </path>
+</vector>
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..bf017fc
--- /dev/null
+++ b/app/src/main/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,33 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt"
+ android:width="108dp"
+ android:height="108dp"
+ android:viewportWidth="512"
+ android:viewportHeight="512">
+ <group
+ android:scaleX="0.34"
+ android:scaleY="0.34"
+ android:translateX="168.96"
+ android:translateY="168.96">
+ <path android:pathData="M237.7,24.3L14.1,472.1C7.5,485.4 17.2,501 32,501h447.1c14.9,0 24.5,-15.6 17.9,-28.9L273.5,24.3C266.1,9.6 245.1,9.6 237.7,24.3z">
+ <aapt:attr name="android:fillColor">
+ <gradient
+ android:endX="437.58"
+ android:endY="550.88"
+ android:startX="73.62"
+ android:startY="186.92"
+ android:type="linear">
+ <item
+ android:color="#FFE44857"
+ android:offset="0" />
+ <item
+ android:color="#FFC711E1"
+ android:offset="0.5" />
+ <item
+ android:color="#FF7F52FF"
+ android:offset="1" />
+ </gradient>
+ </aapt:attr>
+ </path>
+ </group>
+</vector>
diff --git a/app/src/main/res/drawable/outline_home_24.xml b/app/src/main/res/drawable/outline_home_24.xml
new file mode 100644
index 0000000..dcfedda
--- /dev/null
+++ b/app/src/main/res/drawable/outline_home_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="#000000"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,5.69l5,4.5V18h-2v-6H9v6H7v-7.81l5,-4.5M12,3L2,12h3v8h6v-6h2v6h6v-8h3L12,3z" />
+</vector>
diff --git a/app/src/main/res/drawable/outline_person_24.xml b/app/src/main/res/drawable/outline_person_24.xml
new file mode 100644
index 0000000..e1c804c
--- /dev/null
+++ b/app/src/main/res/drawable/outline_person_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="#000000"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,6c1.1,0 2,0.9 2,2s-0.9,2 -2,2 -2,-0.9 -2,-2 0.9,-2 2,-2m0,10c2.7,0 5.8,1.29 6,2L6,18c0.23,-0.72 3.31,-2 6,-2m0,-12C9.79,4 8,5.79 8,8s1.79,4 4,4 4,-1.79 4,-4 -1.79,-4 -4,-4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z" />
+</vector>
diff --git a/app/src/main/res/drawable/outline_search_24.xml b/app/src/main/res/drawable/outline_search_24.xml
new file mode 100644
index 0000000..d3b13cf
--- /dev/null
+++ b/app/src/main/res/drawable/outline_search_24.xml
@@ -0,0 +1,10 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:tint="#000000"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M15.5,14h-0.79l-0.28,-0.27C15.41,12.59 16,11.11 16,9.5 16,5.91 13.09,3 9.5,3S3,5.91 3,9.5 5.91,16 9.5,16c1.61,0 3.09,-0.59 4.23,-1.57l0.27,0.28v0.79l5,4.99L20.49,19l-4.99,-5zM9.5,14C7.01,14 5,11.99 5,9.5S7.01,5 9.5,5 14,7.01 14,9.5 11.99,14 9.5,14z" />
+</vector>
diff --git a/app/src/main/res/drawable/outline_text_snippet_24.xml b/app/src/main/res/drawable/outline_text_snippet_24.xml
new file mode 100644
index 0000000..c52bfc5
--- /dev/null
+++ b/app/src/main/res/drawable/outline_text_snippet_24.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:autoMirrored="true"
+ android:tint="#000000"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M14.17,5L19,9.83V19H5V5L14.17,5L14.17,5M14.17,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V9.83c0,-0.53 -0.21,-1.04 -0.59,-1.41l-4.83,-4.83C15.21,3.21 14.7,3 14.17,3L14.17,3zM7,15h10v2H7V15zM7,11h10v2H7V11zM7,7h7v2H7V7z" />
+</vector>
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..96d5235
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:id="@+id/textView"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/progressBar" />
+
+ <Button
+ android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible"
+ app:layout_constraintBottom_toTopOf="@+id/webView"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ tools:text="e" />
+
+ <com.google.android.material.bottomnavigation.BottomNavigationView
+ android:id="@+id/navigationBar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:hapticFeedbackEnabled="true"
+ android:soundEffectsEnabled="true"
+ app:labelVisibilityMode="labeled"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:menu="@menu/navigation_bar" />
+
+ <WebView
+ android:id="@+id/webView"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginBottom="80dp"
+ android:saveEnabled="true"
+ android:visibility="invisible"
+ app:layout_constraintBottom_toTopOf="@id/navigationBar"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/progressBar">
+
+ </WebView>
+
+ <ProgressBar
+ android:id="@+id/progressBar"
+ style="@android:style/Widget.DeviceDefault.Light.ProgressBar.Horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="-8dp"
+ android:indeterminate="true"
+ android:padding="0dp"
+ android:paddingHorizontal="0dp"
+ android:paddingVertical="0dp"
+ android:paddingStart="0dp"
+ android:paddingLeft="0dp"
+ android:paddingTop="0dp"
+ android:paddingEnd="0dp"
+ android:paddingRight="0dp"
+ android:paddingBottom="0dp"
+ app:barrierMargin="0dp"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent" />
+
+</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file
diff --git a/app/src/main/res/menu/action_bar.xml b/app/src/main/res/menu/action_bar.xml
new file mode 100644
index 0000000..d25a24c
--- /dev/null
+++ b/app/src/main/res/menu/action_bar.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <item
+ android:id="@+id/user"
+ android:icon="@drawable/defaultuser"
+ android:title="@string/navigation_profile"
+ app:showAsAction="ifRoom" />
+ <item
+ android:id="@+id/btn_forward"
+ android:title="@string/navigation_forward"
+ app:showAsAction="never" />
+
+ <item
+ android:id="@+id/btn_reload"
+ android:title="@string/navigation_reload"
+ app:showAsAction="never" />
+
+ <item
+ android:id="@+id/btn_user_logout"
+ android:enabled="false"
+ android:title="@string/navigation_user_logout"
+ app:showAsAction="never" />
+ <item
+ android:id="@+id/btn_about"
+ android:enabled="true"
+ android:title="@string/navigation_user_about"
+ app:showAsAction="never" />
+</menu> \ No newline at end of file
diff --git a/app/src/main/res/menu/navigation_bar.xml b/app/src/main/res/menu/navigation_bar.xml
new file mode 100644
index 0000000..acaeb0e
--- /dev/null
+++ b/app/src/main/res/menu/navigation_bar.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <item
+ android:id="@+id/navigation_dashboard"
+ android:icon="@drawable/baseline_home_24"
+ android:title="@string/pages_dashboard"
+ app:showAsAction="ifRoom" />
+
+ <item
+ android:id="@+id/navigation_content"
+ android:icon="@drawable/outline_text_snippet_24"
+ android:title="@string/pages_content"
+ app:showAsAction="ifRoom" />
+
+ <item
+ android:id="@+id/navigation_search"
+ android:icon="@drawable/outline_search_24"
+ android:title="@string/pages_search"
+ app:showAsAction="ifRoom" />
+
+ <item
+ android:id="@+id/navigation_profile"
+ android:icon="@drawable/baseline_person_24"
+ android:title="@string/pages_profile"
+ app:showAsAction="ifRoom" />
+
+</menu> \ No newline at end of file
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..ac94b34
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+ <background android:drawable="@color/ic_launcher_background" />
+ <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon> \ 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..ac94b34
--- /dev/null
+++ b/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
+ <background android:drawable="@color/ic_launcher_background" />
+ <foreground android:drawable="@drawable/ic_launcher_foreground" />
+</adaptive-icon> \ No newline at end of file
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher.png b/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..d7273d4
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 0000000..d7273d4
--- /dev/null
+++ b/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher.png b/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..128dfb8
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 0000000..128dfb8
--- /dev/null
+++ b/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..10fc1e0
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..10fc1e0
--- /dev/null
+++ b/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..9e654bf
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..9e654bf
--- /dev/null
+++ b/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..649f939
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
Binary files differ
diff --git a/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 0000000..649f939
--- /dev/null
+++ b/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
Binary files differ
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
new file mode 100644
index 0000000..3d882d1
--- /dev/null
+++ b/app/src/main/res/values-fr/strings.xml
@@ -0,0 +1,26 @@
+<resources>
+ <string name="navigation_forward">Aller en avant</string>
+ <string name="navigation_search">Recherche</string>
+ <string name="navigation_profile">Utilisateur</string>
+ <string name="navigation_reload">Recharger</string>
+ <string name="navigation_user_profile">Profil</string>
+ <string name="navigation_user_logout">Se déconnecter</string>
+ <string name="navigation_user_about">À propos</string>
+ <string name="about_title">À propos de %1$s</string>
+ <string name="about_message">Une application Android pour la plate-forme Delta.\n\nApplication : %1$s\nServeur : %2$s\nAndroid : %3$s\nMàJ : %6$s\nNoyau : %4$s\nAppareil : %5$s\nCarte : %7$s\nAmorceur : %8$s</string>
+ <string name="about_close">Fermer</string>
+ <string name="pages_dashboard">Accueil</string>
+ <string name="pages_search">Recherche</string>
+ <string name="pages_profile">Profil</string>
+ <string name="pages_alerts">Alertes</string>
+ <string name="pages_content">Contenu</string>
+ <string name="offline_title">Impossible de se connecter à Delta</string>
+ <string name="offline_message">Nous ne parvenons pas à joindre les serveurs de Delta. Vérifiez votre connexion Internet et réessayez.</string>
+ <string name="offline_close">Quitter</string>
+ <string name="offline_retry">Réessayer</string>
+ <string name="channel_name">Alertes Delta</string>
+ <string name="channel_description">Pour les utilisateurs Delta Ultra uniquement. Alertes qui apparaissent sur votre profil.</string>
+ <string name="about_copy">Copier</string>
+ <string name="about_copy_done">Informations copiées dans le presse-papiers</string>
+ <string name="offline_status">Ouvrir l\'état des services</string>
+</resources> \ No newline at end of file
diff --git a/app/src/main/res/values-night/themes.xml b/app/src/main/res/values-night/themes.xml
new file mode 100644
index 0000000..33d0ef5
--- /dev/null
+++ b/app/src/main/res/values-night/themes.xml
@@ -0,0 +1,3 @@
+<resources>
+ <style name="Theme.Delta" parent="Theme.Material3.DynamicColors.DayNight" />
+</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml
new file mode 100644
index 0000000..51c43ef
--- /dev/null
+++ b/app/src/main/res/values/dimens.xml
@@ -0,0 +1,4 @@
+<resources>
+ <dimen name="activity_horizontal_margin">16dp</dimen>
+ <dimen name="activity_vertical_margin">16dp</dimen>
+</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/ic_launcher_background.xml b/app/src/main/res/values/ic_launcher_background.xml
new file mode 100644
index 0000000..746b9f4
--- /dev/null
+++ b/app/src/main/res/values/ic_launcher_background.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <color name="ic_launcher_background">#E3E3E3</color>
+</resources> \ 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..0cbeecc
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,26 @@
+<resources>
+ <string name="navigation_forward">Navigate down</string>
+ <string name="navigation_search">Search</string>
+ <string name="navigation_profile">User</string>
+ <string name="navigation_reload">Reload</string>
+ <string name="navigation_user_profile">Profile</string>
+ <string name="navigation_user_logout">Log out</string>
+ <string name="navigation_user_about">About</string>
+ <string name="about_title">About %1$s</string>
+ <string name="about_message">An Android app for the Delta platform.\n\nApp: %1$s\nServer: %2$s\nAndroid: %3$s\nSecurity: %6$s\nKernel: %4$s\nDevice: %5$s\nBoard: %7$s\nBootloader: %8$s</string>
+ <string name="about_close">Close</string>
+ <string name="about_copy">Copy</string>
+ <string name="about_copy_done">Copied info to clipboard</string>
+ <string name="pages_dashboard">Home</string>
+ <string name="pages_search">Search</string>
+ <string name="pages_profile">Profile</string>
+ <string name="pages_alerts">Alerts</string>
+ <string name="pages_content">Content</string>
+ <string name="offline_title">Unable to connect to Delta</string>
+ <string name="offline_message">We are currently unable to connect to Delta\'s servers. Check your network connection and try again later.</string>
+ <string name="offline_close">Quit</string>
+ <string name="offline_status">Open status page</string>
+ <string name="offline_retry">Retry</string>
+ <string name="channel_name">Delta alerts</string>
+ <string name="channel_description">For Delta Ultra users only. Alerts that appear on your Delta profile.</string>
+</resources> \ 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..33d0ef5
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,3 @@
+<resources>
+ <style name="Theme.Delta" parent="Theme.Material3.DynamicColors.DayNight" />
+</resources> \ No newline at end of file
diff --git a/app/src/main/res/values/values.xml b/app/src/main/res/values/values.xml
new file mode 100644
index 0000000..ee1eb49
--- /dev/null
+++ b/app/src/main/res/values/values.xml
@@ -0,0 +1,5 @@
+<resources>
+ <string name="app_name" translatable="false">Equestria.dev Delta</string>
+ <string name="app_launch_name" translatable="false">Delta</string>
+ <string name="delta_root" translatable="false">https://delta.equestria.dev</string>
+</resources> \ No newline at end of file
diff --git a/app/src/main/res/xml/backup_rules.xml b/app/src/main/res/xml/backup_rules.xml
new file mode 100644
index 0000000..c981ec0
--- /dev/null
+++ b/app/src/main/res/xml/backup_rules.xml
@@ -0,0 +1 @@
+<full-backup-content></full-backup-content> \ No newline at end of file
diff --git a/app/src/main/res/xml/data_extraction_rules.xml b/app/src/main/res/xml/data_extraction_rules.xml
new file mode 100644
index 0000000..11dba30
--- /dev/null
+++ b/app/src/main/res/xml/data_extraction_rules.xml
@@ -0,0 +1,3 @@
+<data-extraction-rules>
+ <cloud-backup></cloud-backup>
+</data-extraction-rules> \ No newline at end of file
diff --git a/app/src/main/res/xml/locales_config.xml b/app/src/main/res/xml/locales_config.xml
new file mode 100644
index 0000000..da6451b
--- /dev/null
+++ b/app/src/main/res/xml/locales_config.xml
@@ -0,0 +1,4 @@
+<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
+ <locale android:name="en" />
+ <locale android:name="fr" />
+</locale-config> \ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 0000000..591b467
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,31 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ repositories {
+ // Make sure that you have the following two repositories
+ google() // Google's Maven repository
+
+ mavenCentral() // Maven Central repository
+
+ }
+ dependencies {
+ // Add the dependency for the Google services Gradle plugin
+ classpath("com.google.gms:google-services:4.3.14")
+
+ }
+}
+
+plugins {
+ id("com.android.application") version "8.0.0-alpha10" apply false
+ id("com.android.library") version "8.0.0-alpha10" apply false
+ id("org.jetbrains.kotlin.android") version "1.7.21" apply false
+}
+
+allprojects {
+ repositories {
+ // Make sure that you have the following two repositories
+ google() // Google's Maven repository
+
+ mavenCentral() // Maven Central repository
+
+ }
+} \ No newline at end of file
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..3c5031e
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,23 @@
+# Project-wide Gradle settings.
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+# AndroidX package structure to make it clearer which packages are bundled with the
+# Android operating system, and which are packaged with your app's APK
+# https://developer.android.com/topic/libraries/support-library/androidx-rn
+android.useAndroidX=true
+# Kotlin code style for this project: "official" or "obsolete":
+kotlin.code.style=official
+# Enables namespacing of each library's R class so that its R class includes only the
+# resources declared in the library itself and none from the library's dependencies,
+# thereby reducing the size of the R class for that library
+android.nonTransitiveRClass=true \ No newline at end of file
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..e708b1c
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..fab501d
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,6 @@
+#Tue Dec 27 09:59:20 CET 2022
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 0000000..4f906e0
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,185 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=`expr $i + 1`
+ done
+ case $i in
+ 0) set -- ;;
+ 1) set -- "$args0" ;;
+ 2) set -- "$args0" "$args1" ;;
+ 3) set -- "$args0" "$args1" "$args2" ;;
+ 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100644
index 0000000..ac1b06f
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,89 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%" == "" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%" == "" set DIRNAME=.
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if "%ERRORLEVEL%" == "0" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if "%ERRORLEVEL%"=="0" goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
+exit /b 1
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 0000000..8684a0f
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1,9 @@
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+rootProject.name = "Delta"
+include(":app")