From 5c67b425e8c6c256911d1351badccca9d81c3751 Mon Sep 17 00:00:00 2001 From: Dima Date: Mon, 17 Feb 2025 21:28:09 +0900 Subject: [PATCH] Updating UI for Retrieval Metadata Screen/Dialog. Upping versionCode to 135 --- .../navigation/CommonScreenNavigation.kt | 17 --- .../phone/DashboardRootPhoneNavigation.kt | 19 ++- .../DashboardRootTopLevelTabletNavigation.kt | 28 +++- .../android/pdfworker/PdfWorkerController.kt | 8 +- .../RetrieveMetadataScreen.kt | 134 ++++-------------- .../RetrieveMetadataViewModel.kt | 6 +- .../data/RetrieveMetadataState.kt | 2 +- .../rows/RetrieveMetadataItemRow.kt | 40 ++++++ .../RetrieveMetadataItemRowCentralPart.kt | 120 ++++++++++++++++ .../rows/RetrieveMetadataItemRowLeftPart.kt | 22 +++ .../android/screens/share/ShareViewModel.kt | 2 +- app/src/main/res/drawable/failure.xml | 14 ++ app/src/main/res/drawable/success.xml | 14 ++ app/src/main/res/values/strings.xml | 4 - buildSrc/src/main/kotlin/BuildConfig.kt | 2 +- 15 files changed, 289 insertions(+), 143 deletions(-) create mode 100644 app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRow.kt create mode 100644 app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRowCentralPart.kt create mode 100644 app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRowLeftPart.kt create mode 100644 app/src/main/res/drawable/failure.xml create mode 100644 app/src/main/res/drawable/success.xml diff --git a/app/src/main/java/org/zotero/android/architecture/navigation/CommonScreenNavigation.kt b/app/src/main/java/org/zotero/android/architecture/navigation/CommonScreenNavigation.kt index e0f7fd7..1132361 100644 --- a/app/src/main/java/org/zotero/android/architecture/navigation/CommonScreenNavigation.kt +++ b/app/src/main/java/org/zotero/android/architecture/navigation/CommonScreenNavigation.kt @@ -15,7 +15,6 @@ import org.zotero.android.screens.libraries.LibrariesScreen import org.zotero.android.screens.loading.LoadingScreen import org.zotero.android.screens.mediaviewer.image.ImageViewerScreen import org.zotero.android.screens.mediaviewer.video.VideoPlayerView -import org.zotero.android.screens.retrievemetadata.RetrieveMetadataScreen import org.zotero.android.screens.webview.ZoteroWebViewScreen import java.io.File @@ -195,17 +194,6 @@ fun NavGraphBuilder.collectionsScreen( } } -fun NavGraphBuilder.retrieveMetadataScreen() { - dialogFixedMaxHeight( - route = "${CommonScreenDestinations.RETRIEVE_METADATA_SCREEN}/{$ARG_RETRIEVE_METADATA}", - arguments = listOf( - navArgument(ARG_RETRIEVE_METADATA) { type = NavType.StringType }, - ), - ) { - RetrieveMetadataScreen() - } -} - object CommonScreenDestinations { const val LOADING = "loading" const val LIBRARIES_SCREEN = "librariesScreen" @@ -217,7 +205,6 @@ object CommonScreenDestinations { const val IMAGE_VIEWER_SCREEN = "imageViewerScreen" const val COLLECTIONS_SCREEN = "collectionsScreen" const val ZOTERO_WEB_VIEW_SCREEN = "zoteroWebViewScreen" - const val RETRIEVE_METADATA_SCREEN = "retrieveMetadataScreen" } @@ -242,7 +229,3 @@ fun ZoteroNavigation.toZoteroWebViewScreen(encodedUrl: String) { "${CommonScreenDestinations.ZOTERO_WEB_VIEW_SCREEN}/$encodedUrl" ) } - -fun ZoteroNavigation.toRetrieveMetadata(args: String) { - navController.navigate("${CommonScreenDestinations.RETRIEVE_METADATA_SCREEN}/$args") -} \ No newline at end of file diff --git a/app/src/main/java/org/zotero/android/architecture/navigation/phone/DashboardRootPhoneNavigation.kt b/app/src/main/java/org/zotero/android/architecture/navigation/phone/DashboardRootPhoneNavigation.kt index d7ae907..1b5df3a 100644 --- a/app/src/main/java/org/zotero/android/architecture/navigation/phone/DashboardRootPhoneNavigation.kt +++ b/app/src/main/java/org/zotero/android/architecture/navigation/phone/DashboardRootPhoneNavigation.kt @@ -19,6 +19,7 @@ import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import androidx.navigation.navArgument import org.zotero.android.architecture.EventBusConstants +import org.zotero.android.architecture.navigation.ARG_RETRIEVE_METADATA import org.zotero.android.architecture.navigation.CommonScreenDestinations import org.zotero.android.architecture.navigation.DashboardTopLevelDialogs import org.zotero.android.architecture.navigation.ZoteroNavigation @@ -29,11 +30,9 @@ import org.zotero.android.architecture.navigation.imageViewerScreen import org.zotero.android.architecture.navigation.itemDetailsScreen import org.zotero.android.architecture.navigation.librariesScreen import org.zotero.android.architecture.navigation.loadingScreen -import org.zotero.android.architecture.navigation.retrieveMetadataScreen import org.zotero.android.architecture.navigation.toAddOrEditNote import org.zotero.android.architecture.navigation.toImageViewerScreen import org.zotero.android.architecture.navigation.toItemDetails -import org.zotero.android.architecture.navigation.toRetrieveMetadata import org.zotero.android.architecture.navigation.toVideoPlayerScreen import org.zotero.android.architecture.navigation.toZoteroWebViewScreen import org.zotero.android.architecture.navigation.toolbar.SyncToolbarScreen @@ -52,6 +51,7 @@ import org.zotero.android.screens.dashboard.DashboardViewEffect import org.zotero.android.screens.dashboard.DashboardViewModel import org.zotero.android.screens.dashboard.DashboardViewState import org.zotero.android.screens.filter.FilterScreenPhone +import org.zotero.android.screens.retrievemetadata.RetrieveMetadataScreen import org.zotero.android.screens.scanbarcode.ui.ScanBarcodeScreen import org.zotero.android.screens.settings.settingsNavScreens import org.zotero.android.screens.settings.toSettingsScreen @@ -177,6 +177,15 @@ internal fun DashboardRootPhoneNavigation( TagPickerScreen(onBack = navigation::onBack) } + composable( + route = "${DashboardRootPhoneDestinations.RETRIEVE_METADATA}/{$ARG_RETRIEVE_METADATA}", + arguments = listOf( + navArgument(ARG_RETRIEVE_METADATA) { type = NavType.StringType }, + ), + ) { + RetrieveMetadataScreen(onBack = navigation::onBack) + } + composable( route = DashboardRootPhoneDestinations.TAG_FILTER, arguments = listOf(), @@ -237,7 +246,6 @@ internal fun DashboardRootPhoneNavigation( navigateToTagPicker = navigation::toTagPicker ) zoterWebViewScreen(onClose = navigation::onBack) - retrieveMetadataScreen() } } DashboardTopLevelDialogs(viewState = viewState, viewModel = viewModel) @@ -259,6 +267,7 @@ private object DashboardRootPhoneDestinations { const val TAG_FILTER = "tagFilter" const val COLLECTION_PICKER = "collectionPicker" const val SCAN_BARCODE = "scanBarcode" + const val RETRIEVE_METADATA = "retrieveMetadata" } @@ -288,6 +297,10 @@ private fun ZoteroNavigation.toTagFilter() { navController.navigate(DashboardRootPhoneDestinations.TAG_FILTER) } +private fun ZoteroNavigation.toRetrieveMetadata(args: String) { + navController.navigate("${DashboardRootPhoneDestinations.RETRIEVE_METADATA}/$args") +} + private fun toAllItems( navController: NavHostController, ) { diff --git a/app/src/main/java/org/zotero/android/architecture/navigation/tablet/DashboardRootTopLevelTabletNavigation.kt b/app/src/main/java/org/zotero/android/architecture/navigation/tablet/DashboardRootTopLevelTabletNavigation.kt index a3e3e95..a61afc2 100644 --- a/app/src/main/java/org/zotero/android/architecture/navigation/tablet/DashboardRootTopLevelTabletNavigation.kt +++ b/app/src/main/java/org/zotero/android/architecture/navigation/tablet/DashboardRootTopLevelTabletNavigation.kt @@ -9,20 +9,23 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController +import androidx.navigation.navArgument import org.zotero.android.architecture.EventBusConstants +import org.zotero.android.architecture.navigation.ARG_RETRIEVE_METADATA import org.zotero.android.architecture.navigation.ZoteroNavigation import org.zotero.android.architecture.navigation.addNoteScreen import org.zotero.android.architecture.navigation.dialogDynamicHeight -import org.zotero.android.architecture.navigation.retrieveMetadataScreen +import org.zotero.android.architecture.navigation.dialogFixedMaxHeight import org.zotero.android.architecture.navigation.toAddOrEditNote -import org.zotero.android.architecture.navigation.toRetrieveMetadata import org.zotero.android.architecture.navigation.toZoteroWebViewScreen import org.zotero.android.architecture.navigation.zoterWebViewScreen import org.zotero.android.pdf.pdfReaderScreenAndNavigationForTablet import org.zotero.android.pdf.toPdfScreen import org.zotero.android.screens.dashboard.DashboardViewModel +import org.zotero.android.screens.retrievemetadata.RetrieveMetadataScreen import org.zotero.android.screens.tagpicker.TagPickerScreen import org.zotero.android.uicomponents.navigation.ZoteroNavHost import java.io.File @@ -74,7 +77,9 @@ internal fun DashboardRootTopLevelTabletNavigation( navigateToTagPicker = navigation::toTagPickerScreen ) zoterWebViewScreen(onClose = navigation::onBack) - retrieveMetadataScreen() + retrieveMetadataDialog(onBack = { + navController.popBackStack() + }) } } @@ -126,10 +131,23 @@ private fun NavGraphBuilder.tagPickerDialog( } } +private fun NavGraphBuilder.retrieveMetadataDialog(onBack: () -> Unit) { + dialogFixedMaxHeight( + route = "${DashboardRootDestinations.RETRIEVE_METADATA_DIALOG}/{$ARG_RETRIEVE_METADATA}", + arguments = listOf( + navArgument(ARG_RETRIEVE_METADATA) { type = NavType.StringType }, + ), + ) { + RetrieveMetadataScreen(onBack = onBack) + } +} + + private object DashboardRootDestinations { const val DASHBOARD_SCREEN = "dashboardScreen" const val TAG_PICKER_SCREEN = "tagPickerScreen" const val TAG_PICKER_DIALOG = "tagPickerDialog" + const val RETRIEVE_METADATA_DIALOG = "retrieveMetadataDialog" } private fun ZoteroNavigation.toTagPickerScreen() { @@ -138,4 +156,8 @@ private fun ZoteroNavigation.toTagPickerScreen() { private fun ZoteroNavigation.toTagPickerDialog() { navController.navigate(DashboardRootDestinations.TAG_PICKER_DIALOG) +} + +private fun ZoteroNavigation.toRetrieveMetadata(args: String) { + navController.navigate("${DashboardRootDestinations.RETRIEVE_METADATA_DIALOG}/$args") } \ No newline at end of file diff --git a/app/src/main/java/org/zotero/android/pdfworker/PdfWorkerController.kt b/app/src/main/java/org/zotero/android/pdfworker/PdfWorkerController.kt index 6f87715..dc1bde3 100644 --- a/app/src/main/java/org/zotero/android/pdfworker/PdfWorkerController.kt +++ b/app/src/main/java/org/zotero/android/pdfworker/PdfWorkerController.kt @@ -140,7 +140,7 @@ class PdfWorkerController @Inject constructor( ) ) - observable.emitAsync(Update.recognizedAndSaved) + observable.emitAsync(Update.recognizedAndSaved(createdItem.displayTitle)) } private fun processPdfWorkerUpdate(result: Result) { @@ -268,7 +268,7 @@ class PdfWorkerController @Inject constructor( filename = filename, ) - observable.emitAsync(Update.recognizeInit(fileName = filename)) + observable.emitAsync(Update.recognizeInit(pdfFileName = filename)) identifierLookupController.initialize( lookupMode = IdentifierLookupMode.identifyAndSaveParentItem, @@ -344,10 +344,10 @@ class PdfWorkerController @Inject constructor( } sealed interface Update { - data class recognizeInit(val fileName: String) : Update + data class recognizeInit(val pdfFileName: String) : Update object recognizedDataIsEmpty: Update data class recognizeError(val errorMessage: String) : Update - object recognizedAndSaved : Update + data class recognizedAndSaved(val recognizedTitle: String) : Update object recognizedAndKeptInMemory : Update } } \ No newline at end of file diff --git a/app/src/main/java/org/zotero/android/screens/retrievemetadata/RetrieveMetadataScreen.kt b/app/src/main/java/org/zotero/android/screens/retrievemetadata/RetrieveMetadataScreen.kt index cecb87e..cfb116f 100644 --- a/app/src/main/java/org/zotero/android/screens/retrievemetadata/RetrieveMetadataScreen.kt +++ b/app/src/main/java/org/zotero/android/screens/retrievemetadata/RetrieveMetadataScreen.kt @@ -1,30 +1,23 @@ package org.zotero.android.screens.retrievemetadata -import androidx.activity.compose.LocalOnBackPressedDispatcherOwner -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.material.CircularProgressIndicator -import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import org.zotero.android.screens.retrievemetadata.RetrieveMetadataViewEffect.NavigateBack import org.zotero.android.screens.retrievemetadata.data.RetrieveMetadataState +import org.zotero.android.screens.retrievemetadata.rows.RetrieveMetadataItemRow import org.zotero.android.uicomponents.CustomScaffold import org.zotero.android.uicomponents.Strings import org.zotero.android.uicomponents.misc.NewDivider -import org.zotero.android.uicomponents.theme.CustomPalette import org.zotero.android.uicomponents.theme.CustomTheme import org.zotero.android.uicomponents.theme.CustomThemeWithStatusAndNavBars import org.zotero.android.uicomponents.topbar.NewCustomTopBar @@ -32,6 +25,7 @@ import org.zotero.android.uicomponents.topbar.NewHeadingTextButton @Composable internal fun RetrieveMetadataScreen( + onBack: () -> Unit, viewModel: RetrieveMetadataViewModel = hiltViewModel(), ) { @@ -40,18 +34,16 @@ internal fun RetrieveMetadataScreen( LaunchedEffect(key1 = viewModel) { viewModel.init() } - val backDispatcher = LocalOnBackPressedDispatcherOwner.current?.onBackPressedDispatcher LaunchedEffect(key1 = viewEffect) { when (viewEffect?.consume()) { NavigateBack -> { - backDispatcher?.onBackPressed() + onBack() } null -> Unit } } - val isBackEnabled = viewState.retrieveMetadataState != RetrieveMetadataState.loading val backgroundColor = CustomTheme.colors.popupBackgroundContent @@ -59,42 +51,27 @@ internal fun RetrieveMetadataScreen( statusBarBackgroundColor = CustomTheme.colors.topBarBackgroundColor, navBarBackgroundColor = backgroundColor ) { - + val isLoadingState = viewState.retrieveMetadataState == RetrieveMetadataState.loading CustomScaffold( backgroundColor = backgroundColor, topBar = { RetrieveMetadataTopBar(onDone = { - backDispatcher?.onBackPressed() - }, isEnabled = isBackEnabled) + onBack() + }, + onCancel = { + onBack() + } + , isLoadingState = isLoadingState) }, ) { LazyColumn( modifier = Modifier .fillMaxSize() - .padding(8.dp) ) { - val retrieveMetadataState = viewState.retrieveMetadataState item { - FileNameRow(viewState.fileName) - RetrieveMetadataDivider() - StatusRow(retrieveMetadataState) - RetrieveMetadataDivider() - } - - item { - when (retrieveMetadataState) { - is RetrieveMetadataState.success -> { - } - - else -> { - //no-op - } - } + RetrieveMetadataItemRow(viewState = viewState, showBottomDivider = false) } } - if (viewState.retrieveMetadataState == RetrieveMetadataState.loading) { - LoadingIndicator() - } } } } @@ -106,87 +83,32 @@ private fun RetrieveMetadataDivider() { Spacer(modifier = Modifier.height(4.dp)) } -@Composable -private fun StatusRow(state: RetrieveMetadataState) { - val text = when(state) { - is RetrieveMetadataState.failed -> { - stringResource(Strings.retrieve_metadata_status_failed, state.message) - } - RetrieveMetadataState.loading -> { - stringResource(Strings.retrieve_metadata_status_in_progress) - } - is RetrieveMetadataState.success -> { - stringResource(Strings.retrieve_metadata_status_in_success) - } - is RetrieveMetadataState.recognizedDataIsEmpty -> { - stringResource(Strings.retrieve_metadata_status_no_results) - } - - RetrieveMetadataState.fileIsNotPdf -> { - //no-op - "" - } - } - Text( - modifier = Modifier - .fillMaxSize(), - text = text, - color = CustomTheme.colors.primaryContent, - style = CustomTheme.typography.default, - ) - if (state is RetrieveMetadataState.failed) { - Text( - modifier = Modifier - .fillMaxSize(), - text = "Error: ${state.message}", - color = CustomPalette.ErrorRed, - style = CustomTheme.typography.default, - ) - } -} - -@Composable -private fun FileNameRow(fileName: String) { - Text( - modifier = Modifier - .fillMaxSize(), - text = stringResource(id = Strings.retrieve_metadata_filename, fileName), - color = CustomTheme.colors.primaryContent, - style = CustomTheme.typography.default, - ) -} - -@Composable -private fun LoadingIndicator() { - Box(modifier = Modifier.fillMaxSize()) { - CircularProgressIndicator( - color = CustomTheme.colors.zoteroDefaultBlue, - modifier = Modifier - .align(Alignment.Center) - .size(48.dp) - ) - } -} - @Composable private fun RetrieveMetadataTopBar( onDone: () -> Unit, - isEnabled: Boolean, + onCancel: () -> Unit, + isLoadingState: Boolean, ) { NewCustomTopBar( title = stringResource(id = Strings.retrieve_metadata_dialog_title), rightGuidelineStartPercentage = 0.2f, leftGuidelineStartPercentage = 0.2f, + leftContainerContent = listOf { + if (isLoadingState) { + NewHeadingTextButton( + text = stringResource(id = Strings.cancel), + onClick = onCancel + ) + } + }, rightContainerContent = listOf { - NewHeadingTextButton( - text = stringResource(id = Strings.done), - isEnabled = isEnabled, - onClick = { - if (isEnabled) { - onDone() - } - } - ) + if (!isLoadingState) { + NewHeadingTextButton( + text = stringResource(id = Strings.done), + onClick = onDone + ) + } + } ) } \ No newline at end of file diff --git a/app/src/main/java/org/zotero/android/screens/retrievemetadata/RetrieveMetadataViewModel.kt b/app/src/main/java/org/zotero/android/screens/retrievemetadata/RetrieveMetadataViewModel.kt index d92b497..4571bae 100644 --- a/app/src/main/java/org/zotero/android/screens/retrievemetadata/RetrieveMetadataViewModel.kt +++ b/app/src/main/java/org/zotero/android/screens/retrievemetadata/RetrieveMetadataViewModel.kt @@ -45,7 +45,7 @@ internal class RetrieveMetadataViewModel @Inject constructor( when(update) { is PdfWorkerController.Update.recognizeInit -> { updateState { - copy(fileName = update.fileName) + copy(pdfFileName = update.pdfFileName) } } PdfWorkerController.Update.recognizedDataIsEmpty -> { @@ -58,7 +58,7 @@ internal class RetrieveMetadataViewModel @Inject constructor( } is PdfWorkerController.Update.recognizedAndSaved -> { updateState { - copy(retrieveMetadataState = RetrieveMetadataState.success) + copy(retrieveMetadataState = RetrieveMetadataState.success(update.recognizedTitle)) } } is PdfWorkerController.Update.recognizedAndKeptInMemory -> { @@ -75,7 +75,7 @@ internal class RetrieveMetadataViewModel @Inject constructor( } internal data class RetrieveMetadataViewState( - val fileName: String = "", + val pdfFileName: String = "", val retrieveMetadataState: RetrieveMetadataState = RetrieveMetadataState.loading, ) : ViewState diff --git a/app/src/main/java/org/zotero/android/screens/retrievemetadata/data/RetrieveMetadataState.kt b/app/src/main/java/org/zotero/android/screens/retrievemetadata/data/RetrieveMetadataState.kt index bb4c65d..274bcc2 100644 --- a/app/src/main/java/org/zotero/android/screens/retrievemetadata/data/RetrieveMetadataState.kt +++ b/app/src/main/java/org/zotero/android/screens/retrievemetadata/data/RetrieveMetadataState.kt @@ -4,6 +4,6 @@ sealed interface RetrieveMetadataState { object loading : RetrieveMetadataState object recognizedDataIsEmpty : RetrieveMetadataState data class failed(val message: String) : RetrieveMetadataState - object success : RetrieveMetadataState + data class success(val recognizedTitle: String) : RetrieveMetadataState object fileIsNotPdf : RetrieveMetadataState } \ No newline at end of file diff --git a/app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRow.kt b/app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRow.kt new file mode 100644 index 0000000..af20760 --- /dev/null +++ b/app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRow.kt @@ -0,0 +1,40 @@ +package org.zotero.android.screens.retrievemetadata.rows + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import org.zotero.android.screens.retrievemetadata.RetrieveMetadataViewState +import org.zotero.android.uicomponents.misc.CustomDivider + +@Composable +internal fun RetrieveMetadataItemRow( + viewState: RetrieveMetadataViewState, + showBottomDivider: Boolean = false, +) { + val rowModifier: Modifier = Modifier.height(64.dp) + Box { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = rowModifier + ) { + RetrieveMetadataItemRowLeftPart() + Spacer(modifier = Modifier.width(16.dp)) + RetrieveMetadataItemRowCentralPart( + title = viewState.pdfFileName, + retrieveMetadataState = viewState.retrieveMetadataState + ) + } + if (showBottomDivider) { + CustomDivider(modifier = Modifier + .align(Alignment.BottomCenter) + .padding(start = 60.dp)) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRowCentralPart.kt b/app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRowCentralPart.kt new file mode 100644 index 0000000..78e4fcf --- /dev/null +++ b/app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRowCentralPart.kt @@ -0,0 +1,120 @@ +package org.zotero.android.screens.retrievemetadata.rows + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.material.LinearProgressIndicator +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import org.zotero.android.screens.retrievemetadata.data.RetrieveMetadataState +import org.zotero.android.uicomponents.Drawables +import org.zotero.android.uicomponents.Strings +import org.zotero.android.uicomponents.theme.CustomPalette +import org.zotero.android.uicomponents.theme.CustomTheme + +@Composable +internal fun RetrieveMetadataItemRowCentralPart( + title:String, + retrieveMetadataState: RetrieveMetadataState, +) { + Column { + Row(verticalAlignment = Alignment.CenterVertically) { + Column( + modifier = Modifier + .padding(end = 8.dp) + .weight(1f) + ) { + Text( + text = title, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + color = CustomTheme.colors.allItemsRowTitleColor, + style = CustomTheme.typography.newHeadline + ) + Spacer(modifier = Modifier.height(4.dp)) + Row( + modifier = Modifier.fillMaxWidth(), + verticalAlignment = Alignment.CenterVertically + ) { + when (retrieveMetadataState) { + is RetrieveMetadataState.failed -> { + ErrorMessagePart(retrieveMetadataState.message) + } + RetrieveMetadataState.fileIsNotPdf -> { + //no-op + } + RetrieveMetadataState.loading -> { + LoadingPart() + } + RetrieveMetadataState.recognizedDataIsEmpty -> { + SuccessMessagePart(stringResource(Strings.retrieve_metadata_status_no_results)) + } + is RetrieveMetadataState.success -> { + SuccessMessagePart(retrieveMetadataState.recognizedTitle) + } + } + } + } + } + } +} + +@Composable +private fun LoadingPart() { + LinearProgressIndicator( + modifier = Modifier + .fillMaxWidth() + .padding(top = 4.dp, bottom = 8.dp), + backgroundColor = Color(0x29787880), + color = Color(0xFF1A88FF), + ) +} + +@Composable +private fun RowScope.ErrorMessagePart(errorMessage: String) { + Image( + modifier = Modifier.size(16.dp), + painter = painterResource(id = Drawables.failure), + contentDescription = null, + ) + Spacer(modifier = Modifier.width(4.dp)) + Text( + modifier = Modifier, + text = errorMessage, + color = CustomPalette.ErrorRed, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + style = CustomTheme.typography.newBody, + ) +} + +@Composable +private fun RowScope.SuccessMessagePart(successMessage: String) { + Image( + modifier = Modifier.size(16.dp), + painter = painterResource(id = Drawables.success), + contentDescription = null, + ) + Spacer(modifier = Modifier.width(4.dp)) + Text( + text = successMessage, + style = CustomTheme.typography.newBody, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + color = CustomPalette.SystemGray, + ) +} \ No newline at end of file diff --git a/app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRowLeftPart.kt b/app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRowLeftPart.kt new file mode 100644 index 0000000..da63b3e --- /dev/null +++ b/app/src/main/java/org/zotero/android/screens/retrievemetadata/rows/RetrieveMetadataItemRowLeftPart.kt @@ -0,0 +1,22 @@ +package org.zotero.android.screens.retrievemetadata.rows + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.unit.dp +import org.zotero.android.uicomponents.Drawables + +@Composable +internal fun RetrieveMetadataItemRowLeftPart( +) { + Spacer(modifier = Modifier.width(16.dp)) + Image( + modifier = Modifier.size(28.dp), + painter = painterResource(id = Drawables.item_type_pdf), + contentDescription = null, + ) +} \ No newline at end of file diff --git a/app/src/main/java/org/zotero/android/screens/share/ShareViewModel.kt b/app/src/main/java/org/zotero/android/screens/share/ShareViewModel.kt index 7ab44e7..737d87a 100644 --- a/app/src/main/java/org/zotero/android/screens/share/ShareViewModel.kt +++ b/app/src/main/java/org/zotero/android/screens/share/ShareViewModel.kt @@ -1077,7 +1077,7 @@ internal class ShareViewModel @Inject constructor( } is PdfWorkerController.Update.recognizedAndKeptInMemory -> { updateState { - copy(retrieveMetadataState = RetrieveMetadataState.success) + copy(retrieveMetadataState = RetrieveMetadataState.success("")) } } } diff --git a/app/src/main/res/drawable/failure.xml b/app/src/main/res/drawable/failure.xml new file mode 100644 index 0000000..b96e195 --- /dev/null +++ b/app/src/main/res/drawable/failure.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/app/src/main/res/drawable/success.xml b/app/src/main/res/drawable/success.xml new file mode 100644 index 0000000..679834d --- /dev/null +++ b/app/src/main/res/drawable/success.xml @@ -0,0 +1,14 @@ + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 75e0bd4..acff14c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -40,10 +40,6 @@ Retrieve Metadata Metadata Retrieval - Filename: %s - Status: In Progress - Status: Success - Status: Failed Status: recognition yielded no results Failed to initialize diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt index c56a35e..1b9eb0c 100644 --- a/buildSrc/src/main/kotlin/BuildConfig.kt +++ b/buildSrc/src/main/kotlin/BuildConfig.kt @@ -4,7 +4,7 @@ object BuildConfig { const val compileSdkVersion = 34 const val targetSdk = 34 - val versionCode = 134 // Must be updated on every build + val versionCode = 135 // Must be updated on every build val version = Version( major = 1, minor = 0,