diff --git a/app/src/main/java/com/tunnelguard/app/UpdateManager.kt b/app/src/main/java/com/tunnelguard/app/UpdateManager.kt index 654a11f..054add0 100644 --- a/app/src/main/java/com/tunnelguard/app/UpdateManager.kt +++ b/app/src/main/java/com/tunnelguard/app/UpdateManager.kt @@ -8,6 +8,7 @@ import android.net.Uri import android.os.Build import android.provider.Settings import androidx.core.content.FileProvider +import com.tunnelguard.app.update.UpdateRepository import java.io.File import java.io.FileOutputStream import java.io.IOException @@ -424,12 +425,27 @@ class UpdateManager( } fun showUpdateErrorDialog(errorMessage: String) { - androidx.appcompat.app.AlertDialog.Builder(activity) + val repo = UpdateRepository.getInstance(activity) + val targetUrl = repo.getCachedReleaseUrl()?.ifBlank { null } ?: repo.getCachedApkUrl() + + val builder = androidx.appcompat.app.AlertDialog.Builder(activity) .setTitle("Update Check Failed") .setMessage("Could not check for updates or download update.\n\nDetails: $errorMessage") .setPositiveButton("OK") { dialog, _ -> dialog.dismiss() } - .show() + + if (!targetUrl.isNullOrBlank()) { + builder.setNeutralButton("Open in Browser") { dialog, _ -> + dialog.dismiss() + try { + val intent = Intent(Intent.ACTION_VIEW, Uri.parse(targetUrl)) + activity.startActivity(intent) + } catch (e: Exception) { + config.addLog("Failed to open browser for update: ${e.message}") + } + } + } + builder.show() } } diff --git a/app/src/main/java/com/tunnelguard/app/update/UpdateDialogScreen.kt b/app/src/main/java/com/tunnelguard/app/update/UpdateDialogScreen.kt index 8c3b59c..68a7f12 100644 --- a/app/src/main/java/com/tunnelguard/app/update/UpdateDialogScreen.kt +++ b/app/src/main/java/com/tunnelguard/app/update/UpdateDialogScreen.kt @@ -72,7 +72,28 @@ fun UpdateDialogScreen(state: UpdateUiState, onUpdateNow: () -> Unit, onExitApp: state.errorMessage?.let { Text(it, color = MaterialTheme.colorScheme.error, modifier = Modifier.padding(top = 12.dp)) } Spacer(Modifier.height(16.dp)) Row(Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.spacedBy(12.dp)) { - Button(onClick = onUpdateNow, enabled = !state.isDownloading, modifier = Modifier.weight(1f).height(56.dp).focusRequester(focusRequester)) { Text("Update Now") } + val context = LocalContext.current + val browserUrl = state.releaseUrl.ifBlank { state.apkUrl.orEmpty() } + + if (!state.errorMessage.isNullOrBlank() && browserUrl.isNotBlank()) { + Button( + onClick = { + try { + val intent = android.content.Intent(android.content.Intent.ACTION_VIEW, android.net.Uri.parse(browserUrl)) + context.startActivity(intent) + } catch (e: Exception) { + val config = com.tunnelguard.app.TunnelGuardConfig(context) + config.addLog("Failed to open browser for update: ${e.message}", "ERROR") + android.widget.Toast.makeText(context, "Failed to launch browser. Please open the link manually.", android.widget.Toast.LENGTH_LONG).show() + } + }, + modifier = Modifier.weight(1f).height(56.dp) + ) { + Text("Open in Browser") + } + } else { + Button(onClick = onUpdateNow, enabled = !state.isDownloading, modifier = Modifier.weight(1f).height(56.dp).focusRequester(focusRequester)) { Text("Update Now") } + } OutlinedButton(onClick = onExitApp, enabled = !state.isDownloading, modifier = Modifier.weight(1f).height(56.dp)) { Text("Exit App") } } }