Skip to content

Commit 407ef28

Browse files
committed
Replace SendQRDialog with WaitingForReceiver screen
1 parent cb496ce commit 407ef28

File tree

2 files changed

+108
-258
lines changed

2 files changed

+108
-258
lines changed

app/src/main/java/dev/arkbuilders/drop/app/presentation/send/Send.kt

Lines changed: 2 additions & 210 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,30 @@
11
package dev.arkbuilders.drop.app.presentation.send
22

3-
import android.content.ClipData
4-
import android.content.ClipboardManager
5-
import android.content.Context
6-
import android.graphics.Bitmap
73
import androidx.activity.compose.rememberLauncherForActivityResult
84
import androidx.activity.result.contract.ActivityResultContracts
9-
import androidx.compose.foundation.Image
10-
import androidx.compose.foundation.layout.Arrangement
115
import androidx.compose.foundation.layout.Column
12-
import androidx.compose.foundation.layout.Row
13-
import androidx.compose.foundation.layout.Spacer
146
import androidx.compose.foundation.layout.fillMaxSize
15-
import androidx.compose.foundation.layout.height
16-
import androidx.compose.foundation.layout.padding
17-
import androidx.compose.foundation.layout.size
18-
import androidx.compose.foundation.layout.width
19-
import androidx.compose.foundation.lazy.rememberLazyListState
207
import androidx.compose.foundation.rememberScrollState
21-
import androidx.compose.foundation.shape.RoundedCornerShape
228
import androidx.compose.foundation.verticalScroll
23-
import androidx.compose.material3.AlertDialog
249
import androidx.compose.material3.ExperimentalMaterial3Api
25-
import androidx.compose.material3.Icon
26-
import androidx.compose.material3.MaterialTheme
27-
import androidx.compose.material3.Surface
28-
import androidx.compose.material3.Text
29-
import androidx.compose.material3.TextButton
3010
import androidx.compose.runtime.Composable
3111
import androidx.compose.runtime.getValue
32-
import androidx.compose.runtime.mutableStateOf
33-
import androidx.compose.runtime.remember
34-
import androidx.compose.runtime.rememberCoroutineScope
35-
import androidx.compose.runtime.setValue
36-
import androidx.compose.ui.Alignment
3712
import androidx.compose.ui.Modifier
38-
import androidx.compose.ui.graphics.Color
39-
import androidx.compose.ui.graphics.asImageBitmap
40-
import androidx.compose.ui.platform.LocalContext
41-
import androidx.compose.ui.platform.LocalHapticFeedback
42-
import androidx.compose.ui.text.font.FontWeight
43-
import androidx.compose.ui.text.style.TextAlign
44-
import androidx.compose.ui.unit.dp
4513
import androidx.navigation.NavController
46-
import compose.icons.TablerIcons
47-
import compose.icons.tablericons.Copy
48-
import compose.icons.tablericons.Qrcode
4914
import dev.arkbuilders.drop.app.presentation.components.DropErrorCard
5015
import dev.arkbuilders.drop.app.presentation.components.DropTopBarBack
51-
import dev.arkbuilders.drop.app.presentation.send.components.ButtonSize
52-
import dev.arkbuilders.drop.app.presentation.send.components.ButtonVariant
53-
import dev.arkbuilders.drop.app.presentation.send.components.SendButton
54-
import dev.arkbuilders.drop.app.presentation.send.components.SendLoadingIndicator
5516
import dev.arkbuilders.drop.app.presentation.send.components.phase.FileSelectionPhase
5617
import dev.arkbuilders.drop.app.presentation.send.components.phase.GeneratingQRPhase
5718
import dev.arkbuilders.drop.app.presentation.send.components.phase.TransferCompletePhase
5819
import dev.arkbuilders.drop.app.presentation.send.components.phase.TransferringPhase
5920
import dev.arkbuilders.drop.app.presentation.send.components.phase.WaitingForReceiverPhase
60-
import kotlinx.coroutines.delay
61-
import kotlinx.coroutines.launch
6221
import org.koin.compose.koinInject
6322
import org.orbitmvi.orbit.compose.collectAsState
6423
import org.orbitmvi.orbit.compose.collectSideEffect
6524

6625
@OptIn(ExperimentalMaterial3Api::class)
6726
@Composable
6827
fun Send(navController: NavController) {
69-
val haptic = LocalHapticFeedback.current
70-
val listState = rememberLazyListState()
7128
val viewModel: SendViewModel = koinInject()
7229

7330
val state by viewModel.collectAsState()
@@ -127,6 +84,8 @@ fun Send(navController: NavController) {
12784

12885
is SendScreenState.WaitingForReceiver -> {
12986
WaitingForReceiverPhase(
87+
qrBitmap = sendScreenState.qrBitmap,
88+
copyString = sendScreenState.copyString,
13089
fileCount = sendScreenState.files.size,
13190
onCancel = { viewModel.onCancelTransfer() },
13291
)
@@ -163,176 +122,9 @@ fun Send(navController: NavController) {
163122
)
164123
}
165124
}
166-
167-
if (sendScreenState is SendScreenState.WaitingForReceiver) {
168-
SendQRDialog(
169-
qrBitmap = sendScreenState.qrBitmap,
170-
fileCount = sendScreenState.files.size,
171-
copyString = sendScreenState.copyString,
172-
onDismiss = { },
173-
onCancel = {},
174-
)
175-
}
176125
}
177126
}
178127

