feat: F-Droid flavor

This commit is contained in:
rebelonion 2024-02-06 01:10:12 -06:00
parent 21f5d503cd
commit c0f3fed142
37 changed files with 218 additions and 97 deletions

View file

@ -0,0 +1,9 @@
package ani.dantotsu.connections.crashlytics
class CrashlyticsFactory {
companion object {
fun createCrashlytics(): CrashlyticsInterface {
return FirebaseCrashlytics()
}
}
}

View file

@ -0,0 +1,28 @@
package ani.dantotsu.connections.crashlytics
import com.google.firebase.crashlytics.FirebaseCrashlytics
import com.google.firebase.crashlytics.ktx.crashlytics
import com.google.firebase.ktx.Firebase
class FirebaseCrashlytics : CrashlyticsInterface {
override fun logException(e: Throwable) {
FirebaseCrashlytics.getInstance().recordException(e)
}
override fun log(message: String) {
FirebaseCrashlytics.getInstance().log(message)
}
override fun setUserId(id: String) {
Firebase.crashlytics.setUserId(id)
}
override fun setCustomKey(key: String, value: String) {
FirebaseCrashlytics.getInstance().setCustomKey(key, value)
}
override fun setCrashlyticsCollectionEnabled(enabled: Boolean) {
FirebaseCrashlytics.getInstance().setCrashlyticsCollectionEnabled(enabled)
}
}

View file

@ -0,0 +1,235 @@
package ani.dantotsu.others
import android.annotation.SuppressLint
import android.app.Activity
import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.Uri
import android.os.Environment
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.core.content.getSystemService
import androidx.fragment.app.FragmentActivity
import ani.dantotsu.*
import ani.dantotsu.settings.saving.PrefManager
import io.noties.markwon.Markwon
import io.noties.markwon.SoftBreakAddsNewLinePlugin
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.decodeFromJsonElement
import java.io.File
import java.text.SimpleDateFormat
import java.util.*
object AppUpdater {
suspend fun check(activity: FragmentActivity, post: Boolean = false) {
if (post) snackString(currContext()?.getString(R.string.checking_for_update))
val repo = activity.getString(R.string.repo)
tryWithSuspend {
val (md, version) = if (BuildConfig.DEBUG) {
val res = client.get("https://api.github.com/repos/$repo/releases")
.parsed<JsonArray>().map {
Mapper.json.decodeFromJsonElement<GithubResponse>(it)
}
val r = res.filter { it.prerelease }.maxByOrNull {
it.timeStamp()
} ?: throw Exception("No Pre Release Found")
val v = r.tagName.substringAfter("v", "")
(r.body ?: "") to v.ifEmpty { throw Exception("Weird Version : ${r.tagName}") }
} else {
val res =
client.get("https://raw.githubusercontent.com/$repo/main/stable.md").text
res to res.substringAfter("# ").substringBefore("\n")
}
logger("Git Version : $version")
val dontShow = PrefManager.getCustomVal("dont_ask_for_update_$version", false)
if (compareVersion(version) && !dontShow && !activity.isDestroyed) activity.runOnUiThread {
CustomBottomDialog.newInstance().apply {
setTitleText(
"${if (BuildConfig.DEBUG) "Beta " else ""}Update " + currContext()!!.getString(
R.string.available
)
)
addView(
TextView(activity).apply {
val markWon = Markwon.builder(activity)
.usePlugin(SoftBreakAddsNewLinePlugin.create()).build()
markWon.setMarkdown(this, md)
}
)
setCheck(
currContext()!!.getString(R.string.dont_show_again, version),
false
) { isChecked ->
if (isChecked) {
PrefManager.setCustomVal("dont_ask_for_update_$version", true)
}
}
setPositiveButton(currContext()!!.getString(R.string.lets_go)) {
MainScope().launch(Dispatchers.IO) {
try {
client.get("https://api.github.com/repos/$repo/releases/tags/v$version")
.parsed<GithubResponse>().assets?.find {
it.browserDownloadURL.endsWith("apk")
}?.browserDownloadURL.apply {
if (this != null) activity.downloadUpdate(version, this)
else openLinkInBrowser("https://github.com/repos/$repo/releases/tag/v$version")
}
} catch (e: Exception) {
logError(e)
}
}
dismiss()
}
setNegativeButton(currContext()!!.getString(R.string.cope)) {
dismiss()
}
show(activity.supportFragmentManager, "dialog")
}
}
else {
if (post) snackString(currContext()?.getString(R.string.no_update_found))
}
}
}
private fun compareVersion(version: String): Boolean {
if (BuildConfig.DEBUG) {
return BuildConfig.VERSION_NAME != version
} else {
fun toDouble(list: List<String>): Double {
return list.mapIndexed { i: Int, s: String ->
when (i) {
0 -> s.toDouble() * 100
1 -> s.toDouble() * 10
2 -> s.toDouble()
else -> s.toDoubleOrNull() ?: 0.0
}
}.sum()
}
val new = toDouble(version.split("."))
val curr = toDouble(BuildConfig.VERSION_NAME.split("."))
return new > curr
}
}
//Blatantly kanged from https://github.com/LagradOst/CloudStream-3/blob/master/app/src/main/java/com/lagradost/cloudstream3/utils/InAppUpdater.kt
private fun Activity.downloadUpdate(version: String, url: String): Boolean {
toast(getString(R.string.downloading_update, version))
val downloadManager = this.getSystemService<DownloadManager>()!!
val request = DownloadManager.Request(Uri.parse(url))
.setMimeType("application/vnd.android.package-archive")
.setTitle("Downloading Dantotsu $version")
.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
"Dantotsu $version.apk"
)
.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI or DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(true)
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
val id = try {
downloadManager.enqueue(request)
} catch (e: Exception) {
logError(e)
-1
}
if (id == -1L) return true
ContextCompat.registerReceiver(
this,
object : BroadcastReceiver() {
@SuppressLint("Range")
override fun onReceive(context: Context?, intent: Intent?) {
try {
val downloadId = intent?.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, id
) ?: id
val query = DownloadManager.Query()
query.setFilterById(downloadId)
val c = downloadManager.query(query)
if (c.moveToFirst()) {
val columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS)
if (DownloadManager.STATUS_SUCCESSFUL == c
.getInt(columnIndex)
) {
c.getColumnIndex(DownloadManager.COLUMN_MEDIAPROVIDER_URI)
val uri = Uri.parse(
c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))
)
openApk(this@downloadUpdate, uri)
}
}
} catch (e: Exception) {
logError(e)
}
}
}, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE),
ContextCompat.RECEIVER_EXPORTED
)
return true
}
private fun openApk(context: Context, uri: Uri) {
try {
uri.path?.let {
val contentUri = FileProvider.getUriForFile(
context,
BuildConfig.APPLICATION_ID + ".provider",
File(it)
)
val installIntent = Intent(Intent.ACTION_VIEW).apply {
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
data = contentUri
}
context.startActivity(installIntent)
}
} catch (e: Exception) {
logError(e)
}
}
val dateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US)
@Serializable
data class GithubResponse(
@SerialName("html_url")
val htmlUrl: String,
@SerialName("tag_name")
val tagName: String,
val prerelease: Boolean,
@SerialName("created_at")
val createdAt: String,
val body: String? = null,
val assets: List<Asset>? = null
) {
@Serializable
data class Asset(
@SerialName("browser_download_url")
val browserDownloadURL: String
)
fun timeStamp(): Long {
return dateFormat.parse(createdAt)!!.time
}
}
}