Skip to content
Merged

Dev #110

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 0 additions & 22 deletions .github/workflows/codeberg.yml

This file was deleted.

7 changes: 4 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ android {
applicationId "com.nin0dev.vendroid"
minSdk 25
targetSdk 34
versionCode 10
versionName "1.7"
versionCode 11
versionName "1.8"
}

buildTypes {
Expand All @@ -37,8 +37,9 @@ dependencies {
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'androidx.activity:activity-ktx:1.9.3'
implementation 'com.google.code.gson:gson:2.11.0'
implementation 'com.google.code.gson:gson:2.12.1'
implementation 'com.android.volley:volley:1.2.1'
implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
implementation 'com.google.firebase:firebase-common-ktx:21.0.0'
}

3 changes: 0 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@
android:exported="true"
android:launchMode="singleTask"
android:theme="@style/AppTheme" />
<activity
android:name=".SettingsActivity"
android:exported="false" />
<activity
android:name=".WelcomeActivity"
android:exported="false"
Expand Down
192 changes: 145 additions & 47 deletions app/src/main/java/com/nin0dev/vendroid/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,68 +3,142 @@ package com.nin0dev.vendroid
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.StrictMode
import android.os.StrictMode.ThreadPolicy
import android.view.KeyEvent
import android.view.View.GONE
import android.view.View.VISIBLE
import android.view.WindowManager
import android.webkit.ValueCallback
import android.webkit.WebView
import android.widget.Button
import android.widget.LinearLayout
import android.widget.Toast
import com.android.volley.Request
import com.android.volley.toolbox.StringRequest
import com.android.volley.toolbox.Volley
import com.google.android.material.color.DynamicColors
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import com.google.android.material.textfield.TextInputEditText
import com.google.gson.Gson
import com.nin0dev.vendroid.HttpClient.fetchVencord
import com.nin0dev.vendroid.Logger.e
import com.nin0dev.vendroid.utils.Logger.e
import com.nin0dev.vendroid.utils.UpdateData
import com.nin0dev.vendroid.webview.HttpClient.fetchVencord
import com.nin0dev.vendroid.webview.VChromeClient
import com.nin0dev.vendroid.webview.VWebviewClient
import com.nin0dev.vendroid.webview.VencordNative
import pl.droidsonroids.gif.GifImageView
import java.io.IOException


data class UpdateData(val version: Int, val changelog: String)

class MainActivity : Activity() {
private var wvInitialized = false
private var wv: WebView? = null

@JvmField
var filePathCallback: ValueCallback<Array<Uri?>?>? = null

fun checkUpdates(ignoreSetting: Boolean = false)
{
private fun setupQuickCss() {
val saveButton = findViewById<Button>(R.id.save_css)
val cssEditText = findViewById<TextInputEditText>(R.id.css)

saveButton.setOnClickListener {
wv!!.evaluateJavascript(
"VencordNative.quickCss.set(\"${
cssEditText.text
.toString()
.replace("\\", "\\\\")
.replace("\"", "\\\"")
.replace("\n", "\\n")
.replace("\r", "\\r")
}\")", null
)
showDiscordToast("Saved QuickCSS", "SUCCESS")
findViewById<LinearLayout>(R.id.quickcss).visibility = GONE
findViewById<LinearLayout>(R.id.loading_screen).visibility = GONE
wv!!.visibility = VISIBLE
currentFocus?.clearFocus();
}
}

private fun migrateSettings() {
val sPrefs = getSharedPreferences("settings", Context.MODE_PRIVATE)
if(sPrefs.getBoolean("checkVendroidUpdates", false) || ignoreSetting) {
if (sPrefs.getBoolean("migratedSettings", false)) return;
val e = sPrefs.edit()
e.putBoolean("migratedSettings", true);

e.putBoolean("checkVDEUpdates", sPrefs.getBoolean("checkVendroidUpdates", true))
e.putBoolean(
"checkAnnouncements",
sPrefs.getBoolean("checkVendroidUpdates", true)
) // The user likely turned off auto-updating for privacy reasons, so also disable phoning home for announcements.
e.putString(
"clientMod",
if (sPrefs.getBoolean("equicord", false)) "equicord" else "vencord"
)
e.putString("splashScreen", sPrefs.getString("splash", "viggy"));

e.apply()
}

fun checkUpdates(ignoreSetting: Boolean = false) {
val sPrefs = getSharedPreferences("settings", Context.MODE_PRIVATE)
if (sPrefs.getBoolean("checkVDEUpdates", true) || sPrefs.getBoolean(
"checkAnnouncements",
true
) || ignoreSetting
) {
val queue = Volley.newRequestQueue(this)
val url = "https://vendroid.nin0.dev/api/updates"
val url =
"https://vendroid-staging.nin0.dev/api/updates?version=${BuildConfig.VERSION_CODE}"
val stringRequest = StringRequest(
Request.Method.GET, url,
{ response ->
val gson = Gson()
val updateData = gson.fromJson<UpdateData>(response, UpdateData::class.java)
if(updateData.version != BuildConfig.VERSION_CODE)
{
val madb = MaterialAlertDialogBuilder(this)
madb.setTitle(getString(R.string.vendroid_update_available))
madb.setMessage("Changelog:\n" + updateData.changelog)
madb.setPositiveButton(getString(R.string.update), DialogInterface.OnClickListener { dialogInterface, i ->
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse("https://github.com/VendroidEnhanced/Vendroid/releases/latest/download/app-release.apk"))
startActivity(browserIntent)
})
madb.setNegativeButton(getString(R.string.later), DialogInterface.OnClickListener { _, _ -> })
madb.show()

if (updateData.update != null && sPrefs.getBoolean("checkVDEUpdates", true)) {
MaterialAlertDialogBuilder(this)
.setIcon(R.drawable.baseline_system_update_24)
.setTitle("An update is available (${updateData.update.title})")
.setMessage(updateData.update.text)
.setPositiveButton(getString(R.string.update)) { _, _ ->
val browserIntent = Intent(
Intent.ACTION_VIEW,
Uri.parse("https://github.com/nin0-dev/VendroidEnhanced/releases/latest/download/app-release.apk")
)
startActivity(browserIntent)
}
.setNegativeButton(getString(R.string.later)) { _, _ -> }
.show()
}
if(ignoreSetting && updateData.version == BuildConfig.VERSION_CODE) {
showDiscordToast("No updates available", "MESSAGE")
if (!sPrefs.getBoolean(
"checkAnnouncements",
true
) || ignoreSetting
) return@StringRequest
for (announcement in updateData.announcements!!) {
val sp = getSharedPreferences("announcements", Context.MODE_PRIVATE)
if (!sp.getBoolean(announcement.id.toString(), false)) {
MaterialAlertDialogBuilder(this)
.setIcon(R.drawable.campaign_24dp_000000)
.setTitle(announcement.title)
.setMessage(announcement.text)
.setPositiveButton("OK") { _, _ ->
val e = sp.edit()
e.putBoolean(announcement.id.toString(), true)
e.apply()
}
.show()
}
}
},
{ error ->
if (BuildConfig.DEBUG) {
if (BuildConfig.DEBUG) {
e("Network error during update check", error)
}
Toast.makeText(this, "Failed to check for updates", Toast.LENGTH_SHORT).show()
Expand All @@ -78,56 +152,75 @@ class MainActivity : Activity() {
@SuppressLint("SetJavaScriptEnabled") // mad? watch this swag
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
migrateSettings()
DynamicColors.applyToActivitiesIfAvailable(application)
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.statusBarColor = Color.TRANSPARENT
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
window.navigationBarColor = Color.TRANSPARENT

val sPrefs = getSharedPreferences("settings", Context.MODE_PRIVATE)
val editor = sPrefs.edit()

// https://developer.chrome.com/docs/devtools/remote-debugging/webviews/
WebView.setWebContentsDebuggingEnabled(BuildConfig.DEBUG)
WebView.setWebContentsDebuggingEnabled(
BuildConfig.DEBUG || sPrefs.getBoolean(
"allowRemoteDebugging",
false
)
)
setContentView(R.layout.activity_main)
if (sPrefs.getString("splash", "viggy") == "viggy") findViewById<GifImageView>(R.id.viggy_gif).visibility = VISIBLE
else if (sPrefs.getString("splash", "viggy") == "shiggy") findViewById<GifImageView>(R.id.shiggy_gif).visibility = VISIBLE
else if (sPrefs.getString("splash", "viggy") == "oneko") findViewById<GifImageView>(R.id.oneko_gif).visibility = VISIBLE

findViewById<GifImageView>(
mapOf(
"viggy" to R.id.viggy_gif,
"shiggy" to R.id.shiggy_gif,
"oneko" to R.id.oneko_gif
)[sPrefs.getString("splashScreen", "viggy")]!!
).visibility = VISIBLE

wv = findViewById(R.id.webview)!!
setupQuickCss()
explodeAndroid()
wv!!.setWebViewClient(VWebviewClient())
wv!!.setWebChromeClient(VChromeClient(this))
if(sPrefs.getBoolean("desktopMode", false)) {
wv!!.settings.userAgentString = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
if (sPrefs.getBoolean("desktopMode", false)) {
wv!!.settings.userAgentString =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36"
}
val s = wv?.getSettings()!!
s.javaScriptEnabled = true
s.domStorageEnabled = true
s.allowFileAccess = true
if(!sPrefs.getBoolean("safeMode", false)) {

if (!sPrefs.getBoolean("safeMode", false)) {
wv?.addJavascriptInterface(VencordNative(this, wv!!), "VencordMobileNative")
try {
fetchVencord(this)
} catch (ex: IOException) {
} catch (_: IOException) {

}
}
else {
Toast.makeText(this, "Safe mode enabled, Vencord won't be loaded", Toast.LENGTH_SHORT).show()
} else {
Toast.makeText(this, "Safe mode enabled, Vencord won't be loaded", Toast.LENGTH_SHORT)
.show()
editor.putBoolean("safeMode", false)
editor.apply()
}

val intent = intent
if (intent.action == Intent.ACTION_VIEW) {
val data = intent.data
if (data != null) handleUrl(intent.data)
} else {
if (sPrefs.getString("discordBranch", "") == "stable") wv!!.loadUrl("https://discord.com/app")
else if (sPrefs.getString("discordBranch", "") == "ptb") wv!!.loadUrl("https://ptb.discord.com/app")
else if (sPrefs.getString("discordBranch", "") == "canary") wv!!.loadUrl("https://canary.discord.com/app")
else {
finish()
startActivity(Intent(this@MainActivity, WelcomeActivity::class.java))
}
wv!!.loadUrl(
mapOf(
"stable" to "https://discord.com/app",
"ptb" to "https://discord.com/app",
"oneko" to "https://discord.com/app"
)[sPrefs.getString("discordBranch", "stable")]!!
)
}

checkUpdates()
wvInitialized = true
}
Expand All @@ -143,7 +236,7 @@ class MainActivity : Activity() {
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent?) {
super.onActivityResult(requestCode, resultCode, intent)
try {
if(resultCode != RESULT_CANCELED) {
if (resultCode != RESULT_CANCELED) {
if (requestCode != FILECHOOSER_RESULTCODE || filePathCallback == null) return
if (resultCode != RESULT_OK || intent == null) {
filePathCallback!!.onReceiveValue(null)
Expand All @@ -167,8 +260,7 @@ class MainActivity : Activity() {
}
filePathCallback = null
}
}
catch (ex: Exception) {
} catch (ex: Exception) {
// it is well known that the best fix for the crash is to wrap the entire function in a try/catch block
}
}
Expand All @@ -181,13 +273,16 @@ class MainActivity : Activity() {
)
}

fun handleUrl(url: Uri?) {
private fun handleUrl(url: Uri?) {
if (url != null) {
if (url.authority != "discord.com" || url.authority != "ptb.discord.com" || url.authority != "canary.discord.com") return
if (!wvInitialized) {
wv!!.loadUrl(url.toString())
} else {
wv!!.evaluateJavascript("Vencord.Webpack.Common.NavigationRouter.transitionTo(\"" + url.path + "\")", null)
wv!!.evaluateJavascript(
"Vencord.Webpack.Common.NavigationRouter.transitionTo(\"" + url.path + "\")",
null
)
}
}
}
Expand All @@ -200,7 +295,10 @@ class MainActivity : Activity() {

fun showDiscordToast(message: String, type: String) {
wv?.post(Runnable {
wv?.evaluateJavascript("toasts=Vencord.Webpack.Common.Toasts; toasts.show({id: toasts.genId(), message: \"$message\", type: toasts.Type.$type, options: {position: toasts.Position.BOTTOM,}})", null) // NOBODY LIKES TOASTS AT THE TOP
wv?.evaluateJavascript(
"toasts=Vencord.Webpack.Common.Toasts; toasts.show({id: toasts.genId(), message: \"$message\", type: toasts.Type.$type, options: {position: toasts.Position.BOTTOM,}})",
null
) // NOBODY LIKES TOASTS AT THE TOP
})
}

Expand Down
4 changes: 0 additions & 4 deletions app/src/main/java/com/nin0dev/vendroid/RecoveryActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,6 @@ class RecoveryActivity : AppCompatActivity() {
finish()
startActivity(Intent(this, MainActivity::class.java))
}
findViewById<MaterialCardView>(R.id.settings).setOnClickListener {
finish()
startActivity(Intent(this, SettingsActivity::class.java))
}

}
override fun onNewIntent(intent: Intent) {
Expand Down
Loading
Loading