1
1
package com.capyreader.app.ui.accounts
2
2
3
+ import android.app.Activity
4
+ import android.security.KeyChain
5
+ import androidx.compose.foundation.interaction.MutableInteractionSource
6
+ import androidx.compose.foundation.interaction.PressInteraction
3
7
import androidx.compose.foundation.layout.Arrangement
4
8
import androidx.compose.foundation.layout.Box
5
9
import androidx.compose.foundation.layout.Column
@@ -20,6 +24,8 @@ import androidx.compose.material3.Text
20
24
import androidx.compose.material3.TextField
21
25
import androidx.compose.material3.TopAppBar
22
26
import androidx.compose.runtime.Composable
27
+ import androidx.compose.runtime.LaunchedEffect
28
+ import androidx.compose.runtime.remember
23
29
import androidx.compose.ui.Alignment
24
30
import androidx.compose.ui.Modifier
25
31
import androidx.compose.ui.platform.LocalContext
@@ -45,9 +51,11 @@ fun LoginView(
45
51
onUsernameChange : (username: String ) -> Unit = {},
46
52
onPasswordChange : (password: String ) -> Unit = {},
47
53
onUrlChange : (url: String ) -> Unit = {},
54
+ onClientCertAliasChange : (clientCertAlias: String ) -> Unit = {},
48
55
onSubmit : () -> Unit = {},
49
56
onNavigateBack : () -> Unit = {},
50
57
url : String ,
58
+ clientCertAlias : String ,
51
59
username : String ,
52
60
password : String ,
53
61
loading : Boolean = false,
@@ -104,6 +112,10 @@ fun LoginView(
104
112
}
105
113
}
106
114
)
115
+ CertificateField (
116
+ onChange = onClientCertAliasChange,
117
+ certAlias = clientCertAlias,
118
+ )
107
119
}
108
120
AuthFields (
109
121
username = username,
@@ -148,6 +160,37 @@ fun UrlField(
148
160
)
149
161
}
150
162
163
+ @Composable
164
+ fun CertificateField (
165
+ onChange : (certAlias: String ) -> Unit ,
166
+ certAlias : String ,
167
+ ) {
168
+ val context = LocalContext .current
169
+ TextField (
170
+ value = certAlias,
171
+ onValueChange = onChange,
172
+ singleLine = true ,
173
+ label = {
174
+ Text (stringResource(R .string.auth_fields_client_certificate))
175
+ },
176
+ modifier = Modifier
177
+ .fillMaxWidth(),
178
+ readOnly = true ,
179
+ interactionSource = remember { MutableInteractionSource () }
180
+ .also { interactionSource ->
181
+ LaunchedEffect (interactionSource) {
182
+ interactionSource.interactions.collect {
183
+ if (it is PressInteraction .Release ) {
184
+ KeyChain .choosePrivateKeyAlias(context as Activity , { alias ->
185
+ onChange(alias ? : " " )
186
+ }, null , null , null , null )
187
+ }
188
+ }
189
+ }
190
+ }
191
+ )
192
+ }
193
+
151
194
@Preview
152
195
@Composable
153
196
private fun LoginViewPreview () {
@@ -162,6 +205,7 @@ private fun LoginViewPreview() {
162
205
LoginView (
163
206
source = Source .FEEDBIN ,
164
207
url = " " ,
208
+ clientCertAlias = " " ,
165
209
166
210
password = " " ,
167
211
)
0 commit comments