Skip to content

Commit 5fe5f7b

Browse files
committed
refactor(webview): create a common AppWebView component #262
- Extract AppWebView as a common component for web screen- Update PluginLoginActivity and WebScreen to use the new AppWebView - Add error handling for foreground service start- Implement dark theme support for webview - Add page reload on error- Use CompositionLocal for context instead of LocalContext.current
1 parent 7bbb363 commit 5fe5f7b

File tree

18 files changed

+368
-311
lines changed

18 files changed

+368
-311
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,10 @@
11
package com.github.jing332.tts_server_android.compose.forwarder
22

33
import android.annotation.SuppressLint
4-
import android.content.Intent
5-
import android.webkit.JsResult
6-
import android.webkit.WebResourceRequest
7-
import android.webkit.WebView
8-
import androidx.compose.foundation.layout.Column
9-
import androidx.compose.foundation.layout.fillMaxSize
10-
import androidx.compose.material3.AlertDialog
114
import androidx.compose.material3.ExperimentalMaterial3Api
12-
import androidx.compose.material3.MaterialTheme
13-
import androidx.compose.material3.Text
14-
import androidx.compose.material3.TextButton
15-
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
16-
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
175
import androidx.compose.runtime.Composable
18-
import androidx.compose.runtime.getValue
19-
import androidx.compose.runtime.mutableStateOf
20-
import androidx.compose.runtime.remember
21-
import androidx.compose.runtime.setValue
22-
import androidx.compose.ui.Alignment
236
import androidx.compose.ui.Modifier
24-
import androidx.compose.ui.platform.LocalContext
25-
import androidx.compose.ui.res.stringResource
26-
import com.github.jing332.common.utils.longToast
27-
import com.google.accompanist.web.AccompanistWebChromeClient
28-
import com.google.accompanist.web.AccompanistWebViewClient
29-
import com.google.accompanist.web.LoadingState
30-
import com.google.accompanist.web.WebView
7+
import com.github.jing332.compose.widgets.AppWebView
318
import com.google.accompanist.web.WebViewNavigator
329
import com.google.accompanist.web.WebViewState
3310
import com.google.accompanist.web.rememberWebViewNavigator
@@ -43,116 +20,5 @@ internal fun WebScreen(
4320
state: WebViewState = rememberWebViewState(url),
4421
navigator: WebViewNavigator = rememberWebViewNavigator(),
4522
) {
46-
var showAlertDialog by remember { mutableStateOf<Triple<String, String, JsResult>?>(null) }
47-
if (showAlertDialog != null) {
48-
val webUrl = showAlertDialog!!.first
49-
val msg = showAlertDialog!!.second
50-
val result = showAlertDialog!!.third
51-
AlertDialog(onDismissRequest = {
52-
result.cancel()
53-
showAlertDialog = null
54-
},
55-
title = { Text(webUrl) },
56-
text = { Text(msg) },
57-
confirmButton = {
58-
TextButton(
59-
onClick = {
60-
result.confirm()
61-
showAlertDialog = null
62-
}) {
63-
Text(stringResource(id = android.R.string.ok))
64-
}
65-
}, dismissButton = {
66-
result.cancel()
67-
showAlertDialog = null
68-
})
69-
}
70-
71-
val context = LocalContext.current
72-
val chromeClient = remember {
73-
object : AccompanistWebChromeClient() {
74-
override fun onJsConfirm(
75-
view: WebView?,
76-
url: String?,
77-
message: String?,
78-
result: JsResult?,
79-
): Boolean {
80-
if (result == null) return false
81-
showAlertDialog = Triple(url ?: "", message ?: "", result)
82-
return true
83-
}
84-
85-
override fun onJsAlert(
86-
view: WebView?,
87-
url: String?,
88-
message: String?,
89-
result: JsResult?,
90-
): Boolean {
91-
if (result == null) return false
92-
showAlertDialog = Triple(url ?: "", message ?: "", result)
93-
94-
return true
95-
}
96-
}
97-
}
98-
99-
val client = remember {
100-
object : AccompanistWebViewClient() {
101-
override fun shouldOverrideUrlLoading(
102-
view: WebView?,
103-
request: WebResourceRequest?,
104-
): Boolean {
105-
kotlin.runCatching {
106-
if (request?.url?.scheme?.startsWith("http") == false) {
107-
val intent = Intent(Intent.ACTION_VIEW, request.url)
108-
context.startActivity(Intent.createChooser(intent, request.url.toString()))
109-
return true
110-
}
111-
}.onFailure {
112-
context.longToast("跳转APP失败: ${request?.url}")
113-
}
114-
115-
return super.shouldOverrideUrlLoading(view, request)
116-
}
117-
}
118-
}
119-
120-
Column(modifier = modifier) {
121-
val process =
122-
if (state.loadingState is LoadingState.Loading) (state.loadingState as LoadingState.Loading).progress else 0f
123-
124-
var lastTitle by remember { mutableStateOf("") }
125-
val refreshState = rememberPullToRefreshState()
126-
Text(
127-
modifier = Modifier
128-
.align(Alignment.CenterHorizontally),
129-
text = state.pageTitle?.apply { lastTitle = this } ?: lastTitle,
130-
maxLines = 1,
131-
style = MaterialTheme.typography.titleMedium,
132-
)
133-
134-
PullToRefreshBox(state.isLoading, state = refreshState, onRefresh = { }) {
135-
WebView(
136-
modifier = Modifier.fillMaxSize(),
137-
state = state,
138-
navigator = navigator,
139-
onCreated = {
140-
it.settings.javaScriptEnabled = true
141-
it.settings.domStorageEnabled = true
142-
it.settings.databaseEnabled = true
143-
},
144-
client = client,
145-
chromeClient = chromeClient,
146-
)
147-
148-
// Column(Modifier.fillMaxWidth()) {
149-
// PullREF
150-
// PullRefreshIndicator(
151-
// modifier = Modifier.align(Alignment.CenterHorizontally),
152-
// refreshing = refreshState.refreshing,
153-
// state = refreshState
154-
// )
155-
// }
156-
}
157-
}
23+
AppWebView(modifier = modifier, state = state, navigator = navigator)
15824
}

0 commit comments

Comments
 (0)