, value: T) {
+ coroutineScope.launch { context.dataStore.edit { it[key] = value } }
}
- }
-
- Scaffold(
- topBar = {
- LargeTopAppBar(
- title = { Text(stringResource(R.string.settings)) },
- navigationIcon = {
- IconButton(onClick = onBackPressed) {
- Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.go_back))
- }
- },
- scrollBehavior = scrollBehavior,
- )
- },
- modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
- ) { innerPadding ->
- Column(Modifier.padding(innerPadding).verticalScroll(rememberScrollState())) {
- Row(
- modifier =
- Modifier.clickable { setUnmeteredOnly(unmeteredOnly.not()) }
- .padding(16.dp, 12.dp)
- .fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween,
- verticalAlignment = Alignment.CenterVertically,
- ) {
- Column(modifier = Modifier.fillMaxWidth(0.8f)) {
- Text(stringResource(R.string.unmetered_only_setting))
- Text(
- stringResource(R.string.unmetered_only_setting_detail),
- style = MaterialTheme.typography.bodyMedium)
- }
- Switch(checked = unmeteredOnly, onCheckedChange = { setUnmeteredOnly(it) })
- }
- Row(
- modifier =
- Modifier.clickable { setValue(CLIPBOARD_PASTE_ENABLED, clipboardPasteEnabled.not()) }
- .padding(16.dp, 12.dp)
- .fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween,
- verticalAlignment = Alignment.CenterVertically,
- ) {
- Column(modifier = Modifier.fillMaxWidth(0.8f)) {
- Text(stringResource(R.string.clipboard_paste_enabled))
- Text(
- stringResource(R.string.clipboard_paste_description),
- style = MaterialTheme.typography.bodyMedium)
+ val setUnmeteredOnly: (Boolean) -> Unit = { value ->
+ coroutineScope.launch {
+ context.dataStore.edit { it[UNMETERED_ONLY] = value }
+ context.enqueueNotificationWorker()
}
- Switch(
- checked = clipboardPasteEnabled,
- onCheckedChange = { setValue(CLIPBOARD_PASTE_ENABLED, it) })
- }
+ }
- // Preferred Region Setting
- Column(modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth()) {
- Text(stringResource(R.string.preferred_region))
- Text(
- stringResource(R.string.preferred_region_description),
- style = MaterialTheme.typography.bodyMedium,
- modifier = Modifier.padding(bottom = 8.dp)
- )
-
- ExposedDropdownMenuBox(
- expanded = regionDropdownExpanded,
- onExpandedChange = { regionDropdownExpanded = !regionDropdownExpanded }
- ) {
- OutlinedTextField(
- value = when (preferredRegion) {
- "international" -> stringResource(R.string.region_international)
- "north_america" -> stringResource(R.string.region_north_america)
- "europe" -> stringResource(R.string.region_europe)
- "asia" -> stringResource(R.string.region_asia)
- "belarus" -> stringResource(R.string.country_belarus)
- "bulgaria" -> stringResource(R.string.country_bulgaria)
- "czech" -> stringResource(R.string.country_czech)
- "uk" -> stringResource(R.string.country_uk)
- "ireland" -> stringResource(R.string.country_ireland)
- "poland" -> stringResource(R.string.country_poland)
- "hungary" -> stringResource(R.string.country_hungary)
- "germany" -> stringResource(R.string.country_germany)
- "italy" -> stringResource(R.string.country_italy)
- "romania" -> stringResource(R.string.country_romania)
- "scandinavia" -> stringResource(R.string.country_scandinavia)
- "ukraine" -> stringResource(R.string.country_ukraine)
- "india" -> stringResource(R.string.country_india)
- "thailand" -> stringResource(R.string.country_thailand)
- else -> stringResource(R.string.region_international)
- },
- onValueChange = { },
- readOnly = true,
- trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded = regionDropdownExpanded) },
- modifier = Modifier.menuAnchor().fillMaxWidth()
- )
-
- ExposedDropdownMenu(
- expanded = regionDropdownExpanded,
- onDismissRequest = { regionDropdownExpanded = false }
- ) {
- // Continental regions
- DropdownMenuItem(
- text = { Text(stringResource(R.string.region_international)) },
- onClick = {
- setValue(PREFERRED_REGION, "international")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.region_north_america)) },
- onClick = {
- setValue(PREFERRED_REGION, "north_america")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.region_europe)) },
- onClick = {
- setValue(PREFERRED_REGION, "europe")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.region_asia)) },
- onClick = {
- setValue(PREFERRED_REGION, "asia")
- regionDropdownExpanded = false
- }
- )
-
- // European countries
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_belarus)) },
- onClick = {
- setValue(PREFERRED_REGION, "belarus")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_bulgaria)) },
- onClick = {
- setValue(PREFERRED_REGION, "bulgaria")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_czech)) },
- onClick = {
- setValue(PREFERRED_REGION, "czech")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_uk)) },
- onClick = {
- setValue(PREFERRED_REGION, "uk")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_ireland)) },
- onClick = {
- setValue(PREFERRED_REGION, "ireland")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_poland)) },
- onClick = {
- setValue(PREFERRED_REGION, "poland")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_hungary)) },
- onClick = {
- setValue(PREFERRED_REGION, "hungary")
- regionDropdownExpanded = false
- }
+ Scaffold(
+ topBar = {
+ LargeTopAppBar(
+ title = { Text(stringResource(R.string.settings)) },
+ navigationIcon = {
+ IconButton(onClick = onBackPressed) {
+ Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.go_back))
+ }
+ },
+ scrollBehavior = scrollBehavior,
)
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_germany)) },
- onClick = {
- setValue(PREFERRED_REGION, "germany")
- regionDropdownExpanded = false
+ },
+ modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
+ ) { innerPadding ->
+ Column(Modifier.padding(innerPadding).verticalScroll(rememberScrollState())) {
+ Row(
+ modifier =
+ Modifier.clickable { setUnmeteredOnly(unmeteredOnly.not()) }
+ .padding(16.dp, 12.dp)
+ .fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Column(modifier = Modifier.fillMaxWidth(0.8f)) {
+ Text(stringResource(R.string.unmetered_only_setting))
+ Text(
+ stringResource(R.string.unmetered_only_setting_detail),
+ style = MaterialTheme.typography.bodyMedium
+ )
}
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_italy)) },
- onClick = {
- setValue(PREFERRED_REGION, "italy")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_romania)) },
- onClick = {
- setValue(PREFERRED_REGION, "romania")
- regionDropdownExpanded = false
+ Switch(checked = unmeteredOnly, onCheckedChange = { setUnmeteredOnly(it) })
+ }
+
+ Row(
+ modifier =
+ Modifier.clickable {
+ setValue(CLIPBOARD_PASTE_ENABLED, clipboardPasteEnabled.not())
+ }
+ .padding(16.dp, 12.dp)
+ .fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Column(modifier = Modifier.fillMaxWidth(0.8f)) {
+ Text(stringResource(R.string.clipboard_paste_enabled))
+ Text(
+ stringResource(R.string.clipboard_paste_description),
+ style = MaterialTheme.typography.bodyMedium
+ )
}
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_scandinavia)) },
- onClick = {
- setValue(PREFERRED_REGION, "scandinavia")
- regionDropdownExpanded = false
+ Switch(
+ checked = clipboardPasteEnabled,
+ onCheckedChange = { setValue(CLIPBOARD_PASTE_ENABLED, it) }
+ )
+ }
+
+ Column(modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth()) {
+ Text(stringResource(R.string.preferred_region))
+ Text(
+ stringResource(R.string.preferred_region_description),
+ style = MaterialTheme.typography.bodyMedium,
+ modifier = Modifier.padding(bottom = 8.dp)
+ )
+
+ ExposedDropdownMenuBox(
+ expanded = regionDropdownExpanded,
+ onExpandedChange = { regionDropdownExpanded = !regionDropdownExpanded }
+ ) {
+ OutlinedTextField(
+ value =
+ when (preferredRegion) {
+ "international" -> stringResource(R.string.region_international)
+ "north_america" -> stringResource(R.string.region_north_america)
+ "europe" -> stringResource(R.string.region_europe)
+ "asia" -> stringResource(R.string.region_asia)
+ "belarus" -> stringResource(R.string.country_belarus)
+ "bulgaria" -> stringResource(R.string.country_bulgaria)
+ "czech" -> stringResource(R.string.country_czech)
+ "uk" -> stringResource(R.string.country_uk)
+ "ireland" -> stringResource(R.string.country_ireland)
+ "poland" -> stringResource(R.string.country_poland)
+ "hungary" -> stringResource(R.string.country_hungary)
+ "germany" -> stringResource(R.string.country_germany)
+ "italy" -> stringResource(R.string.country_italy)
+ "romania" -> stringResource(R.string.country_romania)
+ "scandinavia" -> stringResource(R.string.country_scandinavia)
+ "ukraine" -> stringResource(R.string.country_ukraine)
+ "india" -> stringResource(R.string.country_india)
+ "thailand" -> stringResource(R.string.country_thailand)
+ else -> stringResource(R.string.region_international)
+ },
+ onValueChange = {},
+ readOnly = true,
+ trailingIcon = {
+ ExposedDropdownMenuDefaults.TrailingIcon(
+ expanded = regionDropdownExpanded
+ )
+ },
+ modifier = Modifier.menuAnchor().fillMaxWidth()
+ )
+
+ ExposedDropdownMenu(
+ expanded = regionDropdownExpanded,
+ onDismissRequest = { regionDropdownExpanded = false }
+ ) {
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.region_international)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "international")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.region_north_america)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "north_america")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.region_europe)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "europe")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.region_asia)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "asia")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_belarus)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "belarus")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_bulgaria)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "bulgaria")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_czech)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "czech")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_uk)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "uk")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_ireland)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "ireland")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_poland)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "poland")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_hungary)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "hungary")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_germany)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "germany")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_italy)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "italy")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_romania)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "romania")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_scandinavia)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "scandinavia")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_ukraine)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "ukraine")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_india)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "india")
+ regionDropdownExpanded = false
+ }
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_thailand)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "thailand")
+ regionDropdownExpanded = false
+ }
+ )
+ }
}
+ }
+
+ Text(
+ stringResource(R.string.settings_api_keys),
+ modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 2.dp),
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
)
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_ukraine)) },
- onClick = {
- setValue(PREFERRED_REGION, "ukraine")
- regionDropdownExpanded = false
- }
+
+ OutlinedTextField(
+ dhlApiKey,
+ { setValue(DHL_API_KEY, it) },
+ modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp).fillMaxWidth(),
+ label = { Text(stringResource(R.string.service_dhl)) },
+ singleLine = true,
+ visualTransformation = PasswordVisualTransformation(),
)
-
- // Asian countries
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_india)) },
- onClick = {
- setValue(PREFERRED_REGION, "india")
- regionDropdownExpanded = false
- }
+
+ Text(
+ AnnotatedString.fromHtml(
+ stringResource(R.string.dhl_api_key_flavor_text),
+ linkStyles =
+ TextLinkStyles(
+ style =
+ SpanStyle(
+ textDecoration = TextDecoration.Underline,
+ color = MaterialTheme.colorScheme.primary
+ )
+ )
+ ),
+ style = MaterialTheme.typography.bodyMedium,
+ modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
)
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_thailand)) },
- onClick = {
- setValue(PREFERRED_REGION, "thailand")
- regionDropdownExpanded = false
- }
+
+ Text(
+ stringResource(R.string.settings_experimental),
+ modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 2.dp),
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
)
- }
- }
- }
- Text(
- stringResource(R.string.settings_api_keys),
- modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 2.dp),
- style = MaterialTheme.typography.bodyMedium,
- color = MaterialTheme.colorScheme.onSurfaceVariant,
- )
+ Row(
+ modifier =
+ Modifier.clickable { setValue(DEMO_MODE, demoMode.not()) }
+ .padding(16.dp, 12.dp)
+ .fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Column(modifier = Modifier.fillMaxWidth(0.8f)) {
+ Text(stringResource(R.string.demo_mode))
+ Text(
+ stringResource(R.string.demo_mode_detail),
+ style = MaterialTheme.typography.bodyMedium
+ )
+ }
+ Switch(checked = demoMode, onCheckedChange = { setValue(DEMO_MODE, it) })
+ }
- OutlinedTextField(
- dhlApiKey,
- { setValue(DHL_API_KEY, it) },
- modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp).fillMaxWidth(),
- label = { Text(stringResource(R.string.service_dhl)) },
- singleLine = true,
- visualTransformation = PasswordVisualTransformation(),
- )
+ if (BuildConfig.DEBUG)
+ FilledTonalButton(
+ onClick = {
+ context.sendNotification(
+ Parcel(0xf100f, "Cool stuff", "", null, Service.EXAMPLE),
+ Status.OutForDelivery,
+ ParcelHistoryItem(
+ "The courier has picked up the package",
+ LocalDateTime.now(),
+ ""
+ )
+ )
+ },
+ modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth()
+ ) {
+ Text("Send test notification")
+ }
- Text(
- AnnotatedString.fromHtml(
- stringResource(R.string.dhl_api_key_flavor_text),
- linkStyles =
- TextLinkStyles(
- style =
- SpanStyle(
- textDecoration = TextDecoration.Underline,
- color = MaterialTheme.colorScheme.primary))),
- style = MaterialTheme.typography.bodyMedium,
- modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp))
+ LogcatButton(modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth())
- Text(
- stringResource(R.string.settings_experimental),
- modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 2.dp),
- style = MaterialTheme.typography.bodyMedium,
- color = MaterialTheme.colorScheme.onSurfaceVariant,
- )
+ FilledTonalButton(
+ onClick = { aboutDialogOpen = true },
+ modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth()
+ ) {
+ Icon(Icons.Filled.Info, contentDescription = stringResource(R.string.about_app))
+ Text(
+ text = " ${stringResource(R.string.about_app)}",
+ modifier = Modifier.padding(start = 8.dp)
+ )
+ }
- Row(
- modifier =
- Modifier.clickable { setValue(DEMO_MODE, demoMode.not()) }
- .padding(16.dp, 12.dp)
- .fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween,
- verticalAlignment = Alignment.CenterVertically,
- ) {
- Column(modifier = Modifier.fillMaxWidth(0.8f)) {
- Text(stringResource(R.string.demo_mode))
- Text(
- stringResource(R.string.demo_mode_detail),
- style = MaterialTheme.typography.bodyMedium)
+ Text(
+ "Parcel ${BuildConfig.VERSION_NAME}",
+ modifier = Modifier.padding(16.dp, 8.dp),
+ style = MaterialTheme.typography.bodySmall,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
}
- Switch(checked = demoMode, onCheckedChange = { setValue(DEMO_MODE, it) })
- }
-
- if (BuildConfig.DEBUG)
- FilledTonalButton(
- onClick = {
- context.sendNotification(
- Parcel(0xf100f, "Cool stuff", "", null, Service.EXAMPLE),
- Status.OutForDelivery,
- ParcelHistoryItem(
- "The courier has picked up the package", LocalDateTime.now(), ""))
- },
- modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth()) {
- Text("Send test notification")
- }
-
- LogcatButton(modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth())
- FilledTonalButton(
- onClick = { aboutDialogOpen = true },
- modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth()
- ) {
- Icon(Icons.Filled.Info, contentDescription = stringResource(R.string.about_app))
- Text(
- text = " ${stringResource(R.string.about_app)}",
- modifier = Modifier.padding(start = 8.dp)
- )
- }
-
- Text(
- "Parcel ${BuildConfig.VERSION_NAME}",
- modifier = Modifier.padding(16.dp, 8.dp),
- style = MaterialTheme.typography.bodySmall,
- color = MaterialTheme.colorScheme.onSurfaceVariant,
- )
- }
-
- if (aboutDialogOpen) {
- AboutDialog { aboutDialogOpen = false }
+ if (aboutDialogOpen) {
+ AboutDialog { aboutDialogOpen = false }
+ }
}
- }
}
@Composable
@PreviewLightDark
private fun SettingsViewPreview() {
- ParcelTrackerTheme {
- SettingsView(
- onBackPressed = {},
- )
- }
+ ParcelTrackerTheme {
+ SettingsView(
+ onBackPressed = {},
+ )
+ }
}
From 031852d0a0e9496247398f99e3862990a7af5c71 Mon Sep 17 00:00:00 2001
From: Zan1456 <62830223+Zan1456@users.noreply.github.com>
Date: Sun, 20 Jul 2025 19:36:40 +0200
Subject: [PATCH 11/18] format with ktfmt
---
.idea/codeStyles/Project.xml | 46 ++
.../api/ExpressOneDeliveryService.kt | 20 +-
.../ui/components/BottomNavBar.kt | 8 +-
.../ui/components/ParcelActionBar.kt | 61 +-
.../parceltracker/ui/components/ParcelRow.kt | 24 +-
.../parceltracker/ui/views/AdaptiveView.kt | 76 +-
.../ui/views/AddEditParcelView.kt | 639 +++++++++--------
.../itsvic/parceltracker/ui/views/HomeView.kt | 24 +-
.../parceltracker/ui/views/ParcelView.kt | 265 +++----
.../parceltracker/ui/views/SettingsView.kt | 678 +++++++++---------
.../parceltracker/ui/views/TabletView.kt | 268 ++++---
11 files changed, 1077 insertions(+), 1032 deletions(-)
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 7643783..64a4c97 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -1,6 +1,47 @@
+
+
+
+
@@ -118,6 +159,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/dev/itsvic/parceltracker/api/ExpressOneDeliveryService.kt b/app/src/main/java/dev/itsvic/parceltracker/api/ExpressOneDeliveryService.kt
index e11f144..a8facf0 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/api/ExpressOneDeliveryService.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/api/ExpressOneDeliveryService.kt
@@ -36,16 +36,16 @@ object ExpressOneDeliveryService : DeliveryService {
currentStatus = Status.Delivered
}
htmlLower.contains("kiszállítás") ||
- htmlLower.contains("out for delivery") ||
- htmlLower.contains("kiadva futárnak") -> {
+ htmlLower.contains("out for delivery") ||
+ htmlLower.contains("kiadva futárnak") -> {
currentStatus = Status.OutForDelivery
}
htmlLower.contains("depóba érkezett") || htmlLower.contains("arrived at depot") -> {
currentStatus = Status.InWarehouse
}
htmlLower.contains("feldolgozás") ||
- htmlLower.contains("processing") ||
- htmlLower.contains("átszállítás") -> {
+ htmlLower.contains("processing") ||
+ htmlLower.contains("átszállítás") -> {
currentStatus = Status.InTransit
}
htmlLower.contains("átvétel") || htmlLower.contains("pickup") -> {
@@ -60,8 +60,8 @@ object ExpressOneDeliveryService : DeliveryService {
val datePattern = "(\\d{4}-\\d{2}-\\d{2})
".toRegex()
val rowPattern =
- "]*>(\\d{2}:\\d{2}:\\d{2}) | \\s*]*>([^<]*) | \\s*]*>([^<]*) | "
- .toRegex()
+ "]*>(\\d{2}:\\d{2}:\\d{2}) | \\s*]*>([^<]*) | \\s*]*>([^<]*) | "
+ .toRegex()
val dateMatches = datePattern.findAll(html)
@@ -106,8 +106,12 @@ object ExpressOneDeliveryService : DeliveryService {
if (history.isEmpty()) {
history.add(
- ParcelHistoryItem(
- "Csomag nyomon követése elindítva", LocalDateTime.now(), "Express One Hungary"))
+ ParcelHistoryItem(
+ "Csomag nyomon követése elindítva",
+ LocalDateTime.now(),
+ "Express One Hungary",
+ )
+ )
}
return Parcel(trackingId, history, currentStatus)
diff --git a/app/src/main/java/dev/itsvic/parceltracker/ui/components/BottomNavBar.kt b/app/src/main/java/dev/itsvic/parceltracker/ui/components/BottomNavBar.kt
index 9fe6f35..0001296 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/ui/components/BottomNavBar.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/ui/components/BottomNavBar.kt
@@ -25,13 +25,13 @@ fun BottomNavBar(
icon = { Icon(Icons.Filled.Home, contentDescription = stringResource(R.string.home)) },
label = { Text(stringResource(R.string.home)) },
selected = currentRoute.contains("HomePage"),
- onClick = onNavigateToHome
+ onClick = onNavigateToHome,
)
NavigationBarItem(
icon = { Icon(Icons.Filled.Add, contentDescription = stringResource(R.string.add)) },
label = { Text(stringResource(R.string.add)) },
selected = currentRoute.contains("AddParcelPage"),
- onClick = onNavigateToAddParcel
+ onClick = onNavigateToAddParcel,
)
NavigationBarItem(
icon = {
@@ -39,7 +39,7 @@ fun BottomNavBar(
},
label = { Text(stringResource(R.string.settings)) },
selected = currentRoute.contains("SettingsPage"),
- onClick = onNavigateToSettings
+ onClick = onNavigateToSettings,
)
}
-}
\ No newline at end of file
+}
diff --git a/app/src/main/java/dev/itsvic/parceltracker/ui/components/ParcelActionBar.kt b/app/src/main/java/dev/itsvic/parceltracker/ui/components/ParcelActionBar.kt
index 4c97db5..51b3ccd 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/ui/components/ParcelActionBar.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/ui/components/ParcelActionBar.kt
@@ -25,7 +25,7 @@ fun ParcelActionBar(
status: Status?,
onEdit: () -> Unit,
onArchive: () -> Unit,
- onDelete: () -> Unit
+ onDelete: () -> Unit,
) {
var showDeleteDialog by remember { mutableStateOf(false) }
@@ -34,7 +34,7 @@ fun ParcelActionBar(
icon = { Icon(Icons.Filled.Edit, contentDescription = stringResource(R.string.edit)) },
label = { Text(stringResource(R.string.edit)) },
selected = false,
- onClick = onEdit
+ onClick = onEdit,
)
if (status == Status.Delivered) {
@@ -42,46 +42,41 @@ fun ParcelActionBar(
icon = {
Icon(
painterResource(R.drawable.archive),
- contentDescription = stringResource(R.string.archive))
+ contentDescription = stringResource(R.string.archive),
+ )
},
label = { Text(stringResource(R.string.archive)) },
selected = false,
- onClick = onArchive
+ onClick = onArchive,
)
}
NavigationBarItem(
- icon = {
- Icon(Icons.Filled.Delete, contentDescription = stringResource(R.string.delete))
- },
+ icon = { Icon(Icons.Filled.Delete, contentDescription = stringResource(R.string.delete)) },
label = { Text(stringResource(R.string.delete)) },
selected = false,
- onClick = { showDeleteDialog = true }
+ onClick = { showDeleteDialog = true },
)
}
- if (showDeleteDialog) {
- AlertDialog(
- onDismissRequest = { showDeleteDialog = false },
- title = { Text(stringResource(R.string.delete)) },
- text = { Text(stringResource(R.string.delete_confirmation)) },
- confirmButton = {
- TextButton(
- onClick = {
- showDeleteDialog = false
- onDelete()
- }
- ) {
- Text(stringResource(R.string.delete))
- }
- },
- dismissButton = {
- TextButton(
- onClick = { showDeleteDialog = false }
- ) {
- Text(stringResource(R.string.cancel))
- }
- }
- )
- }
-}
\ No newline at end of file
+ if (showDeleteDialog) {
+ AlertDialog(
+ onDismissRequest = { showDeleteDialog = false },
+ title = { Text(stringResource(R.string.delete)) },
+ text = { Text(stringResource(R.string.delete_confirmation)) },
+ confirmButton = {
+ TextButton(
+ onClick = {
+ showDeleteDialog = false
+ onDelete()
+ }
+ ) {
+ Text(stringResource(R.string.delete))
+ }
+ },
+ dismissButton = {
+ TextButton(onClick = { showDeleteDialog = false }) { Text(stringResource(R.string.cancel)) }
+ },
+ )
+ }
+}
diff --git a/app/src/main/java/dev/itsvic/parceltracker/ui/components/ParcelRow.kt b/app/src/main/java/dev/itsvic/parceltracker/ui/components/ParcelRow.kt
index d8f6636..16336c7 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/ui/components/ParcelRow.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/ui/components/ParcelRow.kt
@@ -38,17 +38,20 @@ fun ParcelRow(parcel: Parcel, status: Status?, isSelected: Boolean = false, onCl
.fillMaxWidth()
.background(
if (isSelected) MaterialTheme.colorScheme.primaryContainer.copy(alpha = 0.3f)
- else MaterialTheme.colorScheme.surface)
+ else MaterialTheme.colorScheme.surface
+ )
.padding(16.dp, 12.dp),
horizontalArrangement = Arrangement.spacedBy(16.dp),
- verticalAlignment = Alignment.CenterVertically) {
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
if (status != null)
Box(
modifier =
Modifier.size(40.dp)
.clip(CircleShape)
.background(MaterialTheme.colorScheme.primaryContainer),
- contentAlignment = Alignment.Center) {
+ contentAlignment = Alignment.Center,
+ ) {
Icon(
painterResource(
when (status) {
@@ -73,9 +76,11 @@ fun ParcelRow(parcel: Parcel, status: Status?, isSelected: Boolean = false, onCl
Status.Damaged -> R.drawable.outline_deployed_code_alert_24
Status.Destroyed -> R.drawable.outline_destruction_24
else -> R.drawable.outline_question_mark_24
- }),
+ }
+ ),
stringResource(status.nameResource),
- tint = MaterialTheme.colorScheme.primary)
+ tint = MaterialTheme.colorScheme.primary,
+ )
}
Column {
@@ -84,7 +89,8 @@ fun ParcelRow(parcel: Parcel, status: Status?, isSelected: Boolean = false, onCl
Text(
"${stringResource(getDeliveryServiceName(parcel.service)!!)}: ${parcel.parcelId}",
fontSize = 12.sp,
- color = MaterialTheme.colorScheme.onSurfaceVariant)
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
}
}
}
@@ -95,9 +101,9 @@ fun ParcelRowPreview() {
ParcelTrackerTheme {
Box(modifier = Modifier.background(color = MaterialTheme.colorScheme.background)) {
ParcelRow(
- Parcel(0, "My precious package", "EXMPL0001", null, Service.EXAMPLE),
- status = Status.InTransit,
- onClick = {},
+ Parcel(0, "My precious package", "EXMPL0001", null, Service.EXAMPLE),
+ status = Status.InTransit,
+ onClick = {},
)
}
}
diff --git a/app/src/main/java/dev/itsvic/parceltracker/ui/views/AdaptiveView.kt b/app/src/main/java/dev/itsvic/parceltracker/ui/views/AdaptiveView.kt
index 53a2e2d..0ac6eee 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/ui/views/AdaptiveView.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/ui/views/AdaptiveView.kt
@@ -14,45 +14,45 @@ import dev.itsvic.parceltracker.db.ParcelWithStatus
@Composable
fun AdaptiveParcelApp(
- windowSizeClass: WindowSizeClass,
- parcels: List,
- selectedParcel: Parcel?,
- apiParcel: APIParcel?,
- isLoading: Boolean,
- onNavigateToParcel: (Parcel) -> Unit,
- onNavigateToAddParcel: () -> Unit,
- onNavigateToSettings: () -> Unit,
- onEditParcel: (Parcel) -> Unit,
- onDeleteParcel: (Parcel) -> Unit,
- onArchiveParcel: (Parcel) -> Unit,
- onArchivePromptDismissal: (Parcel) -> Unit,
- settingsContent: @Composable () -> Unit,
- addParcelContent: @Composable () -> Unit,
- homeContent: @Composable () -> Unit
+ windowSizeClass: WindowSizeClass,
+ parcels: List,
+ selectedParcel: Parcel?,
+ apiParcel: APIParcel?,
+ isLoading: Boolean,
+ onNavigateToParcel: (Parcel) -> Unit,
+ onNavigateToAddParcel: () -> Unit,
+ onNavigateToSettings: () -> Unit,
+ onEditParcel: (Parcel) -> Unit,
+ onDeleteParcel: (Parcel) -> Unit,
+ onArchiveParcel: (Parcel) -> Unit,
+ onArchivePromptDismissal: (Parcel) -> Unit,
+ settingsContent: @Composable () -> Unit,
+ addParcelContent: @Composable () -> Unit,
+ homeContent: @Composable () -> Unit,
) {
- val isTablet = windowSizeClass.widthSizeClass >= WindowWidthSizeClass.Medium
+ val isTablet = windowSizeClass.widthSizeClass >= WindowWidthSizeClass.Medium
- if (isTablet) {
- var currentNavigationItem by remember { mutableStateOf(TabletNavigationItem.HOME) }
+ if (isTablet) {
+ var currentNavigationItem by remember { mutableStateOf(TabletNavigationItem.HOME) }
- TabletView(
- parcels = parcels,
- selectedParcel = selectedParcel,
- apiParcel = apiParcel,
- isLoading = isLoading,
- currentNavigationItem = currentNavigationItem,
- onNavigateToItem = { currentNavigationItem = it },
- onNavigateToParcel = onNavigateToParcel,
- onNavigateToAddParcel = onNavigateToAddParcel,
- onNavigateToSettings = onNavigateToSettings,
- onEditParcel = onEditParcel,
- onDeleteParcel = onDeleteParcel,
- onArchiveParcel = onArchiveParcel,
- onArchivePromptDismissal = onArchivePromptDismissal,
- settingsContent = settingsContent,
- addParcelContent = addParcelContent
- )
- } else {
- homeContent()
- }
+ TabletView(
+ parcels = parcels,
+ selectedParcel = selectedParcel,
+ apiParcel = apiParcel,
+ isLoading = isLoading,
+ currentNavigationItem = currentNavigationItem,
+ onNavigateToItem = { currentNavigationItem = it },
+ onNavigateToParcel = onNavigateToParcel,
+ onNavigateToAddParcel = onNavigateToAddParcel,
+ onNavigateToSettings = onNavigateToSettings,
+ onEditParcel = onEditParcel,
+ onDeleteParcel = onDeleteParcel,
+ onArchiveParcel = onArchiveParcel,
+ onArchivePromptDismissal = onArchivePromptDismissal,
+ settingsContent = settingsContent,
+ addParcelContent = addParcelContent,
+ )
+ } else {
+ homeContent()
+ }
}
diff --git a/app/src/main/java/dev/itsvic/parceltracker/ui/views/AddEditParcelView.kt b/app/src/main/java/dev/itsvic/parceltracker/ui/views/AddEditParcelView.kt
index 9a27a4b..3abdfed 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/ui/views/AddEditParcelView.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/ui/views/AddEditParcelView.kt
@@ -5,15 +5,14 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
-import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.sizeIn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.ArrowBack
-import androidx.compose.material.icons.filled.Add
import androidx.compose.material3.Button
import androidx.compose.material3.Checkbox
import androidx.compose.material3.DropdownMenuItem
@@ -48,29 +47,25 @@ import androidx.compose.ui.unit.sp
import dev.itsvic.parceltracker.CLIPBOARD_PASTE_ENABLED
import dev.itsvic.parceltracker.PREFERRED_REGION
import dev.itsvic.parceltracker.R
-import dev.itsvic.parceltracker.dataStore
-import kotlinx.coroutines.flow.map
import dev.itsvic.parceltracker.api.Service
import dev.itsvic.parceltracker.api.getDeliveryService
import dev.itsvic.parceltracker.api.getDeliveryServiceName
import dev.itsvic.parceltracker.api.serviceOptions
+import dev.itsvic.parceltracker.dataStore
import dev.itsvic.parceltracker.db.Parcel
import dev.itsvic.parceltracker.ui.theme.ParcelTrackerTheme
+import kotlinx.coroutines.flow.map
@OptIn(ExperimentalMaterial3Api::class)
@Composable
-fun AddEditParcelView(
- parcel: Parcel?,
- onBackPressed: () -> Unit,
- onCompleted: (Parcel) -> Unit,
-) {
+fun AddEditParcelView(parcel: Parcel?, onBackPressed: () -> Unit, onCompleted: (Parcel) -> Unit) {
val isEdit = parcel != null
val context = LocalContext.current
val clipboardManager = LocalClipboardManager.current
val clipboardPasteEnabled by
- context.dataStore.data.map { it[CLIPBOARD_PASTE_ENABLED] == true }.collectAsState(false)
+ context.dataStore.data.map { it[CLIPBOARD_PASTE_ENABLED] == true }.collectAsState(false)
val preferredRegion by
- context.dataStore.data.map { it[PREFERRED_REGION] ?: "" }.collectAsState("")
+ context.dataStore.data.map { it[PREFERRED_REGION] ?: "" }.collectAsState("")
var humanName by remember { mutableStateOf(parcel?.humanName ?: "") }
var trackingId by remember { mutableStateOf(parcel?.parcelId ?: "") }
@@ -98,8 +93,10 @@ fun AddEditParcelView(
success = false
serviceError = true
}
- if (((backend?.acceptsPostCode == true && specifyPostalCode) ||
- (backend?.requiresPostCode == true)) && postalCode.isBlank()) {
+ if (
+ ((backend?.acceptsPostCode == true && specifyPostalCode) ||
+ (backend?.requiresPostCode == true)) && postalCode.isBlank()
+ ) {
success = false
postalCodeError = true
}
@@ -111,17 +108,82 @@ fun AddEditParcelView(
var expanded by remember { mutableStateOf(false) }
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
- val sortedServiceOptions = serviceOptions.sortedWith(compareBy {
- val isPreferredRegion = when (preferredRegion) {
- "international" ->
- it in
- listOf(Service.CAINIAO, Service.DHL, Service.GLS, Service.UPS, Service.FPX)
- "north_america" -> it == Service.UNIUNI
- "europe" ->
- it in
- listOf(
+ val sortedServiceOptions =
+ serviceOptions.sortedWith(
+ compareBy {
+ val isPreferredRegion =
+ when (preferredRegion) {
+ "international" ->
+ it in listOf(Service.CAINIAO, Service.DHL, Service.GLS, Service.UPS, Service.FPX)
+ "north_america" -> it == Service.UNIUNI
+ "europe" ->
+ it in
+ listOf(
+ Service.BELPOST,
+ Service.SAMEDAY_BG,
+ Service.DPD_UK,
+ Service.EVRI,
+ Service.AN_POST,
+ Service.ALLEGRO_ONEBOX,
+ Service.INPOST,
+ Service.ORLEN_PACZKA,
+ Service.POLISH_POST,
+ Service.GLS_HUNGARY,
+ Service.MAGYAR_POSTA,
+ Service.SAMEDAY_HU,
+ Service.DPD_GER,
+ Service.HERMES,
+ Service.POSTE_ITALIANE,
+ Service.SAMEDAY_RO,
+ Service.POSTNORD,
+ Service.NOVA_POSHTA,
+ Service.UKRPOSHTA,
+ Service.PACKETA,
+ Service.EXPRESS_ONE,
+ )
+ "asia" -> it in listOf(Service.EKART, Service.SPX_TH)
+ "belarus" -> it == Service.BELPOST
+ "bulgaria" -> it == Service.SAMEDAY_BG
+ "uk" -> it in listOf(Service.DPD_UK, Service.EVRI)
+ "ireland" -> it == Service.AN_POST
+ "poland" ->
+ it in
+ listOf(
+ Service.ALLEGRO_ONEBOX,
+ Service.INPOST,
+ Service.ORLEN_PACZKA,
+ Service.POLISH_POST,
+ )
+ "hungary" ->
+ it in
+ listOf(
+ Service.GLS_HUNGARY,
+ Service.MAGYAR_POSTA,
+ Service.SAMEDAY_HU,
+ Service.EXPRESS_ONE,
+ )
+ "germany" -> it in listOf(Service.DPD_GER, Service.HERMES)
+ "italy" -> it == Service.POSTE_ITALIANE
+ "romania" -> it == Service.SAMEDAY_RO
+ "scandinavia" -> it == Service.POSTNORD
+ "ukraine" -> it in listOf(Service.NOVA_POSHTA, Service.UKRPOSHTA)
+ "india" -> it == Service.EKART
+ "thailand" -> it == Service.SPX_TH
+ else -> false
+ }
+ if (isPreferredRegion) 0 else 1
+ }
+ .thenBy {
+ when (it) {
+ Service.CAINIAO,
+ Service.DHL,
+ Service.GLS,
+ Service.UPS,
+ Service.FPX -> 0
+ Service.UNIUNI -> 1
Service.BELPOST,
Service.SAMEDAY_BG,
+ Service.PACKETA,
Service.DPD_UK,
Service.EVRI,
Service.AN_POST,
@@ -132,323 +194,278 @@ fun AddEditParcelView(
Service.GLS_HUNGARY,
Service.MAGYAR_POSTA,
Service.SAMEDAY_HU,
+ Service.EXPRESS_ONE,
Service.DPD_GER,
Service.HERMES,
Service.POSTE_ITALIANE,
Service.SAMEDAY_RO,
Service.POSTNORD,
Service.NOVA_POSHTA,
- Service.UKRPOSHTA,
- Service.PACKETA,
- Service.EXPRESS_ONE)
- "asia" -> it in listOf(Service.EKART, Service.SPX_TH)
- "belarus" -> it == Service.BELPOST
- "bulgaria" -> it == Service.SAMEDAY_BG
- "uk" -> it in listOf(Service.DPD_UK, Service.EVRI)
- "ireland" -> it == Service.AN_POST
- "poland" ->
- it in
- listOf(
+ Service.UKRPOSHTA -> 2
+ Service.EKART,
+ Service.SPX_TH -> 3
+ else -> 4
+ }
+ }
+ .thenBy {
+ when (it) {
+ Service.BELPOST -> "A_Belarus"
+ Service.SAMEDAY_BG -> "B_Bulgaria"
+ Service.PACKETA -> "C_Europe"
+ Service.DPD_UK,
+ Service.EVRI -> "D_UK"
+ Service.AN_POST -> "E_Ireland"
Service.ALLEGRO_ONEBOX,
Service.INPOST,
Service.ORLEN_PACZKA,
- Service.POLISH_POST)
- "hungary" ->
- it in
- listOf(
+ Service.POLISH_POST -> "F_Poland"
Service.GLS_HUNGARY,
Service.MAGYAR_POSTA,
Service.SAMEDAY_HU,
- Service.EXPRESS_ONE)
- "germany" -> it in listOf(Service.DPD_GER, Service.HERMES)
- "italy" -> it == Service.POSTE_ITALIANE
- "romania" -> it == Service.SAMEDAY_RO
- "scandinavia" -> it == Service.POSTNORD
- "ukraine" -> it in listOf(Service.NOVA_POSHTA, Service.UKRPOSHTA)
- "india" -> it == Service.EKART
- "thailand" -> it == Service.SPX_TH
- else -> false
- }
- if (isPreferredRegion) 0 else 1
- }.thenBy {
- when (it) {
- Service.CAINIAO, Service.DHL, Service.GLS, Service.UPS, Service.FPX -> 0
- Service.UNIUNI -> 1
- Service.BELPOST,
- Service.SAMEDAY_BG,
- Service.PACKETA,
- Service.DPD_UK,
- Service.EVRI,
- Service.AN_POST,
- Service.ALLEGRO_ONEBOX,
- Service.INPOST,
- Service.ORLEN_PACZKA,
- Service.POLISH_POST,
- Service.GLS_HUNGARY,
- Service.MAGYAR_POSTA,
- Service.SAMEDAY_HU,
- Service.EXPRESS_ONE,
- Service.DPD_GER,
- Service.HERMES,
- Service.POSTE_ITALIANE,
- Service.SAMEDAY_RO,
- Service.POSTNORD,
- Service.NOVA_POSHTA,
- Service.UKRPOSHTA -> 2
- Service.EKART, Service.SPX_TH -> 3
- else -> 4
- }
- }.thenBy {
- when (it) {
- Service.BELPOST -> "A_Belarus"
- Service.SAMEDAY_BG -> "B_Bulgaria"
- Service.PACKETA -> "C_Europe"
- Service.DPD_UK, Service.EVRI -> "D_UK"
- Service.AN_POST -> "E_Ireland"
- Service.ALLEGRO_ONEBOX,
- Service.INPOST,
- Service.ORLEN_PACZKA,
- Service.POLISH_POST -> "F_Poland"
- Service.GLS_HUNGARY,
- Service.MAGYAR_POSTA,
- Service.SAMEDAY_HU,
- Service.EXPRESS_ONE -> "G_Hungary"
- Service.DPD_GER, Service.HERMES -> "H_Germany"
- Service.POSTE_ITALIANE -> "I_Italy"
- Service.SAMEDAY_RO -> "J_Romania"
- Service.POSTNORD -> "K_Scandinavia"
- Service.NOVA_POSHTA, Service.UKRPOSHTA -> "L_Ukraine"
- else -> it.name
- }
- }.thenBy {
- if (trackingId.isNotBlank()) {
- val backend = getDeliveryService(it)
- if (backend?.acceptsFormat(trackingId) == true) 0 else 1
- } else {
- 0
- }
- })
+ Service.EXPRESS_ONE -> "G_Hungary"
+ Service.DPD_GER,
+ Service.HERMES -> "H_Germany"
+ Service.POSTE_ITALIANE -> "I_Italy"
+ Service.SAMEDAY_RO -> "J_Romania"
+ Service.POSTNORD -> "K_Scandinavia"
+ Service.NOVA_POSHTA,
+ Service.UKRPOSHTA -> "L_Ukraine"
+ else -> it.name
+ }
+ }
+ .thenBy {
+ if (trackingId.isNotBlank()) {
+ val backend = getDeliveryService(it)
+ if (backend?.acceptsFormat(trackingId) == true) 0 else 1
+ } else {
+ 0
+ }
+ }
+ )
Scaffold(
- topBar = {
- TopAppBar(
- title = {
- Text(stringResource(if (isEdit) R.string.edit_parcel else R.string.add_a_parcel))
- },
- navigationIcon = {
- IconButton(onClick = onBackPressed) {
- Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.go_back))
- }
- },
- scrollBehavior = scrollBehavior,
+ topBar = {
+ TopAppBar(
+ title = {
+ Text(stringResource(if (isEdit) R.string.edit_parcel else R.string.add_a_parcel))
+ },
+ navigationIcon = {
+ IconButton(onClick = onBackPressed) {
+ Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.go_back))
+ }
+ },
+ scrollBehavior = scrollBehavior,
+ )
+ },
+ modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
+ ) { innerPadding ->
+ Column(
+ modifier =
+ Modifier.padding(innerPadding).fillMaxWidth().verticalScroll(rememberScrollState()),
+ horizontalAlignment = Alignment.CenterHorizontally,
+ ) {
+ Column(
+ modifier = Modifier.padding(horizontal = 16.dp).sizeIn(maxWidth = 488.dp).fillMaxWidth(),
+ verticalArrangement = Arrangement.spacedBy(8.dp),
+ ) {
+ OutlinedTextField(
+ value = humanName,
+ onValueChange = { humanName = it },
+ singleLine = true,
+ label = { Text(stringResource(R.string.parcel_name)) },
+ modifier = Modifier.fillMaxWidth(),
)
- },
- modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) { innerPadding ->
- Column(
- modifier =
- Modifier.padding(innerPadding).fillMaxWidth().verticalScroll(rememberScrollState()),
- horizontalAlignment = Alignment.CenterHorizontally) {
- Column(
- modifier =
- Modifier.padding(horizontal = 16.dp).sizeIn(maxWidth = 488.dp).fillMaxWidth(),
- verticalArrangement = Arrangement.spacedBy(8.dp),
+
+ OutlinedTextField(
+ value = trackingId,
+ onValueChange = {
+ trackingId = it
+ idError = false
+ },
+ singleLine = true,
+ label = { Text(stringResource(R.string.tracking_id)) },
+ modifier = Modifier.fillMaxWidth(),
+ isError = idError,
+ trailingIcon = {
+ if (clipboardPasteEnabled) {
+ IconButton(
+ onClick = {
+ clipboardManager.getText()?.text?.let { clipboardText ->
+ trackingId = clipboardText
+ idError = false
+ }
+ }
) {
- OutlinedTextField(
- value = humanName,
- onValueChange = {
- humanName = it
- },
- singleLine = true,
- label = { Text(stringResource(R.string.parcel_name)) },
- modifier = Modifier.fillMaxWidth(),
+ Icon(
+ painter = painterResource(id = R.drawable.ic_contentpaste),
+ contentDescription = stringResource(R.string.clipboard_paste),
+ modifier = Modifier.size(20.dp),
+ )
+ }
+ }
+ },
+ supportingText = { if (idError) Text(stringResource(R.string.tracking_id_error_text)) },
+ )
-)
+ // Service dropdown
+ ExposedDropdownMenuBox(expanded = expanded, onExpandedChange = { expanded = it }) {
+ OutlinedTextField(
+ value =
+ if (service == Service.UNDEFINED) ""
+ else stringResource(getDeliveryServiceName(service)!!),
+ onValueChange = {},
+ modifier =
+ Modifier.menuAnchor(ExposedDropdownMenuAnchorType.PrimaryNotEditable).fillMaxWidth(),
+ readOnly = true,
+ label = { Text(stringResource(R.string.delivery_service)) },
+ trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded) },
+ colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
+ isError = serviceError,
+ supportingText = { if (serviceError) Text(stringResource(R.string.service_error_text)) },
+ )
- OutlinedTextField(
- value = trackingId,
- onValueChange = {
- trackingId = it
- idError = false
- },
- singleLine = true,
- label = { Text(stringResource(R.string.tracking_id)) },
- modifier = Modifier.fillMaxWidth(),
- isError = idError,
- trailingIcon = {
- if (clipboardPasteEnabled) {
- IconButton(
- onClick = {
- clipboardManager.getText()?.text?.let { clipboardText ->
- trackingId = clipboardText
- idError = false
- }
- }
- ) {
- Icon(
- painter = painterResource(id = R.drawable.ic_contentpaste),
- contentDescription = stringResource(R.string.clipboard_paste),
- modifier = Modifier.size(20.dp)
- )
- }
- }
- },
- supportingText = {
- if (idError) Text(stringResource(R.string.tracking_id_error_text))
- })
+ ExposedDropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) {
+ var currentCategory = ""
+ sortedServiceOptions.forEach { option ->
+ val category =
+ when (option) {
+ Service.CAINIAO,
+ Service.DHL,
+ Service.GLS,
+ Service.UPS,
+ Service.FPX -> "Nemzetközi"
+ Service.UNIUNI -> "Észak-Amerika"
+ Service.BELPOST -> "Európa - Fehéroroszország"
+ Service.SAMEDAY_BG -> "Európa - Bulgária"
+ Service.PACKETA -> "Európa - Csehország"
+ Service.DPD_UK,
+ Service.EVRI -> "Európa - Egyesült Királyság"
+ Service.AN_POST -> "Európa - Írország"
+ Service.ALLEGRO_ONEBOX,
+ Service.INPOST,
+ Service.ORLEN_PACZKA,
+ Service.POLISH_POST -> "Európa - Lengyelország"
+ Service.GLS_HUNGARY,
+ Service.MAGYAR_POSTA,
+ Service.SAMEDAY_HU -> "Európa - Magyarország"
+ Service.DPD_GER,
+ Service.HERMES -> "Európa - Németország"
+ Service.POSTE_ITALIANE -> "Európa - Olaszország"
+ Service.SAMEDAY_RO -> "Európa - Románia"
+ Service.POSTNORD -> "Európa - Skandinávia"
+ Service.NOVA_POSHTA,
+ Service.UKRPOSHTA -> "Európa - Ukrajna"
+ Service.EKART -> "Ázsia - India"
+ Service.SPX_TH -> "Ázsia - Thaiföld"
+ else -> "Egyéb"
+ }
- // Service dropdown
- ExposedDropdownMenuBox(
- expanded = expanded,
- onExpandedChange = { expanded = it },
- ) {
- OutlinedTextField(
- value =
- if (service == Service.UNDEFINED) ""
- else stringResource(getDeliveryServiceName(service)!!),
- onValueChange = {},
- modifier =
- Modifier.menuAnchor(ExposedDropdownMenuAnchorType.PrimaryNotEditable)
- .fillMaxWidth(),
- readOnly = true,
- label = { Text(stringResource(R.string.delivery_service)) },
- trailingIcon = { ExposedDropdownMenuDefaults.TrailingIcon(expanded) },
- colors = ExposedDropdownMenuDefaults.outlinedTextFieldColors(),
- isError = serviceError,
- supportingText = {
- if (serviceError) Text(stringResource(R.string.service_error_text))
- })
+ if (category != currentCategory) {
+ currentCategory = category
+ DropdownMenuItem(
+ text = {
+ Text(
+ text = category,
+ style = MaterialTheme.typography.labelMedium,
+ color = MaterialTheme.colorScheme.primary,
+ )
+ },
+ onClick = {},
+ enabled = false,
+ contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
+ )
+ }
- ExposedDropdownMenu(
- expanded = expanded, onDismissRequest = { expanded = false }) {
- var currentCategory = ""
- sortedServiceOptions.forEach { option ->
- val category = when (option) {
- Service.CAINIAO, Service.DHL, Service.GLS, Service.UPS, Service.FPX -> "Nemzetközi"
- Service.UNIUNI -> "Észak-Amerika"
- Service.BELPOST -> "Európa - Fehéroroszország"
- Service.SAMEDAY_BG -> "Európa - Bulgária"
- Service.PACKETA -> "Európa - Csehország"
- Service.DPD_UK, Service.EVRI -> "Európa - Egyesült Királyság"
- Service.AN_POST -> "Európa - Írország"
- Service.ALLEGRO_ONEBOX, Service.INPOST, Service.ORLEN_PACZKA, Service.POLISH_POST -> "Európa - Lengyelország"
- Service.GLS_HUNGARY, Service.MAGYAR_POSTA, Service.SAMEDAY_HU -> "Európa - Magyarország"
- Service.DPD_GER, Service.HERMES -> "Európa - Németország"
- Service.POSTE_ITALIANE -> "Európa - Olaszország"
- Service.SAMEDAY_RO -> "Európa - Románia"
- Service.POSTNORD -> "Európa - Skandinávia"
- Service.NOVA_POSHTA, Service.UKRPOSHTA -> "Európa - Ukrajna"
- Service.EKART -> "Ázsia - India"
- Service.SPX_TH -> "Ázsia - Thaiföld"
- else -> "Egyéb"
- }
-
- if (category != currentCategory) {
- currentCategory = category
- DropdownMenuItem(
- text = {
- Text(
- text = category,
- style = MaterialTheme.typography.labelMedium,
- color = MaterialTheme.colorScheme.primary
- )
- },
- onClick = { },
- enabled = false,
- contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
- )
- }
-
- DropdownMenuItem(
- text = { Text(" " + stringResource(getDeliveryServiceName(option)!!)) },
- onClick = {
- service = option
- expanded = false
- serviceError = false
- },
- contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
- )
- }
- }
- }
+ DropdownMenuItem(
+ text = { Text(" " + stringResource(getDeliveryServiceName(option)!!)) },
+ onClick = {
+ service = option
+ expanded = false
+ serviceError = false
+ },
+ contentPadding = ExposedDropdownMenuDefaults.ItemContentPadding,
+ )
+ }
+ }
+ }
- AnimatedVisibility(backend?.acceptsPostCode == true && !backend.requiresPostCode) {
- Row(
- verticalAlignment = Alignment.CenterVertically,
- horizontalArrangement = Arrangement.SpaceBetween,
- modifier = Modifier.fillMaxWidth()) {
- Column(modifier = Modifier.fillMaxWidth(0.8f)) {
- Text(stringResource(R.string.specify_a_postal_code))
- Text(
- stringResource(R.string.specify_postal_code_flavor_text),
- fontSize = 14.sp,
- lineHeight = 21.sp,
- color = MaterialTheme.colorScheme.onSurfaceVariant)
- }
- Checkbox(
- checked = specifyPostalCode,
- onCheckedChange = { specifyPostalCode = it },
- )
- }
- }
+ AnimatedVisibility(backend?.acceptsPostCode == true && !backend.requiresPostCode) {
+ Row(
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.SpaceBetween,
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ Column(modifier = Modifier.fillMaxWidth(0.8f)) {
+ Text(stringResource(R.string.specify_a_postal_code))
+ Text(
+ stringResource(R.string.specify_postal_code_flavor_text),
+ fontSize = 14.sp,
+ lineHeight = 21.sp,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+ }
+ Checkbox(checked = specifyPostalCode, onCheckedChange = { specifyPostalCode = it })
+ }
+ }
- AnimatedVisibility(
- backend?.requiresPostCode == true ||
- (backend?.requiresPostCode == false &&
- backend.acceptsPostCode &&
- specifyPostalCode)) {
- OutlinedTextField(
- value = postalCode,
- onValueChange = {
- postalCode = it
- postalCodeError = false
- },
- singleLine = true,
- label = { Text(stringResource(R.string.postal_code)) },
- modifier = Modifier.fillMaxWidth(),
- isError = postalCodeError,
- supportingText = {
- if (postalCodeError)
- Text(stringResource(R.string.postal_code_error_text))
- })
- }
+ AnimatedVisibility(
+ backend?.requiresPostCode == true ||
+ (backend?.requiresPostCode == false && backend.acceptsPostCode && specifyPostalCode)
+ ) {
+ OutlinedTextField(
+ value = postalCode,
+ onValueChange = {
+ postalCode = it
+ postalCodeError = false
+ },
+ singleLine = true,
+ label = { Text(stringResource(R.string.postal_code)) },
+ modifier = Modifier.fillMaxWidth(),
+ isError = postalCodeError,
+ supportingText = {
+ if (postalCodeError) Text(stringResource(R.string.postal_code_error_text))
+ },
+ )
+ }
- Row(horizontalArrangement = Arrangement.End, modifier = Modifier.fillMaxWidth()) {
- Button(
- onClick = {
- val isOk = validateInputs()
- if (isOk) {
- // data valid, pass it along
- onCompleted(
- Parcel(
- id = parcel?.id ?: 0,
- humanName = if (humanName.isBlank()) context.getString(R.string.undefinied_packagename) else humanName,
- parcelId = trackingId,
- service = service,
- postalCode =
- if (backend?.requiresPostCode == true ||
- (backend?.acceptsPostCode == true && specifyPostalCode))
- postalCode
- else null))
- }
- }) {
- Text(stringResource(if (isEdit) R.string.save else R.string.add_parcel))
- }
- }
+ Row(horizontalArrangement = Arrangement.End, modifier = Modifier.fillMaxWidth()) {
+ Button(
+ onClick = {
+ val isOk = validateInputs()
+ if (isOk) {
+ // data valid, pass it along
+ onCompleted(
+ Parcel(
+ id = parcel?.id ?: 0,
+ humanName =
+ if (humanName.isBlank()) context.getString(R.string.undefinied_packagename)
+ else humanName,
+ parcelId = trackingId,
+ service = service,
+ postalCode =
+ if (
+ backend?.requiresPostCode == true ||
+ (backend?.acceptsPostCode == true && specifyPostalCode)
+ )
+ postalCode
+ else null,
+ )
+ )
}
}
+ ) {
+ Text(stringResource(if (isEdit) R.string.save else R.string.add_parcel))
+ }
+ }
}
+ }
+ }
}
@Composable
@PreviewLightDark
fun AddParcelPreview() {
- ParcelTrackerTheme {
- AddEditParcelView(
- null,
- onBackPressed = {},
- onCompleted = {},
- )
- }
+ ParcelTrackerTheme { AddEditParcelView(null, onBackPressed = {}, onCompleted = {}) }
}
@Composable
@@ -456,9 +473,9 @@ fun AddParcelPreview() {
fun EditParcelPreview() {
ParcelTrackerTheme {
AddEditParcelView(
- Parcel(0, "Test", "Test", null, Service.EXAMPLE),
- onBackPressed = {},
- onCompleted = {},
+ Parcel(0, "Test", "Test", null, Service.EXAMPLE),
+ onBackPressed = {},
+ onCompleted = {},
)
}
}
diff --git a/app/src/main/java/dev/itsvic/parceltracker/ui/views/HomeView.kt b/app/src/main/java/dev/itsvic/parceltracker/ui/views/HomeView.kt
index d58a209..92a5a6b 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/ui/views/HomeView.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/ui/views/HomeView.kt
@@ -42,13 +42,15 @@ fun HomeView(
scrollBehavior = scrollBehavior,
)
},
- modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) { innerPadding ->
+ modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
+ ) { innerPadding ->
LazyColumn(modifier = Modifier.padding(innerPadding)) {
if (parcels.isEmpty())
item {
Text(
stringResource(R.string.no_parcels_flavor),
- modifier = Modifier.padding(horizontal = 16.dp))
+ modifier = Modifier.padding(horizontal = 16.dp),
+ )
}
items(parcels.reversed()) { parcel ->
@@ -63,14 +65,16 @@ fun HomeView(
fun HomeViewPreview() {
ParcelTrackerTheme {
HomeView(
- parcels =
- listOf(
- ParcelWithStatus(
- Parcel(0, "My precious package", "EXMPL0001", null, Service.EXAMPLE),
- ParcelStatus(0, Status.InTransit, Instant.now()))),
- onNavigateToAddParcel = {},
- onNavigateToParcel = {},
- onNavigateToSettings = {},
+ parcels =
+ listOf(
+ ParcelWithStatus(
+ Parcel(0, "My precious package", "EXMPL0001", null, Service.EXAMPLE),
+ ParcelStatus(0, Status.InTransit, Instant.now()),
+ )
+ ),
+ onNavigateToAddParcel = {},
+ onNavigateToParcel = {},
+ onNavigateToSettings = {},
)
}
}
diff --git a/app/src/main/java/dev/itsvic/parceltracker/ui/views/ParcelView.kt b/app/src/main/java/dev/itsvic/parceltracker/ui/views/ParcelView.kt
index a004812..58cf3e2 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/ui/views/ParcelView.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/ui/views/ParcelView.kt
@@ -46,163 +46,166 @@ import java.time.LocalDateTime
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun ParcelView(
- parcel: Parcel,
- humanName: String,
- service: Service,
- isArchived: Boolean,
- archivePromptDismissed: Boolean,
- onBackPressed: () -> Unit,
- onEdit: () -> Unit,
- onDelete: () -> Unit,
- onArchive: () -> Unit,
- onArchivePromptDismissal: () -> Unit,
- showBackButton: Boolean = true,
+ parcel: Parcel,
+ humanName: String,
+ service: Service,
+ isArchived: Boolean,
+ archivePromptDismissed: Boolean,
+ onBackPressed: () -> Unit,
+ onEdit: () -> Unit,
+ onDelete: () -> Unit,
+ onArchive: () -> Unit,
+ onArchivePromptDismissal: () -> Unit,
+ showBackButton: Boolean = true,
) {
val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
Scaffold(
- topBar = {
- MediumTopAppBar(
- title = { Text(humanName) },
- navigationIcon = {
- if (showBackButton) {
- IconButton(onClick = onBackPressed) {
- Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.go_back))
- }
- }
- },
- scrollBehavior = scrollBehavior,
- )
- },
- bottomBar = {
- ParcelActionBar(
- status = parcel.currentStatus,
- onEdit = onEdit,
- onArchive = onArchive,
- onDelete = onDelete
- )
- },
- modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection)) { innerPadding ->
- LazyColumn(
- modifier = Modifier.padding(innerPadding).padding(16.dp, 0.dp),
- verticalArrangement = Arrangement.spacedBy(8.dp),
- ) {
- item {
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween) {
- getDeliveryServiceName(service)?.let {
- Text(
- stringResource(it),
- style = MaterialTheme.typography.bodyMedium,
- color = MaterialTheme.colorScheme.onSurfaceVariant)
- }
-
- SelectionContainer {
- Text(
- parcel.id,
- style = MaterialTheme.typography.bodyMedium,
- color = MaterialTheme.colorScheme.onSurfaceVariant)
- }
+ topBar = {
+ MediumTopAppBar(
+ title = { Text(humanName) },
+ navigationIcon = {
+ if (showBackButton) {
+ IconButton(onClick = onBackPressed) {
+ Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.go_back))
}
}
-
- items(parcel.properties.entries.toList()) {
- Row(
- modifier = Modifier.fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween) {
- Text(
- stringResource(it.key),
- style = MaterialTheme.typography.bodyMedium,
- color = MaterialTheme.colorScheme.onSurfaceVariant)
- Text(
- it.value,
- style = MaterialTheme.typography.bodyMedium,
- color = MaterialTheme.colorScheme.onSurfaceVariant,
- textAlign = TextAlign.End)
- }
+ },
+ scrollBehavior = scrollBehavior,
+ )
+ },
+ bottomBar = {
+ ParcelActionBar(
+ status = parcel.currentStatus,
+ onEdit = onEdit,
+ onArchive = onArchive,
+ onDelete = onDelete,
+ )
+ },
+ modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
+ ) { innerPadding ->
+ LazyColumn(
+ modifier = Modifier.padding(innerPadding).padding(16.dp, 0.dp),
+ verticalArrangement = Arrangement.spacedBy(8.dp),
+ ) {
+ item {
+ Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
+ getDeliveryServiceName(service)?.let {
+ Text(
+ stringResource(it),
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
}
- item {
+ SelectionContainer {
Text(
- LocalContext.current.getString(parcel.currentStatus.nameResource),
- style = MaterialTheme.typography.headlineLarge,
- modifier = Modifier.padding(vertical = 16.dp),
+ parcel.id,
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
)
}
+ }
+ }
+
+ items(parcel.properties.entries.toList()) {
+ Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) {
+ Text(
+ stringResource(it.key),
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+ Text(
+ it.value,
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ textAlign = TextAlign.End,
+ )
+ }
+ }
+
+ item {
+ Text(
+ LocalContext.current.getString(parcel.currentStatus.nameResource),
+ style = MaterialTheme.typography.headlineLarge,
+ modifier = Modifier.padding(vertical = 16.dp),
+ )
+ }
- if (!isArchived &&
- !archivePromptDismissed &&
- (parcel.currentStatus == Status.Delivered || parcel.currentStatus == Status.PickedUp))
- item {
- Card(
- shape = RoundedCornerShape(16.dp),
- modifier = Modifier.padding(bottom = 16.dp)) {
- Column(
- Modifier.padding(24.dp),
- verticalArrangement = Arrangement.spacedBy(8.dp)) {
- Text(
- stringResource(R.string.archive_prompt_question),
- style = MaterialTheme.typography.titleMedium)
- Text(stringResource(R.string.archive_prompt_text))
- Row(
- horizontalArrangement = Arrangement.spacedBy(16.dp),
- modifier = Modifier.fillMaxWidth()) {
- FilledTonalButton(
- onArchivePromptDismissal, modifier = Modifier.weight(1f)) {
- Text(stringResource(R.string.ignore))
- }
- Button(onArchive, modifier = Modifier.weight(1f)) {
- Text(stringResource(R.string.archive))
- }
- }
+ if (
+ !isArchived &&
+ !archivePromptDismissed &&
+ (parcel.currentStatus == Status.Delivered || parcel.currentStatus == Status.PickedUp)
+ )
+ item {
+ Card(shape = RoundedCornerShape(16.dp), modifier = Modifier.padding(bottom = 16.dp)) {
+ Column(Modifier.padding(24.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) {
+ Text(
+ stringResource(R.string.archive_prompt_question),
+ style = MaterialTheme.typography.titleMedium,
+ )
+ Text(stringResource(R.string.archive_prompt_text))
+ Row(
+ horizontalArrangement = Arrangement.spacedBy(16.dp),
+ modifier = Modifier.fillMaxWidth(),
+ ) {
+ FilledTonalButton(onArchivePromptDismissal, modifier = Modifier.weight(1f)) {
+ Text(stringResource(R.string.ignore))
+ }
+ Button(onArchive, modifier = Modifier.weight(1f)) {
+ Text(stringResource(R.string.archive))
}
}
}
-
- items(parcel.history.size) { index ->
- if (index > 0) HorizontalDivider(Modifier.padding(top = 8.dp, bottom = 16.dp))
- ParcelHistoryItemRow(parcel.history[index])
}
}
+
+ items(parcel.history.size) { index ->
+ if (index > 0) HorizontalDivider(Modifier.padding(top = 8.dp, bottom = 16.dp))
+ ParcelHistoryItemRow(parcel.history[index])
}
+ }
+ }
}
@Composable
@PreviewLightDark
private fun ParcelViewPreview() {
val parcel =
- Parcel(
- "EXMPL0001",
- listOf(
- ParcelHistoryItem(
- "The package got lost. Whoops!",
- LocalDateTime.of(2025, 1, 1, 12, 0, 0),
- "Warsaw, Poland"),
- ParcelHistoryItem(
- "Arrived at local warehouse",
- LocalDateTime.of(2025, 1, 1, 10, 0, 0),
- "Warsaw, Poland"),
- ParcelHistoryItem(
- "En route to local warehouse",
- LocalDateTime.of(2024, 12, 1, 12, 0, 0),
- "Netherlands"),
- ParcelHistoryItem(
- "Label created", LocalDateTime.of(2024, 12, 1, 12, 0, 0), "Netherlands"),
- ),
- Status.DeliveryFailure)
+ Parcel(
+ "EXMPL0001",
+ listOf(
+ ParcelHistoryItem(
+ "The package got lost. Whoops!",
+ LocalDateTime.of(2025, 1, 1, 12, 0, 0),
+ "Warsaw, Poland",
+ ),
+ ParcelHistoryItem(
+ "Arrived at local warehouse",
+ LocalDateTime.of(2025, 1, 1, 10, 0, 0),
+ "Warsaw, Poland",
+ ),
+ ParcelHistoryItem(
+ "En route to local warehouse",
+ LocalDateTime.of(2024, 12, 1, 12, 0, 0),
+ "Netherlands",
+ ),
+ ParcelHistoryItem("Label created", LocalDateTime.of(2024, 12, 1, 12, 0, 0), "Netherlands"),
+ ),
+ Status.DeliveryFailure,
+ )
ParcelTrackerTheme {
ParcelView(
- parcel,
- "My precious package",
- Service.EXAMPLE,
- isArchived = false,
- archivePromptDismissed = false,
- onBackPressed = {},
- onEdit = {},
- onDelete = {},
- onArchive = {},
- onArchivePromptDismissal = {},
+ parcel,
+ "My precious package",
+ Service.EXAMPLE,
+ isArchived = false,
+ archivePromptDismissed = false,
+ onBackPressed = {},
+ onEdit = {},
+ onDelete = {},
+ onArchive = {},
+ onArchivePromptDismissal = {},
)
}
}
diff --git a/app/src/main/java/dev/itsvic/parceltracker/ui/views/SettingsView.kt b/app/src/main/java/dev/itsvic/parceltracker/ui/views/SettingsView.kt
index e6c7dea..e07f2a1 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/ui/views/SettingsView.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/ui/views/SettingsView.kt
@@ -71,378 +71,364 @@ import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@Composable
-fun SettingsView(
- onBackPressed: () -> Unit,
-) {
- val context = LocalContext.current
- val demoMode by context.dataStore.data.map { it[DEMO_MODE] == true }.collectAsState(false)
- val unmeteredOnly by
- context.dataStore.data.map { it[UNMETERED_ONLY] == true }.collectAsState(false)
- val clipboardPasteEnabled by
- context.dataStore.data.map { it[CLIPBOARD_PASTE_ENABLED] == true }.collectAsState(false)
- val preferredRegion by
- context.dataStore.data.map { it[PREFERRED_REGION] ?: "" }.collectAsState("")
- val coroutineScope = rememberCoroutineScope()
- var regionDropdownExpanded by remember { mutableStateOf(false) }
- val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
- var aboutDialogOpen by remember { mutableStateOf(false) }
+fun SettingsView(onBackPressed: () -> Unit) {
+ val context = LocalContext.current
+ val demoMode by context.dataStore.data.map { it[DEMO_MODE] == true }.collectAsState(false)
+ val unmeteredOnly by
+ context.dataStore.data.map { it[UNMETERED_ONLY] == true }.collectAsState(false)
+ val clipboardPasteEnabled by
+ context.dataStore.data.map { it[CLIPBOARD_PASTE_ENABLED] == true }.collectAsState(false)
+ val preferredRegion by
+ context.dataStore.data.map { it[PREFERRED_REGION] ?: "" }.collectAsState("")
+ val coroutineScope = rememberCoroutineScope()
+ var regionDropdownExpanded by remember { mutableStateOf(false) }
+ val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
+ var aboutDialogOpen by remember { mutableStateOf(false) }
- val dhlApiKey by context.dataStore.data.map { it[DHL_API_KEY] ?: "" }.collectAsState("")
+ val dhlApiKey by context.dataStore.data.map { it[DHL_API_KEY] ?: "" }.collectAsState("")
- fun setValue(key: Preferences.Key, value: T) {
- coroutineScope.launch { context.dataStore.edit { it[key] = value } }
- }
+ fun setValue(key: Preferences.Key, value: T) {
+ coroutineScope.launch { context.dataStore.edit { it[key] = value } }
+ }
- val setUnmeteredOnly: (Boolean) -> Unit = { value ->
- coroutineScope.launch {
- context.dataStore.edit { it[UNMETERED_ONLY] = value }
- context.enqueueNotificationWorker()
- }
+ val setUnmeteredOnly: (Boolean) -> Unit = { value ->
+ coroutineScope.launch {
+ context.dataStore.edit { it[UNMETERED_ONLY] = value }
+ context.enqueueNotificationWorker()
}
+ }
- Scaffold(
- topBar = {
- LargeTopAppBar(
- title = { Text(stringResource(R.string.settings)) },
- navigationIcon = {
- IconButton(onClick = onBackPressed) {
- Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.go_back))
- }
- },
- scrollBehavior = scrollBehavior,
- )
+ Scaffold(
+ topBar = {
+ LargeTopAppBar(
+ title = { Text(stringResource(R.string.settings)) },
+ navigationIcon = {
+ IconButton(onClick = onBackPressed) {
+ Icon(Icons.AutoMirrored.Filled.ArrowBack, stringResource(R.string.go_back))
+ }
},
- modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
- ) { innerPadding ->
- Column(Modifier.padding(innerPadding).verticalScroll(rememberScrollState())) {
- Row(
- modifier =
- Modifier.clickable { setUnmeteredOnly(unmeteredOnly.not()) }
- .padding(16.dp, 12.dp)
- .fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween,
- verticalAlignment = Alignment.CenterVertically,
- ) {
- Column(modifier = Modifier.fillMaxWidth(0.8f)) {
- Text(stringResource(R.string.unmetered_only_setting))
- Text(
- stringResource(R.string.unmetered_only_setting_detail),
- style = MaterialTheme.typography.bodyMedium
- )
- }
- Switch(checked = unmeteredOnly, onCheckedChange = { setUnmeteredOnly(it) })
- }
-
- Row(
- modifier =
- Modifier.clickable {
- setValue(CLIPBOARD_PASTE_ENABLED, clipboardPasteEnabled.not())
- }
- .padding(16.dp, 12.dp)
- .fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween,
- verticalAlignment = Alignment.CenterVertically,
- ) {
- Column(modifier = Modifier.fillMaxWidth(0.8f)) {
- Text(stringResource(R.string.clipboard_paste_enabled))
- Text(
- stringResource(R.string.clipboard_paste_description),
- style = MaterialTheme.typography.bodyMedium
- )
- }
- Switch(
- checked = clipboardPasteEnabled,
- onCheckedChange = { setValue(CLIPBOARD_PASTE_ENABLED, it) }
- )
- }
+ scrollBehavior = scrollBehavior,
+ )
+ },
+ modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
+ ) { innerPadding ->
+ Column(Modifier.padding(innerPadding).verticalScroll(rememberScrollState())) {
+ Row(
+ modifier =
+ Modifier.clickable { setUnmeteredOnly(unmeteredOnly.not()) }
+ .padding(16.dp, 12.dp)
+ .fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Column(modifier = Modifier.fillMaxWidth(0.8f)) {
+ Text(stringResource(R.string.unmetered_only_setting))
+ Text(
+ stringResource(R.string.unmetered_only_setting_detail),
+ style = MaterialTheme.typography.bodyMedium,
+ )
+ }
+ Switch(checked = unmeteredOnly, onCheckedChange = { setUnmeteredOnly(it) })
+ }
- Column(modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth()) {
- Text(stringResource(R.string.preferred_region))
- Text(
- stringResource(R.string.preferred_region_description),
- style = MaterialTheme.typography.bodyMedium,
- modifier = Modifier.padding(bottom = 8.dp)
- )
+ Row(
+ modifier =
+ Modifier.clickable { setValue(CLIPBOARD_PASTE_ENABLED, clipboardPasteEnabled.not()) }
+ .padding(16.dp, 12.dp)
+ .fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Column(modifier = Modifier.fillMaxWidth(0.8f)) {
+ Text(stringResource(R.string.clipboard_paste_enabled))
+ Text(
+ stringResource(R.string.clipboard_paste_description),
+ style = MaterialTheme.typography.bodyMedium,
+ )
+ }
+ Switch(
+ checked = clipboardPasteEnabled,
+ onCheckedChange = { setValue(CLIPBOARD_PASTE_ENABLED, it) },
+ )
+ }
- ExposedDropdownMenuBox(
- expanded = regionDropdownExpanded,
- onExpandedChange = { regionDropdownExpanded = !regionDropdownExpanded }
- ) {
- OutlinedTextField(
- value =
- when (preferredRegion) {
- "international" -> stringResource(R.string.region_international)
- "north_america" -> stringResource(R.string.region_north_america)
- "europe" -> stringResource(R.string.region_europe)
- "asia" -> stringResource(R.string.region_asia)
- "belarus" -> stringResource(R.string.country_belarus)
- "bulgaria" -> stringResource(R.string.country_bulgaria)
- "czech" -> stringResource(R.string.country_czech)
- "uk" -> stringResource(R.string.country_uk)
- "ireland" -> stringResource(R.string.country_ireland)
- "poland" -> stringResource(R.string.country_poland)
- "hungary" -> stringResource(R.string.country_hungary)
- "germany" -> stringResource(R.string.country_germany)
- "italy" -> stringResource(R.string.country_italy)
- "romania" -> stringResource(R.string.country_romania)
- "scandinavia" -> stringResource(R.string.country_scandinavia)
- "ukraine" -> stringResource(R.string.country_ukraine)
- "india" -> stringResource(R.string.country_india)
- "thailand" -> stringResource(R.string.country_thailand)
- else -> stringResource(R.string.region_international)
- },
- onValueChange = {},
- readOnly = true,
- trailingIcon = {
- ExposedDropdownMenuDefaults.TrailingIcon(
- expanded = regionDropdownExpanded
- )
- },
- modifier = Modifier.menuAnchor().fillMaxWidth()
- )
+ Column(modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth()) {
+ Text(stringResource(R.string.preferred_region))
+ Text(
+ stringResource(R.string.preferred_region_description),
+ style = MaterialTheme.typography.bodyMedium,
+ modifier = Modifier.padding(bottom = 8.dp),
+ )
- ExposedDropdownMenu(
- expanded = regionDropdownExpanded,
- onDismissRequest = { regionDropdownExpanded = false }
- ) {
- DropdownMenuItem(
- text = { Text(stringResource(R.string.region_international)) },
- onClick = {
- setValue(PREFERRED_REGION, "international")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.region_north_america)) },
- onClick = {
- setValue(PREFERRED_REGION, "north_america")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.region_europe)) },
- onClick = {
- setValue(PREFERRED_REGION, "europe")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.region_asia)) },
- onClick = {
- setValue(PREFERRED_REGION, "asia")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_belarus)) },
- onClick = {
- setValue(PREFERRED_REGION, "belarus")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_bulgaria)) },
- onClick = {
- setValue(PREFERRED_REGION, "bulgaria")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_czech)) },
- onClick = {
- setValue(PREFERRED_REGION, "czech")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_uk)) },
- onClick = {
- setValue(PREFERRED_REGION, "uk")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_ireland)) },
- onClick = {
- setValue(PREFERRED_REGION, "ireland")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_poland)) },
- onClick = {
- setValue(PREFERRED_REGION, "poland")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_hungary)) },
- onClick = {
- setValue(PREFERRED_REGION, "hungary")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_germany)) },
- onClick = {
- setValue(PREFERRED_REGION, "germany")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_italy)) },
- onClick = {
- setValue(PREFERRED_REGION, "italy")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_romania)) },
- onClick = {
- setValue(PREFERRED_REGION, "romania")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_scandinavia)) },
- onClick = {
- setValue(PREFERRED_REGION, "scandinavia")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_ukraine)) },
- onClick = {
- setValue(PREFERRED_REGION, "ukraine")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_india)) },
- onClick = {
- setValue(PREFERRED_REGION, "india")
- regionDropdownExpanded = false
- }
- )
- DropdownMenuItem(
- text = { Text(stringResource(R.string.country_thailand)) },
- onClick = {
- setValue(PREFERRED_REGION, "thailand")
- regionDropdownExpanded = false
- }
- )
- }
- }
- }
+ ExposedDropdownMenuBox(
+ expanded = regionDropdownExpanded,
+ onExpandedChange = { regionDropdownExpanded = !regionDropdownExpanded },
+ ) {
+ OutlinedTextField(
+ value =
+ when (preferredRegion) {
+ "international" -> stringResource(R.string.region_international)
+ "north_america" -> stringResource(R.string.region_north_america)
+ "europe" -> stringResource(R.string.region_europe)
+ "asia" -> stringResource(R.string.region_asia)
+ "belarus" -> stringResource(R.string.country_belarus)
+ "bulgaria" -> stringResource(R.string.country_bulgaria)
+ "czech" -> stringResource(R.string.country_czech)
+ "uk" -> stringResource(R.string.country_uk)
+ "ireland" -> stringResource(R.string.country_ireland)
+ "poland" -> stringResource(R.string.country_poland)
+ "hungary" -> stringResource(R.string.country_hungary)
+ "germany" -> stringResource(R.string.country_germany)
+ "italy" -> stringResource(R.string.country_italy)
+ "romania" -> stringResource(R.string.country_romania)
+ "scandinavia" -> stringResource(R.string.country_scandinavia)
+ "ukraine" -> stringResource(R.string.country_ukraine)
+ "india" -> stringResource(R.string.country_india)
+ "thailand" -> stringResource(R.string.country_thailand)
+ else -> stringResource(R.string.region_international)
+ },
+ onValueChange = {},
+ readOnly = true,
+ trailingIcon = {
+ ExposedDropdownMenuDefaults.TrailingIcon(expanded = regionDropdownExpanded)
+ },
+ modifier = Modifier.menuAnchor().fillMaxWidth(),
+ )
- Text(
- stringResource(R.string.settings_api_keys),
- modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 2.dp),
- style = MaterialTheme.typography.bodyMedium,
- color = MaterialTheme.colorScheme.onSurfaceVariant,
+ ExposedDropdownMenu(
+ expanded = regionDropdownExpanded,
+ onDismissRequest = { regionDropdownExpanded = false },
+ ) {
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.region_international)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "international")
+ regionDropdownExpanded = false
+ },
)
-
- OutlinedTextField(
- dhlApiKey,
- { setValue(DHL_API_KEY, it) },
- modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp).fillMaxWidth(),
- label = { Text(stringResource(R.string.service_dhl)) },
- singleLine = true,
- visualTransformation = PasswordVisualTransformation(),
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.region_north_america)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "north_america")
+ regionDropdownExpanded = false
+ },
)
-
- Text(
- AnnotatedString.fromHtml(
- stringResource(R.string.dhl_api_key_flavor_text),
- linkStyles =
- TextLinkStyles(
- style =
- SpanStyle(
- textDecoration = TextDecoration.Underline,
- color = MaterialTheme.colorScheme.primary
- )
- )
- ),
- style = MaterialTheme.typography.bodyMedium,
- modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp)
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.region_europe)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "europe")
+ regionDropdownExpanded = false
+ },
)
-
- Text(
- stringResource(R.string.settings_experimental),
- modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 2.dp),
- style = MaterialTheme.typography.bodyMedium,
- color = MaterialTheme.colorScheme.onSurfaceVariant,
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.region_asia)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "asia")
+ regionDropdownExpanded = false
+ },
)
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_belarus)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "belarus")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_bulgaria)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "bulgaria")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_czech)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "czech")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_uk)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "uk")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_ireland)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "ireland")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_poland)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "poland")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_hungary)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "hungary")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_germany)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "germany")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_italy)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "italy")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_romania)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "romania")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_scandinavia)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "scandinavia")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_ukraine)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "ukraine")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_india)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "india")
+ regionDropdownExpanded = false
+ },
+ )
+ DropdownMenuItem(
+ text = { Text(stringResource(R.string.country_thailand)) },
+ onClick = {
+ setValue(PREFERRED_REGION, "thailand")
+ regionDropdownExpanded = false
+ },
+ )
+ }
+ }
+ }
- Row(
- modifier =
- Modifier.clickable { setValue(DEMO_MODE, demoMode.not()) }
- .padding(16.dp, 12.dp)
- .fillMaxWidth(),
- horizontalArrangement = Arrangement.SpaceBetween,
- verticalAlignment = Alignment.CenterVertically,
- ) {
- Column(modifier = Modifier.fillMaxWidth(0.8f)) {
- Text(stringResource(R.string.demo_mode))
- Text(
- stringResource(R.string.demo_mode_detail),
- style = MaterialTheme.typography.bodyMedium
- )
- }
- Switch(checked = demoMode, onCheckedChange = { setValue(DEMO_MODE, it) })
- }
-
- if (BuildConfig.DEBUG)
- FilledTonalButton(
- onClick = {
- context.sendNotification(
- Parcel(0xf100f, "Cool stuff", "", null, Service.EXAMPLE),
- Status.OutForDelivery,
- ParcelHistoryItem(
- "The courier has picked up the package",
- LocalDateTime.now(),
- ""
- )
- )
- },
- modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth()
- ) {
- Text("Send test notification")
- }
+ Text(
+ stringResource(R.string.settings_api_keys),
+ modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 2.dp),
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
- LogcatButton(modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth())
+ OutlinedTextField(
+ dhlApiKey,
+ { setValue(DHL_API_KEY, it) },
+ modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp).fillMaxWidth(),
+ label = { Text(stringResource(R.string.service_dhl)) },
+ singleLine = true,
+ visualTransformation = PasswordVisualTransformation(),
+ )
- FilledTonalButton(
- onClick = { aboutDialogOpen = true },
- modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth()
- ) {
- Icon(Icons.Filled.Info, contentDescription = stringResource(R.string.about_app))
- Text(
- text = " ${stringResource(R.string.about_app)}",
- modifier = Modifier.padding(start = 8.dp)
+ Text(
+ AnnotatedString.fromHtml(
+ stringResource(R.string.dhl_api_key_flavor_text),
+ linkStyles =
+ TextLinkStyles(
+ style =
+ SpanStyle(
+ textDecoration = TextDecoration.Underline,
+ color = MaterialTheme.colorScheme.primary,
)
- }
+ ),
+ ),
+ style = MaterialTheme.typography.bodyMedium,
+ modifier = Modifier.padding(horizontal = 16.dp, vertical = 8.dp),
+ )
- Text(
- "Parcel ${BuildConfig.VERSION_NAME}",
- modifier = Modifier.padding(16.dp, 8.dp),
- style = MaterialTheme.typography.bodySmall,
- color = MaterialTheme.colorScheme.onSurfaceVariant,
- )
+ Text(
+ stringResource(R.string.settings_experimental),
+ modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 2.dp),
+ style = MaterialTheme.typography.bodyMedium,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+
+ Row(
+ modifier =
+ Modifier.clickable { setValue(DEMO_MODE, demoMode.not()) }
+ .padding(16.dp, 12.dp)
+ .fillMaxWidth(),
+ horizontalArrangement = Arrangement.SpaceBetween,
+ verticalAlignment = Alignment.CenterVertically,
+ ) {
+ Column(modifier = Modifier.fillMaxWidth(0.8f)) {
+ Text(stringResource(R.string.demo_mode))
+ Text(
+ stringResource(R.string.demo_mode_detail),
+ style = MaterialTheme.typography.bodyMedium,
+ )
}
+ Switch(checked = demoMode, onCheckedChange = { setValue(DEMO_MODE, it) })
+ }
- if (aboutDialogOpen) {
- AboutDialog { aboutDialogOpen = false }
+ if (BuildConfig.DEBUG)
+ FilledTonalButton(
+ onClick = {
+ context.sendNotification(
+ Parcel(0xf100f, "Cool stuff", "", null, Service.EXAMPLE),
+ Status.OutForDelivery,
+ ParcelHistoryItem("The courier has picked up the package", LocalDateTime.now(), ""),
+ )
+ },
+ modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth(),
+ ) {
+ Text("Send test notification")
}
+
+ LogcatButton(modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth())
+
+ FilledTonalButton(
+ onClick = { aboutDialogOpen = true },
+ modifier = Modifier.padding(16.dp, 12.dp).fillMaxWidth(),
+ ) {
+ Icon(Icons.Filled.Info, contentDescription = stringResource(R.string.about_app))
+ Text(
+ text = " ${stringResource(R.string.about_app)}",
+ modifier = Modifier.padding(start = 8.dp),
+ )
+ }
+
+ Text(
+ "Parcel ${BuildConfig.VERSION_NAME}",
+ modifier = Modifier.padding(16.dp, 8.dp),
+ style = MaterialTheme.typography.bodySmall,
+ color = MaterialTheme.colorScheme.onSurfaceVariant,
+ )
+ }
+
+ if (aboutDialogOpen) {
+ AboutDialog { aboutDialogOpen = false }
}
+ }
}
@Composable
@PreviewLightDark
private fun SettingsViewPreview() {
- ParcelTrackerTheme {
- SettingsView(
- onBackPressed = {},
- )
- }
+ ParcelTrackerTheme { SettingsView(onBackPressed = {}) }
}
diff --git a/app/src/main/java/dev/itsvic/parceltracker/ui/views/TabletView.kt b/app/src/main/java/dev/itsvic/parceltracker/ui/views/TabletView.kt
index 92b1382..42ef185 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/ui/views/TabletView.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/ui/views/TabletView.kt
@@ -27,174 +27,158 @@ import androidx.compose.material3.NavigationBarItem
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.getValue
-import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import dev.itsvic.parceltracker.R
-import dev.itsvic.parceltracker.api.Parcel as APIParcel
import dev.itsvic.parceltracker.db.Parcel
import dev.itsvic.parceltracker.db.ParcelWithStatus
import dev.itsvic.parceltracker.ui.components.ParcelRow
+import dev.itsvic.parceltracker.api.Parcel as APIParcel
enum class TabletNavigationItem {
- HOME,
- ADD_PARCEL,
- EDIT_PARCEL,
- SETTINGS
+ HOME,
+ ADD_PARCEL,
+ EDIT_PARCEL,
+ SETTINGS,
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun TabletView(
- parcels: List,
- selectedParcel: Parcel?,
- apiParcel: APIParcel?,
- isLoading: Boolean,
- currentNavigationItem: TabletNavigationItem,
- onNavigateToItem: (TabletNavigationItem) -> Unit,
- onNavigateToParcel: (Parcel) -> Unit,
- onNavigateToAddParcel: () -> Unit,
- onNavigateToSettings: () -> Unit,
- onEditParcel: (Parcel) -> Unit,
- onDeleteParcel: (Parcel) -> Unit,
- onArchiveParcel: (Parcel) -> Unit,
- onArchivePromptDismissal: (Parcel) -> Unit,
- settingsContent: @Composable () -> Unit = {},
- addParcelContent: @Composable () -> Unit = {},
- editParcelContent: @Composable () -> Unit = {}
+ parcels: List,
+ selectedParcel: Parcel?,
+ apiParcel: APIParcel?,
+ isLoading: Boolean,
+ currentNavigationItem: TabletNavigationItem,
+ onNavigateToItem: (TabletNavigationItem) -> Unit,
+ onNavigateToParcel: (Parcel) -> Unit,
+ onNavigateToAddParcel: () -> Unit,
+ onNavigateToSettings: () -> Unit,
+ onEditParcel: (Parcel) -> Unit,
+ onDeleteParcel: (Parcel) -> Unit,
+ onArchiveParcel: (Parcel) -> Unit,
+ onArchivePromptDismissal: (Parcel) -> Unit,
+ settingsContent: @Composable () -> Unit = {},
+ addParcelContent: @Composable () -> Unit = {},
+ editParcelContent: @Composable () -> Unit = {},
) {
- val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
+ val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
+
+ Row(modifier = Modifier.fillMaxSize()) {
+ Card(modifier = Modifier.width(400.dp).fillMaxHeight().padding(8.dp)) {
+ Column {
+ Text(
+ text = stringResource(R.string.app_name),
+ style = MaterialTheme.typography.headlineSmall,
+ modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 8.dp),
+ )
- Row(modifier = Modifier.fillMaxSize()) {
- Card(modifier = Modifier.width(400.dp).fillMaxHeight().padding(8.dp)) {
- Column {
+ LazyColumn(modifier = Modifier.fillMaxWidth().weight(1f).padding(horizontal = 8.dp)) {
+ if (parcels.isEmpty()) {
+ item {
+ Card(modifier = Modifier.fillMaxWidth().padding(8.dp)) {
Text(
- text = stringResource(R.string.app_name),
- style = MaterialTheme.typography.headlineSmall,
- modifier = Modifier.padding(16.dp, 16.dp, 16.dp, 8.dp)
+ stringResource(R.string.no_parcels_flavor),
+ style = MaterialTheme.typography.bodyMedium,
+ modifier = Modifier.padding(16.dp),
)
-
- LazyColumn(
- modifier = Modifier.fillMaxWidth().weight(1f).padding(horizontal = 8.dp)
+ }
+ }
+ } else {
+ items(parcels.reversed()) { parcel ->
+ Card(modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp, vertical = 4.dp)) {
+ ParcelRow(
+ parcel.parcel,
+ parcel.status?.status,
+ isSelected = selectedParcel?.id == parcel.parcel.id,
) {
- if (parcels.isEmpty()) {
- item {
- Card(modifier = Modifier.fillMaxWidth().padding(8.dp)) {
- Text(
- stringResource(R.string.no_parcels_flavor),
- style = MaterialTheme.typography.bodyMedium,
- modifier = Modifier.padding(16.dp)
- )
- }
- }
- } else {
- items(parcels.reversed()) { parcel ->
- Card(
- modifier =
- Modifier.fillMaxWidth()
- .padding(horizontal = 8.dp, vertical = 4.dp)
- ) {
- ParcelRow(
- parcel.parcel,
- parcel.status?.status,
- isSelected = selectedParcel?.id == parcel.parcel.id
- ) {
- onNavigateToParcel(parcel.parcel)
- }
- }
- }
- }
+ onNavigateToParcel(parcel.parcel)
}
+ }
+ }
+ }
+ }
- HorizontalDivider()
+ HorizontalDivider()
- NavigationBar(modifier = Modifier.fillMaxWidth()) {
- NavigationBarItem(
- icon = { Icon(Icons.Filled.Home, contentDescription = null) },
- label = { Text(stringResource(R.string.home)) },
- selected = currentNavigationItem == TabletNavigationItem.HOME,
- onClick = { onNavigateToItem(TabletNavigationItem.HOME) }
- )
- NavigationBarItem(
- icon = { Icon(Icons.Filled.Add, contentDescription = null) },
- label = { Text(stringResource(R.string.add_parcel)) },
- selected = currentNavigationItem == TabletNavigationItem.ADD_PARCEL,
- onClick = { onNavigateToItem(TabletNavigationItem.ADD_PARCEL) }
- )
- NavigationBarItem(
- icon = { Icon(Icons.Filled.Settings, contentDescription = null) },
- label = { Text(stringResource(R.string.settings)) },
- selected = currentNavigationItem == TabletNavigationItem.SETTINGS,
- onClick = { onNavigateToItem(TabletNavigationItem.SETTINGS) }
- )
- }
- }
+ NavigationBar(modifier = Modifier.fillMaxWidth()) {
+ NavigationBarItem(
+ icon = { Icon(Icons.Filled.Home, contentDescription = null) },
+ label = { Text(stringResource(R.string.home)) },
+ selected = currentNavigationItem == TabletNavigationItem.HOME,
+ onClick = { onNavigateToItem(TabletNavigationItem.HOME) },
+ )
+ NavigationBarItem(
+ icon = { Icon(Icons.Filled.Add, contentDescription = null) },
+ label = { Text(stringResource(R.string.add_parcel)) },
+ selected = currentNavigationItem == TabletNavigationItem.ADD_PARCEL,
+ onClick = { onNavigateToItem(TabletNavigationItem.ADD_PARCEL) },
+ )
+ NavigationBarItem(
+ icon = { Icon(Icons.Filled.Settings, contentDescription = null) },
+ label = { Text(stringResource(R.string.settings)) },
+ selected = currentNavigationItem == TabletNavigationItem.SETTINGS,
+ onClick = { onNavigateToItem(TabletNavigationItem.SETTINGS) },
+ )
}
+ }
+ }
- // Right panel: Content area
- Card(modifier = Modifier.weight(1f).fillMaxHeight().padding(8.dp)) {
- when (currentNavigationItem) {
- TabletNavigationItem.HOME -> {
- if (selectedParcel != null) {
- if (isLoading) {
- Box(
- modifier = Modifier.fillMaxSize(),
- contentAlignment = Alignment.Center
- ) {
- CircularProgressIndicator()
- }
- } else if (apiParcel != null) {
- ParcelView(
- parcel = apiParcel,
- humanName = selectedParcel.humanName,
- service = selectedParcel.service,
- isArchived = selectedParcel.isArchived,
- archivePromptDismissed = selectedParcel.archivePromptDismissed,
- onBackPressed = { /* No back button in tablet mode */},
- onEdit = { onEditParcel(selectedParcel) },
- onDelete = { onDeleteParcel(selectedParcel) },
- onArchive = { onArchiveParcel(selectedParcel) },
- onArchivePromptDismissal = {
- onArchivePromptDismissal(selectedParcel)
- },
- showBackButton = false
- )
- }
- } else {
- Box(
- modifier = Modifier.fillMaxSize(),
- contentAlignment = Alignment.Center
- ) {
- Column(
- horizontalAlignment = Alignment.CenterHorizontally,
- verticalArrangement = Arrangement.Center
- ) {
- Text(
- text = stringResource(R.string.app_name),
- style = MaterialTheme.typography.headlineMedium,
- modifier = Modifier.padding(bottom = 16.dp)
- )
- Text(
- text = stringResource(R.string.select_parcel_to_view),
- style = MaterialTheme.typography.bodyLarge
- )
- }
- }
- }
- }
- TabletNavigationItem.ADD_PARCEL -> {
- addParcelContent()
- }
- TabletNavigationItem.EDIT_PARCEL -> {
- editParcelContent()
- }
- TabletNavigationItem.SETTINGS -> {
- settingsContent()
- }
+ // Right panel: Content area
+ Card(modifier = Modifier.weight(1f).fillMaxHeight().padding(8.dp)) {
+ when (currentNavigationItem) {
+ TabletNavigationItem.HOME -> {
+ if (selectedParcel != null) {
+ if (isLoading) {
+ Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+ CircularProgressIndicator()
+ }
+ } else if (apiParcel != null) {
+ ParcelView(
+ parcel = apiParcel,
+ humanName = selectedParcel.humanName,
+ service = selectedParcel.service,
+ isArchived = selectedParcel.isArchived,
+ archivePromptDismissed = selectedParcel.archivePromptDismissed,
+ onBackPressed = { /* No back button in tablet mode */ },
+ onEdit = { onEditParcel(selectedParcel) },
+ onDelete = { onDeleteParcel(selectedParcel) },
+ onArchive = { onArchiveParcel(selectedParcel) },
+ onArchivePromptDismissal = { onArchivePromptDismissal(selectedParcel) },
+ showBackButton = false,
+ )
}
+ } else {
+ Box(modifier = Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
+ Column(
+ horizontalAlignment = Alignment.CenterHorizontally,
+ verticalArrangement = Arrangement.Center,
+ ) {
+ Text(
+ text = stringResource(R.string.app_name),
+ style = MaterialTheme.typography.headlineMedium,
+ modifier = Modifier.padding(bottom = 16.dp),
+ )
+ Text(
+ text = stringResource(R.string.select_parcel_to_view),
+ style = MaterialTheme.typography.bodyLarge,
+ )
+ }
+ }
+ }
+ }
+ TabletNavigationItem.ADD_PARCEL -> {
+ addParcelContent()
+ }
+ TabletNavigationItem.EDIT_PARCEL -> {
+ editParcelContent()
+ }
+ TabletNavigationItem.SETTINGS -> {
+ settingsContent()
}
+ }
}
+ }
}
From 18b1b4a508d9e9089ca38be700b2d95c86b845bb Mon Sep 17 00:00:00 2001
From: Zan1456 <62830223+Zan1456@users.noreply.github.com>
Date: Sun, 20 Jul 2025 21:58:43 +0200
Subject: [PATCH 12/18] Support for imile
---
.../java/dev/itsvic/parceltracker/api/Core.kt | 2 +
.../parceltracker/api/IMileDeliveryService.kt | 96 +++++++++++++++++++
.../ui/views/AddEditParcelView.kt | 22 +++--
app/src/main/res/values-hu/strings.xml | 2 +
app/src/main/res/values/strings.xml | 1 +
5 files changed, 114 insertions(+), 9 deletions(-)
create mode 100644 app/src/main/java/dev/itsvic/parceltracker/api/IMileDeliveryService.kt
diff --git a/app/src/main/java/dev/itsvic/parceltracker/api/Core.kt b/app/src/main/java/dev/itsvic/parceltracker/api/Core.kt
index 044eb14..4645c36 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/api/Core.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/api/Core.kt
@@ -56,6 +56,7 @@ enum class Service {
// Asia
EKART,
SPX_TH,
+ IMILE,
}
val serviceOptions =
@@ -100,6 +101,7 @@ fun getDeliveryService(service: Service): DeliveryService? {
Service.EKART -> EKartDeliveryService
Service.SPX_TH -> SPXThailandDeliveryService
+ Service.IMILE -> IMileDeliveryService
Service.EXAMPLE -> ExampleDeliveryService
else -> null
diff --git a/app/src/main/java/dev/itsvic/parceltracker/api/IMileDeliveryService.kt b/app/src/main/java/dev/itsvic/parceltracker/api/IMileDeliveryService.kt
new file mode 100644
index 0000000..faf0354
--- /dev/null
+++ b/app/src/main/java/dev/itsvic/parceltracker/api/IMileDeliveryService.kt
@@ -0,0 +1,96 @@
+// SPDX-License-Identifier: GPL-3.0-or-later
+package dev.itsvic.parceltracker.api
+
+import com.squareup.moshi.JsonClass
+import dev.itsvic.parceltracker.R
+import java.time.LocalDateTime
+import java.time.format.DateTimeFormatter
+import retrofit2.Retrofit
+import retrofit2.http.GET
+import retrofit2.http.Query
+
+object IMileDeliveryService : DeliveryService {
+ override val nameResource: Int = R.string.service_imile
+ override val acceptsPostCode: Boolean = false
+ override val requiresPostCode: Boolean = false
+
+ private const val BASE_URL = "https://www.imile.com/"
+
+ private val retrofit =
+ Retrofit.Builder()
+ .baseUrl(BASE_URL)
+ .client(api_client)
+ .addConverterFactory(api_factory)
+ .build()
+
+ private val service = retrofit.create(API::class.java)
+
+ override suspend fun getParcel(trackingId: String, postCode: String?): Parcel {
+ val response = service.getParcel(trackingId)
+
+ if (response.status != "success" || response.resultObject == null) {
+ throw ParcelNonExistentException()
+ }
+
+ val resultObject = response.resultObject
+ val trackInfos = resultObject.trackInfos
+
+ if (trackInfos.isEmpty()) {
+ throw ParcelNonExistentException()
+ }
+
+ val history = trackInfos.map { trackInfo ->
+ ParcelHistoryItem(
+ description = trackInfo.content,
+ time = LocalDateTime.parse(trackInfo.time, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")),
+ location = trackInfo.operateStationName ?: ""
+ )
+ }
+
+ val currentStatus = when (trackInfos.firstOrNull()?.trackStage) {
+ 1001 -> Status.Preadvice
+ 2004 -> Status.InWarehouse
+ 1002 -> Status.InTransit
+ 1003 -> Status.OutForDelivery
+ else -> Status.Unknown
+ }
+
+ return Parcel(
+ id = trackingId,
+ history = history,
+ currentStatus = currentStatus
+ )
+ }
+
+ private interface API {
+ @GET("saastms/mobileWeb/track/query")
+ suspend fun getParcel(@Query("waybillNo") waybillNo: String): IMileResponse
+ }
+
+ @JsonClass(generateAdapter = true)
+ data class IMileResponse(
+ val status: String,
+ val resultCode: String,
+ val resultObject: IMileResultObject?,
+ val message: String
+ )
+
+ @JsonClass(generateAdapter = true)
+ data class IMileResultObject(
+ val waybillNo: String,
+ val sendSite: String?,
+ val dispatchStation: String?,
+ val country: String?,
+ val trackInfos: List
+ )
+
+ @JsonClass(generateAdapter = true)
+ data class IMileTrackInfo(
+ val content: String,
+ val trackStage: Int,
+ val trackStageTx: String,
+ val time: String,
+ val operateStationName: String?,
+ val proofs: Any?
+ )
+}
diff --git a/app/src/main/java/dev/itsvic/parceltracker/ui/views/AddEditParcelView.kt b/app/src/main/java/dev/itsvic/parceltracker/ui/views/AddEditParcelView.kt
index 3abdfed..22c7c8e 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/ui/views/AddEditParcelView.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/ui/views/AddEditParcelView.kt
@@ -131,6 +131,7 @@ fun AddEditParcelView(parcel: Parcel?, onBackPressed: () -> Unit, onCompleted: (
Service.GLS_HUNGARY,
Service.MAGYAR_POSTA,
Service.SAMEDAY_HU,
+ Service.IMILE,
Service.DPD_GER,
Service.HERMES,
Service.POSTE_ITALIANE,
@@ -161,6 +162,7 @@ fun AddEditParcelView(parcel: Parcel?, onBackPressed: () -> Unit, onCompleted: (
Service.MAGYAR_POSTA,
Service.SAMEDAY_HU,
Service.EXPRESS_ONE,
+ Service.IMILE,
)
"germany" -> it in listOf(Service.DPD_GER, Service.HERMES)
"italy" -> it == Service.POSTE_ITALIANE
@@ -201,11 +203,12 @@ fun AddEditParcelView(parcel: Parcel?, onBackPressed: () -> Unit, onCompleted: (
Service.SAMEDAY_RO,
Service.POSTNORD,
Service.NOVA_POSHTA,
- Service.UKRPOSHTA -> 2
Service.EKART,
- Service.SPX_TH -> 3
+ Service.SPX_TH,
+ Service.IMILE,
+ Service.UKRPOSHTA -> 2
else -> 4
- }
+ } as Comparable<*>?
}
.thenBy {
when (it) {
@@ -222,7 +225,8 @@ fun AddEditParcelView(parcel: Parcel?, onBackPressed: () -> Unit, onCompleted: (
Service.GLS_HUNGARY,
Service.MAGYAR_POSTA,
Service.SAMEDAY_HU,
- Service.EXPRESS_ONE -> "G_Hungary"
+ Service.EXPRESS_ONE,
+ Service.IMILE -> "G_Hungary"
Service.DPD_GER,
Service.HERMES -> "H_Germany"
Service.POSTE_ITALIANE -> "I_Italy"
@@ -345,8 +349,8 @@ fun AddEditParcelView(parcel: Parcel?, onBackPressed: () -> Unit, onCompleted: (
Service.INPOST,
Service.ORLEN_PACZKA,
Service.POLISH_POST -> "Európa - Lengyelország"
- Service.GLS_HUNGARY,
- Service.MAGYAR_POSTA,
+ Service.GLS_HUNGARY -> "Európa - Magyarország"
+ Service.MAGYAR_POSTA -> "Európa - Magyarország"
Service.SAMEDAY_HU -> "Európa - Magyarország"
Service.DPD_GER,
Service.HERMES -> "Európa - Németország"
@@ -357,6 +361,8 @@ fun AddEditParcelView(parcel: Parcel?, onBackPressed: () -> Unit, onCompleted: (
Service.UKRPOSHTA -> "Európa - Ukrajna"
Service.EKART -> "Ázsia - India"
Service.SPX_TH -> "Ázsia - Thaiföld"
+ Service.IMILE -> "Európa - Magyarország"
+ Service.EXPRESS_ONE -> "Európa - Magyarország"
else -> "Egyéb"
}
@@ -437,9 +443,7 @@ fun AddEditParcelView(parcel: Parcel?, onBackPressed: () -> Unit, onCompleted: (
onCompleted(
Parcel(
id = parcel?.id ?: 0,
- humanName =
- if (humanName.isBlank()) context.getString(R.string.undefinied_packagename)
- else humanName,
+ humanName = humanName.ifBlank { context.getString(R.string.undefinied_packagename) },
parcelId = trackingId,
service = service,
postalCode =
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 887d032..49ee93d 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -65,6 +65,8 @@
Ki kell választani egy futárszolgálatot.
Minta Posta
GLS Magyarország
+ Express One Magyarország
+ iMile
Magyar Posta
Lengyel Posta
Olasz Posta
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a49eae2..8e1c299 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -81,6 +81,7 @@
GLS Hungary
Hermes
Hungarian Post
+ iMile
InPost
Nova Post
Orlen Paczka (Poland)
From bc6a75d89dbf3203fd76529fbc598da5cb75738b Mon Sep 17 00:00:00 2001
From: Zan1456 <62830223+Zan1456@users.noreply.github.com>
Date: Mon, 21 Jul 2025 21:53:11 +0200
Subject: [PATCH 13/18] Remove unused
---
.../main/res/drawable-hdpi/ic_contentpaste.png | Bin 352 -> 0 bytes
.../main/res/drawable-mdpi/ic_contentpaste.png | Bin 260 -> 0 bytes
.../main/res/drawable-xhdpi/ic_contentpaste.png | Bin 450 -> 0 bytes
.../main/res/drawable-xxhdpi/ic_contentpaste.png | Bin 785 -> 0 bytes
4 files changed, 0 insertions(+), 0 deletions(-)
delete mode 100644 app/src/main/res/drawable-hdpi/ic_contentpaste.png
delete mode 100644 app/src/main/res/drawable-mdpi/ic_contentpaste.png
delete mode 100644 app/src/main/res/drawable-xhdpi/ic_contentpaste.png
delete mode 100644 app/src/main/res/drawable-xxhdpi/ic_contentpaste.png
diff --git a/app/src/main/res/drawable-hdpi/ic_contentpaste.png b/app/src/main/res/drawable-hdpi/ic_contentpaste.png
deleted file mode 100644
index da7d251f3d43114d26be2cf0f3aa6015f3eed0b6..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 352
zcmeAS@N?(olHy`uVBq!ia0vp^Dj>|k1|%Oc%$UKzz^Lx&;uum9_jblvufqWXt*_l;
zMII}&@NgAQj6ZRzX-DDJUh9S2^IZ!r>hT8Nzh>M$v8d|o6*EDm&j%ZC&$c#>_m=iZ
z->iJ%^Pf$tR&C#;bAMvkwN1yL|7+Dbz3%m{e_X6d;Wc$Rei2PAR+fid*(Wc1DdQVI
zkzY=X>zu3Sq?itl_{SdpFLj?+<_VmbQ#5(sgWaDOZFLP?^P?(Wp>&(AHOH*9m<-qK
zjd?$#;tjGl0tN1UoGbQVaqYF*HSc#m+~;`S{Vj8+`rYGID}V2QgTe~DWM4f5aXMq
diff --git a/app/src/main/res/drawable-mdpi/ic_contentpaste.png b/app/src/main/res/drawable-mdpi/ic_contentpaste.png
deleted file mode 100644
index 4f4d006167bc9b5a5b25d2e3952784974fe7fe82..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 260
zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`Gjr#)R9Ln`8~PIcruWFW%&I?APA
zVaJPgDw%ngdbbO#R|@^I?O%iD)2S(3v6deeni$*f%DTKprKRBg?|)xs&z_fmsJgz_
zu#&1}YjCgh
zM{gz72`9r&@N06t6S>2w7sK^y`@TkzN3J_3&zZ*drjfgKy5;w+FY{KtV)#;PUlRL$
zTF|c(C+91h|GM+4BUS&?rjM-q>b%dyKi*huyIm^jV0moRmF1e^y?))RJU;F}Eac)*k0M
z_Oo}KiukqqZO~txwWW6I8&AJI658hVEKO(aar4UcpLbsTtK+wzSnB!pokuxK{2u?Y
z+HTQ!E^|)&b20S`mc5@}-+9DhwY;!yZuA_7=O*XY7jug_6xh=N@8{~1y?cI={>zY}
zHA|+vE3rRqz+<}e$?b5l_)n=POkdjx-SzKYAL&2mhk6b35k`X-N%qlwXguh-w)n)|zEYt-FmKmWHy9P-q8c(!c!-;c{Xi`PH<{8QJi
z{?d`9`2~VYJD10%pHrE6Hcfrwg8UeV%wNxS#JXpnnJx2iTh-aq@g+%~`ZLWnA2pR%
zzC7*s-+k`R|01)`KFf^x((@=eeQ#X8(!U+^U)=cgJXw9t{o|{@bG}b5l3|sP$nm*s
z(jO_tU45+h*q82C?+@*}=<-8+TIAt%wl?X$IxmHHy9qWf*D-9bt*$sXr=s;<^8JKI
zYqushT0TE{?Eb=bn{>ZBFLkZi4;NJbI&YzP=k4!DAOBYTnfv_B&%b?(6AD%)oM1n=
z@pAd4Wd8H-+Mlx>eh}ms8?bPJ-im+#@eqv_+*%@6SVg&BHF2?)I<_|LT2ORwtM;to
zh2L5K=(9I}ZAy8u_P23_zDL`=UG}3~l+ajiwC8!kt!;l#d~lw>?)ABf^9N0QKXUW6NRIjB*
bv2{%4N7df3Yb^QzOzI4tu6{1-oD!M
Date: Mon, 21 Jul 2025 21:54:16 +0200
Subject: [PATCH 14/18] Added new statuses to iMile
---
.../parceltracker/api/IMileDeliveryService.kt | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/app/src/main/java/dev/itsvic/parceltracker/api/IMileDeliveryService.kt b/app/src/main/java/dev/itsvic/parceltracker/api/IMileDeliveryService.kt
index faf0354..4feb4c3 100644
--- a/app/src/main/java/dev/itsvic/parceltracker/api/IMileDeliveryService.kt
+++ b/app/src/main/java/dev/itsvic/parceltracker/api/IMileDeliveryService.kt
@@ -47,13 +47,7 @@ object IMileDeliveryService : DeliveryService {
)
}
- val currentStatus = when (trackInfos.firstOrNull()?.trackStage) {
- 1001 -> Status.Preadvice
- 2004 -> Status.InWarehouse
- 1002 -> Status.InTransit
- 1003 -> Status.OutForDelivery
- else -> Status.Unknown
- }
+ val currentStatus = mapTrackStageToStatus(trackInfos.firstOrNull()?.trackStage ?: 0)
return Parcel(
id = trackingId,
@@ -62,6 +56,17 @@ object IMileDeliveryService : DeliveryService {
)
}
+ private fun mapTrackStageToStatus(trackStage: Int): Status {
+ return when (trackStage) {
+ 1001 -> Status.Preadvice
+ 2004 -> Status.InWarehouse
+ 1002 -> Status.InTransit
+ 1003 -> Status.OutForDelivery
+ 2060 -> Status.Delivered
+ else -> logUnknownStatus("iMile", trackStage.toString())
+ }
+ }
+
private interface API {
@GET("saastms/mobileWeb/track/query")
suspend fun getParcel(@Query("waybillNo") waybillNo: String): IMileResponse
From 6b4e68185f0cc66e7491a6ed0374a7ad9c927ce4 Mon Sep 17 00:00:00 2001
From: Zan1456 <62830223+Zan1456@users.noreply.github.com>
Date: Mon, 21 Jul 2025 23:05:44 +0200
Subject: [PATCH 15/18] New icons
---
.../res/drawable-anydpi/ic_filterlist.xml | 11 +++++
app/src/main/res/drawable-anydpi/ic_label.xml | 12 ++++++
.../main/res/drawable-anydpi/ic_language.xml | 11 +++++
.../res/drawable-anydpi/ic_localshipping.xml | 12 ++++++
.../res/drawable-anydpi/ic_locationon.xml | 11 +++++
.../res/drawable-anydpi/ic_networkwifi.xml | 11 +++++
.../main/res/drawable-anydpi/ic_qrcode.xml | 41 +++++++++++++++++++
.../main/res/drawable-anydpi/ic_science.xml | 11 +++++
.../main/res/drawable-anydpi/ic_timeline.xml | 11 +++++
.../main/res/drawable-anydpi/ic_vpnkey.xml | 11 +++++
10 files changed, 142 insertions(+)
create mode 100644 app/src/main/res/drawable-anydpi/ic_filterlist.xml
create mode 100644 app/src/main/res/drawable-anydpi/ic_label.xml
create mode 100644 app/src/main/res/drawable-anydpi/ic_language.xml
create mode 100644 app/src/main/res/drawable-anydpi/ic_localshipping.xml
create mode 100644 app/src/main/res/drawable-anydpi/ic_locationon.xml
create mode 100644 app/src/main/res/drawable-anydpi/ic_networkwifi.xml
create mode 100644 app/src/main/res/drawable-anydpi/ic_qrcode.xml
create mode 100644 app/src/main/res/drawable-anydpi/ic_science.xml
create mode 100644 app/src/main/res/drawable-anydpi/ic_timeline.xml
create mode 100644 app/src/main/res/drawable-anydpi/ic_vpnkey.xml
diff --git a/app/src/main/res/drawable-anydpi/ic_filterlist.xml b/app/src/main/res/drawable-anydpi/ic_filterlist.xml
new file mode 100644
index 0000000..9820675
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_filterlist.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/ic_label.xml b/app/src/main/res/drawable-anydpi/ic_label.xml
new file mode 100644
index 0000000..e255848
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_label.xml
@@ -0,0 +1,12 @@
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/ic_language.xml b/app/src/main/res/drawable-anydpi/ic_language.xml
new file mode 100644
index 0000000..8beebb7
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_language.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/ic_localshipping.xml b/app/src/main/res/drawable-anydpi/ic_localshipping.xml
new file mode 100644
index 0000000..76832c9
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_localshipping.xml
@@ -0,0 +1,12 @@
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/ic_locationon.xml b/app/src/main/res/drawable-anydpi/ic_locationon.xml
new file mode 100644
index 0000000..4d88730
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_locationon.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/ic_networkwifi.xml b/app/src/main/res/drawable-anydpi/ic_networkwifi.xml
new file mode 100644
index 0000000..d508b16
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_networkwifi.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/ic_qrcode.xml b/app/src/main/res/drawable-anydpi/ic_qrcode.xml
new file mode 100644
index 0000000..ca6249b
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_qrcode.xml
@@ -0,0 +1,41 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/ic_science.xml b/app/src/main/res/drawable-anydpi/ic_science.xml
new file mode 100644
index 0000000..a00f40b
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_science.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/ic_timeline.xml b/app/src/main/res/drawable-anydpi/ic_timeline.xml
new file mode 100644
index 0000000..4566deb
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_timeline.xml
@@ -0,0 +1,11 @@
+
+
+
diff --git a/app/src/main/res/drawable-anydpi/ic_vpnkey.xml b/app/src/main/res/drawable-anydpi/ic_vpnkey.xml
new file mode 100644
index 0000000..ead0ae1
--- /dev/null
+++ b/app/src/main/res/drawable-anydpi/ic_vpnkey.xml
@@ -0,0 +1,11 @@
+
+
+
From 19e6a8a1a11e83683a04bd2810f28b7ca2ceb4a6 Mon Sep 17 00:00:00 2001
From: Zan1456 <62830223+Zan1456@users.noreply.github.com>
Date: Mon, 21 Jul 2025 23:05:57 +0200
Subject: [PATCH 16/18] New strings
---
app/src/main/res/values-hu/strings.xml | 31 ++++++++++++++++++++++++
app/src/main/res/values/strings.xml | 33 ++++++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 49ee93d..6f22fa1 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -30,6 +30,23 @@
Ukrajna
India
Thaiföld
+ Nemzetközi
+ Észak-Amerika
+ Európa - Fehéroroszország
+ Európa - Bulgária
+ Európa - Csehország
+ Európa - Egyesült Királyság
+ Európa - Írország
+ Európa - Lengyelország
+ Európa - Magyarország
+ Európa - Németország
+ Európa - Olaszország
+ Európa - Románia
+ Európa - Skandinávia
+ Európa - Ukrajna
+ Ázsia - India
+ Ázsia - Thaiföld
+ Egyéb
Válassz egy csomagot a részletek megtekintéséhez
Főoldal
Biztosan törölni szeretnéd ezt a csomagot?
@@ -39,6 +56,11 @@
Törlés
Futárszolgálat
Teszt mód
+ Csomag részletei
+ %s részletei
+ Követési szám
+ További információk
+ Követési előzmények
A művelet nem engedélyezett teszt módban
Minta csomagokat jelenít meg az applikációban. Nem érinti a már meglévő adatokat.
Támogatás
@@ -97,4 +119,13 @@
Csak korlátlan hálózaton való frissítés
A Parcel csak akkor fog frissítéseket keresni automatikusan, ha nem forgalmidíjas hálózatra van csatlakozva a készülék, pl. otthoni Wi-Fi.
Csomag
+ Hálózat
+ Régió
+ Fejlesztői eszközök
+ Verzió %s
+ Teszt értesítés küldése
+ DHL API kulcs
+ Teszt csomag
+ A futár felvette a csomagot
+ Műveletek