feat: enhance MainActivity with system window insets handling and improve WebView alert dialogs; update index.html for better user feedback on loading states

This commit is contained in:
Sarto
2026-04-04 01:00:13 +03:30
parent 0568fc61e7
commit 4712be5c18
3 changed files with 41 additions and 2 deletions
@@ -15,9 +15,15 @@ import android.webkit.WebView
import android.webkit.WebViewClient
import android.view.View
import android.widget.TextView
import android.webkit.JsResult
import android.webkit.WebChromeClient
import android.app.AlertDialog
import androidx.activity.ComponentActivity
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import java.net.HttpURLConnection
import java.net.URL
@@ -32,8 +38,20 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Let the app draw behind the system status bar
WindowCompat.setDecorFitsSystemWindows(window, false)
setContentView(R.layout.activity_main)
// Apply top inset as padding so content isn't hidden behind the status bar
val rootView = findViewById<View>(android.R.id.content)
ViewCompat.setOnApplyWindowInsetsListener(rootView) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(0, systemBars.top, 0, systemBars.bottom)
insets
}
// Trigger inset dispatch explicitly — required on some older Android versions
ViewCompat.requestApplyInsets(rootView)
webView = findViewById(R.id.webView)
txtStatus = findViewById(R.id.txtStatus)
@@ -88,6 +106,21 @@ class MainActivity : ComponentActivity() {
}
}
// Required for confirm() / alert() / prompt() to work in WebView
webView.webChromeClient = object : WebChromeClient() {
override fun onJsConfirm(
view: WebView?, url: String?, message: String?, result: JsResult?
): Boolean {
AlertDialog.Builder(this@MainActivity)
.setMessage(message)
.setPositiveButton(android.R.string.ok) { _, _ -> result?.confirm() }
.setNegativeButton(android.R.string.cancel) { _, _ -> result?.cancel() }
.setOnCancelListener { result?.cancel() }
.show()
return true
}
}
with(webView.settings) {
javaScriptEnabled = true
domStorageEnabled = true
@@ -4,5 +4,7 @@
<item name="colorPrimaryVariant">@color/bgPanel</item>
<item name="colorOnPrimary">@color/text</item>
<item name="android:statusBarColor" tools:targetApi="l">@color/bg</item>
<item name="android:navigationBarColor">@color/bg</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
</style>
</resources>
+6 -2
View File
@@ -356,6 +356,8 @@ var I18N = {
fa: {
search:'جستجو...',settings:'تنظیمات',profiles:'پروفایل‌ها',
no_channels:'کانالی وجود ندارد',loading:'در حال بارگذاری...',no_messages:'هنوز پیامی در این کانال وجود ندارد',
no_channels_hint:'برنامه در حال دریافت اطلاعات از سرور است...',
no_messages_hint:'برنامه در حال دریافت پیام‌ها است. لطفاً چند لحظه صبر کنید...',
write_message:'پیام بنویسید...',configure_server:'برای شروع یک سرور راه‌اندازی کنید',
set_up:'راه‌اندازی',switching:'در حال تغییر پروفایل...',
font_size:'اندازه قلم',debug_mode:'حالت دیباگ',language:'زبان',
@@ -378,6 +380,8 @@ var I18N = {
en: {
search:'Search...',settings:'Settings',profiles:'Profiles',
no_channels:'No channels',loading:'Loading...',no_messages:'No messages in this channel',
no_channels_hint:'The app is fetching channel list from the server...',
no_messages_hint:'The app is trying to fetch messages. Please wait a moment...',
write_message:'Write a message...',configure_server:'Configure a server to start reading',
set_up:'Set Up',switching:'Switching profile...',
font_size:'Font Size',debug_mode:'Debug mode',language:'Language',
@@ -756,7 +760,7 @@ async function loadChannels(){
function renderChannels(){
var el=document.getElementById('channelList');
if(!channels||!channels.length){el.innerHTML='<div style="padding:20px;text-align:center;color:var(--text-dim);font-size:13px">'+t('no_channels')+'</div>';return}
if(!channels||!channels.length){el.innerHTML='<div style="padding:20px;text-align:center;color:var(--text-dim);font-size:13px">'+t('no_channels')+'<br><span style="font-size:11px;opacity:.7">'+t('no_channels_hint')+'</span></div>';return}
var pubs=[],privs=[];
for(var i=0;i<channels.length;i++){var c=channels[i];(c.ChatType===1||c.chatType===1?privs:pubs).push({ch:c,idx:i})}
function section(title,items){
@@ -810,7 +814,7 @@ async function loadMessages(chNum){
function renderMessages(msgs){
var el=document.getElementById('messages');
if(!msgs||!msgs.length){el.innerHTML='<div class="empty-state"><p>'+t('no_messages')+'</p></div>';return}
if(!msgs||!msgs.length){el.innerHTML='<div class="empty-state"><p>'+t('no_messages')+'</p><p style="font-size:12px;opacity:.6;margin-top:6px">'+t('no_messages_hint')+'</p></div>';return}
msgs.sort(function(a,b){return(a.Timestamp||a.timestamp||0)-(b.Timestamp||b.timestamp||0)});
var html='',lastDate='';
var dateLocale=lang==='fa'?'fa-IR':'en-US';