1 /*
2 * Copyright (C) 2025 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.android.permissioncontroller.wear.permission.components.material3
17
18 import androidx.compose.foundation.layout.RowScope
19 import androidx.compose.foundation.layout.size
20 import androidx.compose.runtime.Composable
21 import androidx.compose.ui.Alignment
22 import androidx.compose.ui.Modifier
23 import androidx.compose.ui.unit.dp
24 import androidx.wear.compose.foundation.lazy.rememberScalingLazyListState
25 import androidx.wear.compose.material3.AlertDialog as Material3AlertDialog
26 import androidx.wear.compose.material3.AlertDialogDefaults
27 import androidx.wear.compose.material3.Text
28 import com.android.permissioncontroller.wear.permission.components.material2.AlertDialog
29 import com.android.permissioncontroller.wear.permission.components.theme.WearPermissionMaterialUIVersion
30
31 data class DialogButtonContent(
32 val icon: WearPermissionIconBuilder? = null,
33 val onClick: (() -> Unit),
34 )
35
36 @Composable
WearPermissionConfirmationDialognull37 fun WearPermissionConfirmationDialog(
38 materialUIVersion: WearPermissionMaterialUIVersion =
39 WearPermissionMaterialUIVersion.MATERIAL2_5,
40 show: Boolean,
41 iconRes: WearPermissionIconBuilder? = null,
42 title: String? = null,
43 message: String? = null,
44 positiveButtonContent: DialogButtonContent? = null,
45 negativeButtonContent: DialogButtonContent? = null,
46 ) {
47
48 if (materialUIVersion == WearPermissionMaterialUIVersion.MATERIAL3) {
49 if (
50 (positiveButtonContent == null && negativeButtonContent != null) ||
51 (positiveButtonContent != null && negativeButtonContent == null)
52 ) {
53 val edgeButtonContent = (positiveButtonContent ?: negativeButtonContent)!!
54 WearPermissionConfirmationDialogInternal(
55 show = show,
56 edgeButtonContent = edgeButtonContent,
57 iconRes = iconRes,
58 title = title,
59 message = message,
60 )
61 } else {
62 WearPermissionConfirmationDialogInternal(
63 show = show,
64 positiveButtonContent = positiveButtonContent,
65 negativeButtonContent = negativeButtonContent,
66 iconRes = iconRes,
67 title = title,
68 message = message,
69 )
70 }
71 } else {
72 AlertDialog(
73 title = title,
74 iconRes = iconRes,
75 message = message ?: "",
76 positiveButtonContent = positiveButtonContent,
77 negativeButtonContent = negativeButtonContent,
78 showDialog = show,
79 scalingLazyListState = rememberScalingLazyListState(),
80 )
81 }
82 }
83
84 @Composable
WearPermissionConfirmationDialogInternalnull85 private fun WearPermissionConfirmationDialogInternal(
86 show: Boolean,
87 edgeButtonContent: DialogButtonContent,
88 iconRes: WearPermissionIconBuilder?,
89 title: String?,
90 message: String?,
91 ) {
92 val edgeIcon: @Composable RowScope.() -> Unit =
93 edgeButtonContent.icon?.let {
94 { it.modifier(Modifier.size(36.dp).align(Alignment.CenterVertically)).build() }
95 } ?: AlertDialogDefaults.ConfirmIcon
96
97 Material3AlertDialog(
98 visible = show,
99 onDismissRequest = edgeButtonContent.onClick,
100 edgeButton = {
101 AlertDialogDefaults.EdgeButton(onClick = edgeButtonContent.onClick, content = edgeIcon)
102 },
103 icon = { iconRes?.build() },
104 title = title?.let { { Text(text = title) } } ?: {},
105 text = message?.let { { Text(text = message) } },
106 )
107 }
108
109 @Composable
WearPermissionConfirmationDialogInternalnull110 private fun WearPermissionConfirmationDialogInternal(
111 show: Boolean,
112 positiveButtonContent: DialogButtonContent?,
113 negativeButtonContent: DialogButtonContent?,
114 iconRes: WearPermissionIconBuilder?,
115 title: String?,
116 message: String?,
117 ) {
118 val positiveButton: (@Composable RowScope.() -> Unit)? =
119 positiveButtonContent?.let {
120 {
121 val positiveIcon: @Composable RowScope.() -> Unit =
122 positiveButtonContent.icon?.let {
123 {
124 it.modifier(Modifier.size(36.dp).align(Alignment.CenterVertically))
125 .build()
126 }
127 } ?: AlertDialogDefaults.ConfirmIcon
128
129 AlertDialogDefaults.ConfirmButton(
130 onClick = positiveButtonContent.onClick,
131 content = positiveIcon,
132 )
133 }
134 }
135
136 val negativeButton: (@Composable RowScope.() -> Unit)? =
137 negativeButtonContent?.let {
138 {
139 val negativeIcon: @Composable RowScope.() -> Unit =
140 negativeButtonContent.icon?.let {
141 {
142 it.modifier(Modifier.size(36.dp).align(Alignment.CenterVertically))
143 .build()
144 }
145 } ?: AlertDialogDefaults.DismissIcon
146
147 AlertDialogDefaults.DismissButton(
148 onClick = negativeButtonContent.onClick,
149 content = negativeIcon,
150 )
151 }
152 }
153
154 Material3AlertDialog(
155 visible = show,
156 onDismissRequest = negativeButtonContent?.onClick ?: {},
157 confirmButton = positiveButton ?: {},
158 dismissButton = negativeButton ?: {},
159 icon = { iconRes?.build() },
160 title = title?.let { { Text(text = title) } } ?: {},
161 text = message?.let { { Text(text = message) } },
162 )
163 }
164