diff --git a/app/build.gradle b/app/build.gradle index 42a9447..a1dd49f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,7 +13,7 @@ android { minSdk 24 targetSdk 34 versionCode 1 - versionName "1.0" + versionName "1.2" ndk { //noinspection ChromeOsAbiSupport diff --git a/app/src/main/assets/ifv b/app/src/main/assets/ifv index d0c3546..d7334b0 160000 --- a/app/src/main/assets/ifv +++ b/app/src/main/assets/ifv @@ -1 +1 @@ -Subproject commit d0c3546540ad42b9c1c67ff6fc094102bb5ba48d +Subproject commit d7334b04ce0037e749f7091521bba80d8fceeae5 diff --git a/app/src/main/java/dev/andus/niedu/MainActivity.kt b/app/src/main/java/dev/andus/niedu/MainActivity.kt index fb1f924..5e6a59c 100644 --- a/app/src/main/java/dev/andus/niedu/MainActivity.kt +++ b/app/src/main/java/dev/andus/niedu/MainActivity.kt @@ -48,6 +48,8 @@ class MainActivity : AppCompatActivity() { installExtensions() loadLoginPage() + + UpdateChecker(this).checkForUpdate() } private fun setupGeckoView() { diff --git a/app/src/main/java/dev/andus/niedu/UpdateChecker.kt b/app/src/main/java/dev/andus/niedu/UpdateChecker.kt new file mode 100644 index 0000000..4b4f380 --- /dev/null +++ b/app/src/main/java/dev/andus/niedu/UpdateChecker.kt @@ -0,0 +1,110 @@ +package dev.andus.niedu + +import android.content.Context +import android.net.Uri +import androidx.appcompat.app.AlertDialog +import org.json.JSONObject +import java.net.URL +import androidx.browser.customtabs.CustomTabsIntent + +class UpdateChecker(private val context: Context) { + + data class ReleaseInfo( + val version: String, + val downloadUrl: String, + val size: Long + ) + + private fun getCurrentVersion(): String { + val packageInfo = context.packageManager.getPackageInfo(context.packageName, 0) + return packageInfo.versionName + } + + private fun fetchLatestRelease(): ReleaseInfo? { + return try { + val url = URL("https://api.github.com/repos/AndusDEV/niedu/releases/latest") + val connection = url.openConnection() + connection.setRequestProperty("Accept", "application/vnd.github.v3+json") + + val response = connection.getInputStream().bufferedReader().use { it.readText() } + val jsonObject = JSONObject(response) + + val tagName = jsonObject.getString("tag_name").removePrefix("v") + val assets = jsonObject.getJSONArray("assets") + + if (assets.length() > 0) { + val downloadUrl = jsonObject.getString("html_url") + val apkAsset = assets.getJSONObject(0) + val size = apkAsset.getLong("size") + + ReleaseInfo(tagName, downloadUrl, size) + } else null + } catch (e: Exception) { + e.printStackTrace() + null + } + } + + private fun compareVersions(current: String, latest: String): Boolean { + val currentParts = current.split(".").map { it.toIntOrNull() ?: 0 } + val latestParts = latest.split(".").map { it.toIntOrNull() ?: 0 } + + val maxLength = maxOf(currentParts.size, latestParts.size) + val paddedCurrent = currentParts.padEnd(maxLength) + val paddedLatest = latestParts.padEnd(maxLength) + + for (i in 0 until maxLength) { + if (paddedLatest[i] > paddedCurrent[i]) return true + if (paddedLatest[i] < paddedCurrent[i]) return false + } + return false + } + + private fun List.padEnd(length: Int): List { + return if (size >= length) this + else this + List(length - size) { 0 } + } + + private fun formatFileSize(bytes: Long): String { + val mb = bytes / (1024.0 * 1024.0) + return "%.1f MB".format(mb) + } + + fun checkForUpdate() { + Thread { + val currentVersion = getCurrentVersion() + val latestRelease = fetchLatestRelease() + + if (latestRelease != null && compareVersions(currentVersion, latestRelease.version)) { + (context as MainActivity).runOnUiThread { + showUpdateDialog(currentVersion, latestRelease) + } + } + }.start() + } + + private fun showUpdateDialog(currentVersion: String, releaseInfo: ReleaseInfo) { + val message = """ + Nowa aktualizacja dostępna! + + Aktualna wersja: v$currentVersion + Najnowsza wersja: v${releaseInfo.version} + Rozmiar pliku do pobrania: ${formatFileSize(releaseInfo.size)} + + Czy chciałbyś pobrać plik .apk? + """.trimIndent() + + AlertDialog.Builder(context) + .setTitle("Aktualizacja dostępna") + .setMessage(message) + .setPositiveButton("Pobierz") { _, _ -> + val intent = CustomTabsIntent.Builder() + .setShowTitle(true) + .setUrlBarHidingEnabled(true) + .build() + intent.launchUrl(context, Uri.parse(releaseInfo.downloadUrl)) + } + .setNegativeButton("Później", null) + .show() + } +} \ No newline at end of file