// Copyright (c) Tailscale Inc & AUTHORS // SPDX-License-Identifier: BSD-3-Clause package com.tailscale.ipn.ui.view import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Dialog import androidx.lifecycle.viewmodel.compose.viewModel import com.tailscale.ipn.R import com.tailscale.ipn.ui.viewModel.LoginQRViewModel @OptIn(ExperimentalMaterial3Api::class) @Composable fun LoginQRView(onDismiss: () -> Unit = {}, model: LoginQRViewModel = viewModel()) { Surface(color = MaterialTheme.colorScheme.scrim, modifier = Modifier.fillMaxSize()) { Dialog(onDismissRequest = onDismiss) { val image = model.qrCode.collectAsState() Column( modifier = Modifier.clip(RoundedCornerShape(10.dp)) .background(MaterialTheme.colorScheme.surfaceContainer) .padding(20.dp), verticalArrangement = Arrangement.spacedBy(10.dp), horizontalAlignment = Alignment.CenterHorizontally) { Text( text = stringResource(R.string.scan_to_connect_to_your_tailnet), style = MaterialTheme.typography.titleMedium, color = MaterialTheme.colorScheme.onSurface) Box( modifier = Modifier.size(200.dp) .background(MaterialTheme.colorScheme.onSurface) .fillMaxWidth(), contentAlignment = Alignment.Center) { image.value?.let { Image( bitmap = it, contentDescription = "Scan to login", modifier = Modifier.fillMaxSize()) } } Button(onClick = onDismiss) { Text(text = stringResource(R.string.dismiss)) } } } } }