@@ -41,6 +41,7 @@ import androidx.compose.ui.unit.sp
4141import androidx.compose.ui.window.Dialog
4242import com.jankinwu.fntv.client.data.constants.Colors
4343import com.jankinwu.fntv.client.data.constants.Constants
44+ import com.jankinwu.fntv.client.data.store.SslTrustDecision
4445import com.jankinwu.fntv.client.data.store.SslTrustManager
4546import com.jankinwu.fntv.client.icons.SkipLink
4647import com.jankinwu.fntv.client.icons.Warning
@@ -179,7 +180,9 @@ fun CustomConfirmDialog(
179180 dismissButtonText : String = "取消",
180181 onDismissClick : () -> Unit = {},
181182 confirmButtonText : String ,
182- onConfirmClick : () -> Unit = {}
183+ onConfirmClick : () -> Unit = {},
184+ extraButtonText : String? = null,
185+ onExtraClick : () -> Unit = {}
183186) {
184187 val store = LocalStore .current
185188 Dialog (onDismissRequest = onDismissRequest) {
@@ -256,6 +259,21 @@ fun CustomConfirmDialog(
256259 ) {
257260 Text (confirmButtonText, color = primaryTextColor)
258261 }
262+ if (extraButtonText != null ) {
263+ Button (
264+ onClick = {
265+ onExtraClick()
266+ onDismissRequest()
267+ },
268+ shape = RoundedCornerShape (8 .dp),
269+ colors = ButtonDefaults .buttonColors(
270+ containerColor = confirmButtonColor
271+ ),
272+ modifier = Modifier .weight(1f )
273+ ) {
274+ Text (extraButtonText, color = primaryTextColor)
275+ }
276+ }
259277 }
260278 }
261279 }
@@ -269,7 +287,9 @@ fun CustomContentDialog(
269287 content : @Composable () -> Unit ,
270288 primaryButtonText : String ,
271289 secondaryButtonText : String? = null,
290+ tertiaryButtonText : String? = null,
272291 onButtonClick : (ContentDialogButton ) -> Unit ,
292+ onTertiaryClick : () -> Unit = {},
273293 size : DialogSize = DialogSize .Standard ,
274294 isWarning : Boolean = false
275295) {
@@ -318,31 +338,77 @@ fun CustomContentDialog(
318338 .padding(horizontal = 25 .dp, vertical = 8 .dp),
319339 Alignment .CenterEnd
320340 ) {
321- Row (
322- horizontalArrangement = Arrangement .spacedBy(8 .dp, Alignment .End ),
323- verticalAlignment = Alignment .CenterVertically ,
324- modifier = Modifier .fillMaxWidth()
325- ) {
326- if (secondaryButtonText != null ) Button (
327- modifier = Modifier .pointerHoverIcon(PointerIcon .Hand ),
328- onClick = { onButtonClick(ContentDialogButton .Secondary ) },
341+ if (tertiaryButtonText != null ) {
342+ Row (
343+ horizontalArrangement = Arrangement .SpaceBetween ,
344+ verticalAlignment = Alignment .CenterVertically ,
345+ modifier = Modifier .fillMaxWidth()
329346 ) {
330- Text (
331- secondaryButtonText,
332- style = LocalTypography .current.bodyStrong,
333- color = FluentTheme .colors.text.text.primary
334- )
347+ if (secondaryButtonText != null ) Button (
348+ modifier = Modifier .pointerHoverIcon(PointerIcon .Hand ),
349+ onClick = { onButtonClick(ContentDialogButton .Secondary ) },
350+ ) {
351+ Text (
352+ secondaryButtonText,
353+ style = LocalTypography .current.bodyStrong,
354+ color = FluentTheme .colors.text.text.primary
355+ )
356+ }
357+ Row (
358+ horizontalArrangement = Arrangement .spacedBy(8 .dp, Alignment .End ),
359+ verticalAlignment = Alignment .CenterVertically ,
360+ modifier = Modifier .fillMaxWidth()
361+ ) {
362+ Button (
363+ modifier = Modifier .pointerHoverIcon(PointerIcon .Hand ),
364+ onClick = { onButtonClick(ContentDialogButton .Secondary ) },
365+ ) {
366+ Text (
367+ tertiaryButtonText,
368+ style = LocalTypography .current.bodyStrong,
369+ color = FluentTheme .colors.text.text.primary
370+ )
371+ }
372+ AccentButton (
373+ modifier = Modifier .pointerHoverIcon(PointerIcon .Hand ),
374+ onClick = { onButtonClick(ContentDialogButton .Primary ) },
375+ buttonColors = if (isWarning) customDangerButtonColors() else customAccentButtonColors()
376+ ) {
377+ Text (
378+ primaryButtonText,
379+ style = LocalTypography .current.bodyStrong,
380+ color = FluentTheme .colors.text.text.primary
381+ )
382+ }
383+ }
335384 }
336- AccentButton (
337- modifier = Modifier .pointerHoverIcon(PointerIcon .Hand ),
338- onClick = { onButtonClick(ContentDialogButton .Primary ) },
339- buttonColors = if (isWarning) customDangerButtonColors() else customAccentButtonColors()
385+ } else {
386+ Row (
387+ horizontalArrangement = Arrangement .spacedBy(8 .dp, Alignment .End ),
388+ verticalAlignment = Alignment .CenterVertically ,
389+ modifier = Modifier .fillMaxWidth()
340390 ) {
341- Text (
342- primaryButtonText,
343- style = LocalTypography .current.bodyStrong,
344- color = FluentTheme .colors.text.text.primary
345- )
391+ if (secondaryButtonText != null ) Button (
392+ modifier = Modifier .pointerHoverIcon(PointerIcon .Hand ),
393+ onClick = { onButtonClick(ContentDialogButton .Secondary ) },
394+ ) {
395+ Text (
396+ secondaryButtonText,
397+ style = LocalTypography .current.bodyStrong,
398+ color = FluentTheme .colors.text.text.primary
399+ )
400+ }
401+ AccentButton (
402+ modifier = Modifier .pointerHoverIcon(PointerIcon .Hand ),
403+ onClick = { onButtonClick(ContentDialogButton .Primary ) },
404+ buttonColors = if (isWarning) customDangerButtonColors() else customAccentButtonColors()
405+ ) {
406+ Text (
407+ primaryButtonText,
408+ style = LocalTypography .current.bodyStrong,
409+ color = FluentTheme .colors.text.text.primary
410+ )
411+ }
346412 }
347413 }
348414 }
@@ -357,22 +423,33 @@ fun SslTrustDialogHost(
357423) {
358424 val prompt by SslTrustManager .pendingPrompt.collectAsState()
359425 val host = prompt?.host ? : return
360- CustomConfirmDialog (
361- onDismissRequest = {
362- SslTrustManager .resolvePrompt(false )
363- onReject?.invoke(host)
364- },
426+ CustomContentDialog (
365427 title = " 证书校验失败" ,
366- contentText = " $host 的证书校验失败,可能存在安全风险,是否继续连接?" ,
367- dismissButtonText = " 取消" ,
368- onDismissClick = {
369- SslTrustManager .resolvePrompt(false )
370- onReject?.invoke(host)
428+ visible = true ,
429+ primaryButtonText = " 忽略风险,继续访问" ,
430+ secondaryButtonText = " 取消访问" ,
431+ tertiaryButtonText = " 将此 ip 或域名加入白名单" ,
432+ size = DialogSize .Max ,
433+ isWarning = true ,
434+ onButtonClick = { button ->
435+ when (button) {
436+ ContentDialogButton .Primary -> {
437+ SslTrustManager .resolvePrompt(SslTrustDecision .AllowTemporary )
438+ onAllow?.invoke(host)
439+ }
440+ ContentDialogButton .Secondary -> {
441+ SslTrustManager .resolvePrompt(SslTrustDecision .Reject )
442+ onReject?.invoke(host)
443+ }
444+ else -> Unit
445+ }
371446 },
372- confirmButtonText = " 忽略风险" ,
373- onConfirmClick = {
374- SslTrustManager .resolvePrompt(true )
447+ onTertiaryClick = {
448+ SslTrustManager .resolvePrompt(SslTrustDecision .AllowPersist )
375449 onAllow?.invoke(host)
450+ },
451+ content = {
452+ Text (" 「$host 」的证书校验不通过,可能是证书过期、域名不匹配或自签名证书。继续连接将绕过安全保护,是否继续访问?" )
376453 }
377454 )
378455}
0 commit comments