179-
private fun copyToClipboard(
180-
context: Context,
181-
text: String,
182-
label: String = "Transfer Info",
183-
) {
184-
val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
185-
val clipData = ClipData.newPlainText(label, text)
186-
clipboardManager.setPrimaryClip(clipData)
187-
}
188-
189-
@Composable
190-
private fun SendQRDialog(
191-
qrBitmap: Bitmap,
192-
fileCount: Int,
193-
copyString: String?,
194-
onDismiss: () -> Unit,
195-
onCancel: () -> Unit,
196-
) {
197-
val context = LocalContext.current
198-
val scope = rememberCoroutineScope()
199-
var showCopySuccess by remember { mutableStateOf(false) }
200-
201-
AlertDialog(
202-
onDismissRequest = onDismiss,
203-
title = {
204-
Row(
205-
verticalAlignment = Alignment.CenterVertically,
206-
horizontalArrangement = Arrangement.spacedBy(12.dp),
207-
) {
208-
Icon(
209-
TablerIcons.Qrcode,
210-
contentDescription = null,
211-
modifier = Modifier.size(24.dp),
212-
tint = MaterialTheme.colorScheme.primary,
213-
)
214-
Text(
215-
"QR Code for Transfer",
216-
style =
217-
MaterialTheme.typography.headlineSmall.copy(
218-
fontWeight = FontWeight.Bold,
219-
),
220-
)
221-
}
222-
},
223-
text = {
224-
Column(
225-
horizontalAlignment = Alignment.CenterHorizontally,
226-
) {
227-
Surface(
228-
shape = RoundedCornerShape(16.dp),
229-
color = Color.White,
230-
shadowElevation = 4.dp,
231-
) {
232-
Image(
233-
bitmap = qrBitmap.asImageBitmap(),
234-
contentDescription = "QR code for file transfer",
235-
modifier =
236-
Modifier
237-
.size(220.dp)
238-
.padding(16.dp),
239-
)
240-
}
241-
242-
Spacer(modifier = Modifier.height(20.dp))
243-
244-
Text(
245-
text = "Show this QR code to the receiver",
246-
style =
247-
MaterialTheme.typography.bodyLarge.copy(
248-
fontWeight = FontWeight.Medium,
249-
),
250-
color = MaterialTheme.colorScheme.onSurfaceVariant,
251-
textAlign = TextAlign.Center,
252-
)
253-
254-
Spacer(modifier = Modifier.height(8.dp))
255-
256-
Text(
257-
text = "$fileCount file${if (fileCount != 1) "s" else ""} ready to transfer",
258-
style = MaterialTheme.typography.bodyMedium,
259-
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.8f),
260-
textAlign = TextAlign.Center,
261-
)
262-
263-
// Copy functionality
264-
if (!copyString.isNullOrEmpty()) {
265-
Spacer(modifier = Modifier.height(16.dp))
266-
267-
SendButton(
268-
onClick = {
269-
copyToClipboard(context, copyString, "Transfer Code")
270-
showCopySuccess = true
271-
scope.launch {
272-
delay(2000)
273-
showCopySuccess = false
274-
}
275-
},
276-
variant = ButtonVariant.Secondary,
277-
size = ButtonSize.Medium,
278-
) {
279-
Icon(
280-
TablerIcons.Copy,
281-
contentDescription = null,
282-
modifier = Modifier.size(16.dp),
283-
)
284-
Spacer(modifier = Modifier.width(8.dp))
285-
Text(
286-
if (showCopySuccess) "Copied!" else "Copy Code",
287-
fontWeight = FontWeight.Medium,
288-
)
289-
}
290-
291-
if (showCopySuccess) {
292-
Spacer(modifier = Modifier.height(8.dp))
293-
Text(
294-
text = "Transfer code copied to clipboard",
295-
style = MaterialTheme.typography.bodySmall,
296-
color = MaterialTheme.colorScheme.primary,
297-
textAlign = TextAlign.Center,
298-
)
299-
}
300-
}
301-
302-
Spacer(modifier = Modifier.height(16.dp))
303-
304-
Row(
305-
verticalAlignment = Alignment.CenterVertically,
306-
horizontalArrangement = Arrangement.spacedBy(8.dp),
307-
) {
308-
SendLoadingIndicator()
309-
Text(
310-
text = "Waiting for receiver to scan...",
311-
style =
312-
MaterialTheme.typography.bodyMedium.copy(
313-
fontWeight = FontWeight.Medium,
314-
),
315-
color = MaterialTheme.colorScheme.primary,
316-
)
317-
}
318-
}
319-
},
320-
confirmButton = {},
321-
dismissButton = {
322-
TextButton(
323-
onClick = onCancel,
324-
shape = RoundedCornerShape(8.dp),
325-
) {
326-
Text(
327-
"Cancel Transfer",
328-
fontWeight = FontWeight.Medium,
329-
)
330-
}
331-
},
332-
shape = RoundedCornerShape(20.dp),
333-
)
334-
}
335-
336128
private fun SendException.toMessage() =
337129
when (this) {
338130
SendException.TransferInitializationFailed -> "Transfer initialization failed"

0 commit comments

Comments
 (0)