diff --git a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderBottomPanel.kt b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderBottomPanel.kt index 33cb7026..93b1aa66 100644 --- a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderBottomPanel.kt +++ b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderBottomPanel.kt @@ -19,7 +19,7 @@ import org.zotero.android.uicomponents.theme.CustomTheme @Composable internal fun BoxScope.PdfReaderBottomPanel( layoutType: CustomLayoutSize.LayoutType, - viewModel: PdfReaderViewModel, + vMInterface: PdfReaderVMInterface, viewState: PdfReaderViewState ) { Box( @@ -41,7 +41,7 @@ internal fun BoxScope.PdfReaderBottomPanel( .padding(start = 24.dp) .align(Alignment.CenterStart), drawableRes = filterDrawable, - onClick = viewModel::showFilterPopup + onClick = vMInterface::showFilterPopup ) } } diff --git a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderModes.kt b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderModes.kt new file mode 100644 index 00000000..43ab37a6 --- /dev/null +++ b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderModes.kt @@ -0,0 +1,129 @@ +package org.zotero.android.pdf.reader + +import android.net.Uri +import androidx.compose.animation.AnimatedContent +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.ContentTransform +import androidx.compose.animation.SizeTransform +import androidx.compose.animation.core.tween +import androidx.compose.animation.slideInHorizontally +import androidx.compose.animation.slideOutHorizontally +import androidx.compose.animation.with +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyListState +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.dp +import org.zotero.android.architecture.ui.CustomLayoutSize +import org.zotero.android.pdf.reader.sidebar.PdfReaderSidebar +import org.zotero.android.pdf.reader.sidebar.SidebarDivider +import org.zotero.android.uicomponents.theme.CustomTheme + +@Composable +internal fun PdfReaderTabletMode( + vMInterface: PdfReaderVMInterface, + viewState: PdfReaderViewState, + lazyListState: LazyListState, + layoutType: CustomLayoutSize.LayoutType, + uri: Uri, + focusRequester: FocusRequester, +) { + Row(modifier = Modifier.fillMaxSize()) { + AnimatedContent(targetState = viewState.showSideBar, transitionSpec = { + createSidebarTransitionSpec() + }, label = "") { showSideBar -> + if (showSideBar) { + Column( + modifier = Modifier + .fillMaxHeight() + .fillMaxWidth(0.3f) + ) { + PdfReaderSidebar( + vMInterface = vMInterface, + viewState = viewState, + lazyListState = lazyListState, + layoutType = layoutType, + focusRequester = focusRequester, + ) + } + } + } + if (viewState.showSideBar) { + SidebarDivider( + modifier = Modifier + .width(2.dp) + .fillMaxHeight() + ) + } + + PdfReaderPspdfKitBox( + uri = uri, + viewState = viewState, + vMInterface = vMInterface, + ) + } +} + +@Composable +internal fun PdfReaderPhoneMode( + vMInterface: PdfReaderVMInterface, + viewState: PdfReaderViewState, + lazyListState: LazyListState, + layoutType: CustomLayoutSize.LayoutType, + uri: Uri, + focusRequester: FocusRequester, +) { + Box( + modifier = Modifier + .fillMaxSize() + ) { + PdfReaderPspdfKitBox( + uri = uri, + viewState = viewState, + vMInterface = vMInterface + ) + AnimatedContent( + targetState = viewState.showSideBar, + transitionSpec = { + createSidebarTransitionSpec() + }, label = "" + ) { showSideBar -> + if (showSideBar) { + Column( + modifier = Modifier + .fillMaxSize() + .background(CustomTheme.colors.pdfAnnotationsFormBackground) + ) { + PdfReaderSidebar( + viewState = viewState, + vMInterface = vMInterface, + lazyListState = lazyListState, + layoutType = layoutType, + focusRequester = focusRequester + ) + } + } + } + } +} + +private fun AnimatedContentTransitionScope.createSidebarTransitionSpec(): ContentTransform { + val intOffsetSpec = tween() + return (slideInHorizontally(intOffsetSpec) { -it } with + slideOutHorizontally(intOffsetSpec) { -it }).using( + // Disable clipping since the faded slide-in/out should + // be displayed out of bounds. + SizeTransform( + clip = false, + sizeAnimationSpec = { _, _ -> tween() } + )) +} diff --git a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderPspdfKitBox.kt b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderPspdfKitBox.kt index f8c0ed38..77082bcb 100644 --- a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderPspdfKitBox.kt +++ b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderPspdfKitBox.kt @@ -87,7 +87,7 @@ private val pdfReaderToolsList = listOf( @Composable internal fun PdfReaderPspdfKitBox( uri: Uri, - viewModel: PdfReaderViewModel, + vMInterface: PdfReaderVMInterface, viewState: PdfReaderViewState ) { val density = LocalDensity.current @@ -133,11 +133,11 @@ internal fun PdfReaderPspdfKitBox( ) } ) { - PdfReaderPspdfKitView(uri = uri, viewModel = viewModel) + PdfReaderPspdfKitView(uri = uri, vMInterface = vMInterface) if (viewState.showCreationToolbar) { PdfReaderAnnotationCreationToolbar( - viewModel = viewModel, viewState = viewState, + vMInterface = vMInterface, state = anchoredDraggableState, onShowSnapTargetAreas = { shouldShowSnapTargetAreas = true }, shouldShowSnapTargetAreas = shouldShowSnapTargetAreas @@ -153,8 +153,8 @@ enum class DragAnchors(val fraction: Float) { @Composable fun BoxScope.PdfReaderAnnotationCreationToolbar( - viewModel: PdfReaderViewModel, viewState: PdfReaderViewState, + vMInterface: PdfReaderVMInterface, state: AnchoredDraggableState, onShowSnapTargetAreas: () -> Unit, shouldShowSnapTargetAreas: Boolean, @@ -162,7 +162,7 @@ fun BoxScope.PdfReaderAnnotationCreationToolbar( val roundCornerShape = RoundedCornerShape(size = 4.dp) val draggableInteractionSource = remember { MutableInteractionSource() } val coroutineScope = rememberCoroutineScope() - LaunchedEffect(key1 = viewModel) { + LaunchedEffect(key1 = vMInterface) { draggableInteractionSource.interactions.onEach { onShowSnapTargetAreas() }.launchIn(coroutineScope) @@ -233,21 +233,21 @@ fun BoxScope.PdfReaderAnnotationCreationToolbar( pdfReaderToolsList.forEach { tool -> if (!tool.isHidden) { AnnotationCreationToggleButton( - viewModel = viewModel, + activeAnnotationTool = vMInterface.activeAnnotationTool, pdfReaderTool = tool, - toggleButton = viewModel::toggle + toggleButton = vMInterface::toggle ) Spacer(modifier = Modifier.height(20.dp)) } } - val activeAnnotationTool = viewModel.activeAnnotationTool + val activeAnnotationTool = vMInterface.activeAnnotationTool if (viewState.isColorPickerButtonVisible && activeAnnotationTool != null) { if (activeAnnotationTool == AnnotationTool.ERASER) { - EmptyFilterCircle(onClick = { viewModel.showToolOptions() }) + EmptyFilterCircle(onClick = vMInterface::showToolOptions) } else { - val color = viewModel.toolColors[activeAnnotationTool] + val color = vMInterface.toolColors[activeAnnotationTool] if (color != null) { - FilledFilterCircle(hex = color, onClick = { viewModel.showToolOptions() }) + FilledFilterCircle(hex = color, onClick = vMInterface::showToolOptions) } } } @@ -257,21 +257,21 @@ fun BoxScope.PdfReaderAnnotationCreationToolbar( modifier = Modifier.align(Alignment.BottomCenter) ) { AnnotationCreationButton( - isEnabled = viewModel.canUndo(), + isEnabled = vMInterface.canUndo(), iconInt = Drawables.undo_24px, - onButtonClick = viewModel::onUndoClick + onButtonClick = vMInterface::onUndoClick ) Spacer(modifier = Modifier.height(20.dp)) AnnotationCreationButton( - isEnabled = viewModel.canRedo(), + isEnabled = vMInterface.canRedo(), iconInt = Drawables.redo_24px, - onButtonClick = viewModel::onRedoClick + onButtonClick = vMInterface::onRedoClick ) Spacer(modifier = Modifier.height(20.dp)) AnnotationCreationButton( isEnabled = true, iconInt = Drawables.cancel_24px, - onButtonClick = viewModel::onCloseClick + onButtonClick = vMInterface::onCloseClick ) Spacer(modifier = Modifier.height(20.dp)) } @@ -280,11 +280,11 @@ fun BoxScope.PdfReaderAnnotationCreationToolbar( @Composable private fun AnnotationCreationToggleButton( - viewModel: PdfReaderViewModel, + activeAnnotationTool: AnnotationTool?, pdfReaderTool: PdfReaderTool, toggleButton: (AnnotationTool) -> Unit ) { - val isSelected = viewModel.activeAnnotationTool == pdfReaderTool.type + val isSelected = activeAnnotationTool == pdfReaderTool.type val tintColor = if (isSelected) { Color.White } else { diff --git a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderPspdfKitView.kt b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderPspdfKitView.kt index 7c6f14d2..33d97be7 100644 --- a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderPspdfKitView.kt +++ b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderPspdfKitView.kt @@ -19,12 +19,15 @@ import org.zotero.android.architecture.ui.CustomLayoutSize import timber.log.Timber @Composable -fun PdfReaderPspdfKitView(uri: Uri, viewModel: PdfReaderViewModel) { +fun PdfReaderPspdfKitView( + uri: Uri, + vMInterface: PdfReaderVMInterface +) { val activity = LocalContext.current as? AppCompatActivity ?: return val annotationMaxSideSize = annotationMaxSideSize() val fragmentManager = activity.supportFragmentManager val layoutType = CustomLayoutSize.calculateLayoutType() - viewModel.annotationMaxSideSize = annotationMaxSideSize + vMInterface.annotationMaxSideSize = annotationMaxSideSize AndroidView( modifier = Modifier.fillMaxSize(), factory = { context -> @@ -45,7 +48,7 @@ fun PdfReaderPspdfKitView(uri: Uri, viewModel: PdfReaderViewModel) { pdfThumbnailBar.layoutParams = thumbnailBarLayoutParams frameLayout.addView(pdfThumbnailBar) - viewModel.init( + vMInterface.init( isTablet = layoutType.isTablet(), uri = uri, containerId = fragmentContainerView.id, diff --git a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderScreen.kt b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderScreen.kt index 481cd9c1..1125e0fb 100644 --- a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderScreen.kt +++ b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderScreen.kt @@ -1,45 +1,23 @@ package org.zotero.android.pdf.reader -import android.net.Uri import androidx.appcompat.app.AppCompatActivity import androidx.compose.animation.AnimatedContent -import androidx.compose.animation.AnimatedContentTransitionScope -import androidx.compose.animation.ContentTransform -import androidx.compose.animation.SizeTransform -import androidx.compose.animation.core.tween -import androidx.compose.animation.slideInHorizontally -import androidx.compose.animation.slideOutHorizontally -import androidx.compose.animation.with -import androidx.compose.foundation.background import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager -import androidx.compose.ui.unit.IntOffset -import androidx.compose.ui.unit.dp import androidx.core.view.WindowCompat import androidx.core.view.WindowInsetsCompat import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.Lifecycle import org.zotero.android.architecture.ui.CustomLayoutSize import org.zotero.android.architecture.ui.ObserveLifecycleEvent -import org.zotero.android.pdf.reader.sidebar.PdfReaderSidebar -import org.zotero.android.pdf.reader.sidebar.SidebarDivider import org.zotero.android.uicomponents.CustomScaffold import org.zotero.android.uicomponents.theme.CustomTheme import org.zotero.android.uicomponents.theme.CustomThemeWithStatusAndNavBars @@ -152,19 +130,17 @@ internal fun PdfReaderScreen( ) { if (layoutType.isTablet()) { PdfReaderTabletMode( - showSideBar = viewState.showSideBar, + vMInterface = viewModel, viewState = viewState, - viewModel = viewModel, lazyListState = lazyListState, layoutType = layoutType, - uri = uri, focusRequester = focusRequester, + uri = uri, ) } else { PdfReaderPhoneMode( - showSideBar = viewState.showSideBar, viewState = viewState, - viewModel = viewModel, + vMInterface = viewModel, lazyListState = lazyListState, layoutType = layoutType, uri = uri, @@ -176,100 +152,3 @@ internal fun PdfReaderScreen( } -@Composable -private fun PdfReaderTabletMode( - showSideBar: Boolean, - viewState: PdfReaderViewState, - viewModel: PdfReaderViewModel, - lazyListState: LazyListState, - layoutType: CustomLayoutSize.LayoutType, - uri: Uri, - focusRequester: FocusRequester, -) { - Row(modifier = Modifier.fillMaxSize()) { - AnimatedContent(targetState = showSideBar, transitionSpec = { - createSidebarTransitionSpec() - }, label = "") { showSideBar -> - if (showSideBar) { - Column( - modifier = Modifier - .fillMaxHeight() - .fillMaxWidth(0.3f) - ) { - PdfReaderSidebar( - viewState = viewState, - viewModel = viewModel, - lazyListState = lazyListState, - layoutType = layoutType, - focusRequester = focusRequester, - ) - } - - } - } - if (showSideBar) { - SidebarDivider( - modifier = Modifier - .width(2.dp) - .fillMaxHeight() - ) - } - - PdfReaderPspdfKitBox( - uri = uri, - viewModel = viewModel, - viewState = viewState - ) - } -} - -@Composable -private fun PdfReaderPhoneMode( - showSideBar: Boolean, - viewState: PdfReaderViewState, - viewModel: PdfReaderViewModel, - lazyListState: LazyListState, - layoutType: CustomLayoutSize.LayoutType, - uri: Uri, - focusRequester: FocusRequester, -) { - Box( - modifier = Modifier - .fillMaxSize() - ) { - PdfReaderPspdfKitBox(uri = uri, viewModel = viewModel, viewState = viewState) - AnimatedContent(targetState = showSideBar, transitionSpec = { - createSidebarTransitionSpec() - }, label = "") { showSideBar -> - if (showSideBar) { - Column( - modifier = Modifier - .fillMaxSize() - .background(CustomTheme.colors.pdfAnnotationsFormBackground) - ) { - PdfReaderSidebar( - viewState = viewState, - viewModel = viewModel, - lazyListState = lazyListState, - layoutType = layoutType, - focusRequester = focusRequester, - - ) - } - } - } - } -} - -private fun AnimatedContentTransitionScope.createSidebarTransitionSpec(): ContentTransform { - val intOffsetSpec = tween() - return (slideInHorizontally(intOffsetSpec) { -it } with - slideOutHorizontally(intOffsetSpec) { -it }).using( - // Disable clipping since the faded slide-in/out should - // be displayed out of bounds. - SizeTransform( - clip = false, - sizeAnimationSpec = { _, _ -> tween() } - )) -} - diff --git a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderVMInterface.kt b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderVMInterface.kt new file mode 100644 index 00000000..31159198 --- /dev/null +++ b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderVMInterface.kt @@ -0,0 +1,42 @@ +package org.zotero.android.pdf.reader + +import android.net.Uri +import androidx.fragment.app.FragmentManager +import com.pspdfkit.ui.PdfThumbnailBar +import com.pspdfkit.ui.special_mode.controller.AnnotationTool +import org.zotero.android.pdf.cache.AnnotationPreviewMemoryCache +import org.zotero.android.pdf.data.Annotation + +interface PdfReaderVMInterface { + + var annotationMaxSideSize: Int + val annotationPreviewMemoryCache: AnnotationPreviewMemoryCache + val activeAnnotationTool: AnnotationTool? + var toolColors: MutableMap + + fun init( + uri: Uri, + annotationMaxSideSize: Int, + containerId: Int, + fragmentManager: FragmentManager, + isTablet: Boolean, + pdfThumbnailBar: PdfThumbnailBar, + ) + + fun onTagsClicked(annotation: Annotation) + fun onSearch(text: String) + fun onCommentFocusFieldChange(annotationKey: String) + fun onCommentTextChange(annotationKey: String, comment: String) + fun onMoreOptionsForItemClicked() + fun annotation(key: AnnotationKey): Annotation? + fun selectAnnotation(key: AnnotationKey) + fun loadPreviews(keys: List) + fun showFilterPopup() + fun toggle(tool: AnnotationTool) + fun showToolOptions() + fun canUndo(): Boolean + fun canRedo(): Boolean + fun onUndoClick() + fun onRedoClick() + fun onCloseClick() +} \ No newline at end of file diff --git a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt index dd49a7ac..eb057d61 100644 --- a/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt +++ b/app/src/main/java/org/zotero/android/pdf/reader/PdfReaderViewModel.kt @@ -155,12 +155,12 @@ class PdfReaderViewModel @Inject constructor( private val fileCache: AnnotationPreviewFileCache, private val context: Context, private val annotationPreviewCacheUpdatedEventStream: AnnotationPreviewCacheUpdatedEventStream, - val annotationPreviewMemoryCache: AnnotationPreviewMemoryCache, + override val annotationPreviewMemoryCache: AnnotationPreviewMemoryCache, private val schemaController: SchemaController, private val dateParser: DateParser, private val navigationParamsMarshaller: NavigationParamsMarshaller, stateHandle: SavedStateHandle, -) : BaseViewModel2(PdfReaderViewState()) { +) : BaseViewModel2(PdfReaderViewState()), PdfReaderVMInterface { private var liveAnnotations: RealmResults? = null private var databaseAnnotations: RealmResults? = null @@ -182,9 +182,9 @@ class PdfReaderViewModel @Inject constructor( //Used to recreate a new fragment preserving viewport state private lateinit var pdfDocumentBeforeFragmentDestruction: PdfDocument - var annotationMaxSideSize = 0 + override var annotationMaxSideSize = 0 - var toolColors: MutableMap = mutableMapOf() + override var toolColors: MutableMap = mutableMapOf() var changedColorForTool: AnnotationTool? = null var activeLineWidth: Float = 0.0f var activeEraserSize: Float = 0.0f @@ -310,7 +310,7 @@ class PdfReaderViewModel @Inject constructor( .launchIn(viewModelScope) } - fun init( + override fun init( uri: Uri, annotationMaxSideSize: Int, containerId: Int, @@ -1376,7 +1376,7 @@ class PdfReaderViewModel @Inject constructor( } } - fun annotation(key: AnnotationKey): org.zotero.android.pdf.data.Annotation? { + override fun annotation(key: AnnotationKey): org.zotero.android.pdf.data.Annotation? { when (key.type) { AnnotationKey.Kind.database -> { return this.databaseAnnotations!!.where().key(key.key).findFirst() @@ -1567,7 +1567,7 @@ class PdfReaderViewModel @Inject constructor( return oldComment == newComment } - fun selectAnnotation(key: AnnotationKey) { + override fun selectAnnotation(key: AnnotationKey) { if (!viewState.sidebarEditingEnabled && key != viewState.selectedAnnotationKey) { _select(key = key, didSelectInDocument = false) } @@ -1666,7 +1666,7 @@ class PdfReaderViewModel @Inject constructor( .build() } - fun loadPreviews(keys: List) { + override fun loadPreviews(keys: List) { if (keys.isEmpty()) else { return } @@ -1687,7 +1687,7 @@ class PdfReaderViewModel @Inject constructor( } } - fun onSearch(text: String) { + override fun onSearch(text: String) { updateState { copy(searchTerm = text) } @@ -1808,7 +1808,7 @@ class PdfReaderViewModel @Inject constructor( return hasTag && hasColor } - fun showFilterPopup() { + override fun showFilterPopup() { val colors = mutableSetOf() val tags = mutableSetOf() @@ -1868,7 +1868,7 @@ class PdfReaderViewModel @Inject constructor( triggerEffect(PdfReaderViewEffect.ShowPdfSettings) } - fun showToolOptions() { + override fun showToolOptions() { val tool = this.activeAnnotationTool ?: return val colorHex = this.toolColors[tool] @@ -2007,7 +2007,7 @@ class PdfReaderViewModel @Inject constructor( fragment.exitCurrentlyActiveMode() } } - fun toggle(tool: AnnotationTool) { + override fun toggle(tool: AnnotationTool) { val color = this.toolColors[tool] toggle(annotationTool = tool, color = color) } @@ -2146,29 +2146,29 @@ class PdfReaderViewModel @Inject constructor( ) } - val activeAnnotationTool: AnnotationTool? get() { + override val activeAnnotationTool: AnnotationTool? get() { return this.fragment.activeAnnotationTool } - fun canUndo() : Boolean { + override fun canUndo() : Boolean { return this.fragment.undoManager.canUndo() } - fun canRedo() : Boolean { + override fun canRedo() : Boolean { return this.fragment.undoManager.canRedo() } - fun onUndoClick() { + override fun onUndoClick() { this.fragment.undoManager.undo() triggerEffect(PdfReaderViewEffect.ScreenRefresh) } - fun onRedoClick() { + override fun onRedoClick() { this.fragment.undoManager.redo() triggerEffect(PdfReaderViewEffect.ScreenRefresh) } - fun onCloseClick() { + override fun onCloseClick() { toggleToolbarButton() } @@ -2437,7 +2437,7 @@ class PdfReaderViewModel @Inject constructor( updateAnnotationToolDrawColorAndSize(tool, drawColor = drawColor) } - fun onCommentTextChange(annotationKey: String, comment: String) { + override fun onCommentTextChange(annotationKey: String, comment: String) { updateState { copy(commentFocusText = comment) } @@ -2458,7 +2458,7 @@ class PdfReaderViewModel @Inject constructor( update(annotation = annotation, contents = htmlComment, document = this.document) } - fun onCommentFocusFieldChange(annotationKey: String) { + override fun onCommentFocusFieldChange(annotationKey: String) { val key = AnnotationKey(key = annotationKey, type = AnnotationKey.Kind.database) val annotation = annotation(key) @@ -2473,7 +2473,7 @@ class PdfReaderViewModel @Inject constructor( } } - fun onTagsClicked(annotation: org.zotero.android.pdf.data.Annotation) { + override fun onTagsClicked(annotation: org.zotero.android.pdf.data.Annotation) { // if (!annotation.isAuthor(viewState.userId)) { // return // } @@ -2514,7 +2514,7 @@ class PdfReaderViewModel @Inject constructor( update(annotation = annotation, lineWidth = lineWidth, document = this.document) } - fun onMoreOptionsForItemClicked() { + override fun onMoreOptionsForItemClicked() { ScreenArguments.pdfAnnotationMoreArgs = PdfAnnotationMoreArgs( selectedAnnotation = selectedAnnotation, userId = viewState.userId, diff --git a/app/src/main/java/org/zotero/android/pdf/reader/PdfSidebarSearchBar.kt b/app/src/main/java/org/zotero/android/pdf/reader/PdfSidebarSearchBar.kt index bc8f1244..be265e41 100644 --- a/app/src/main/java/org/zotero/android/pdf/reader/PdfSidebarSearchBar.kt +++ b/app/src/main/java/org/zotero/android/pdf/reader/PdfSidebarSearchBar.kt @@ -16,10 +16,9 @@ import org.zotero.android.uicomponents.theme.CustomTheme @Composable internal fun PdfSidebarSearchBar( - viewState: PdfReaderViewState, - viewModel: PdfReaderViewModel + searchValue: String, + onSearch: (String) -> Unit, ) { - val searchValue = viewState.searchTerm var searchBarTextFieldState by remember { mutableStateOf( TextFieldValue( @@ -29,7 +28,7 @@ internal fun PdfSidebarSearchBar( } val searchBarOnInnerValueChanged: (TextFieldValue) -> Unit = { searchBarTextFieldState = it - viewModel.onSearch(it.text) + onSearch(it.text) } SearchBar( modifier = Modifier.padding(horizontal = 16.dp), diff --git a/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebar.kt b/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebar.kt index 67a1ba02..ee668212 100644 --- a/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebar.kt +++ b/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebar.kt @@ -24,7 +24,7 @@ import androidx.compose.ui.unit.dp import org.zotero.android.architecture.ui.CustomLayoutSize import org.zotero.android.database.objects.AnnotationType import org.zotero.android.pdf.reader.PdfReaderBottomPanel -import org.zotero.android.pdf.reader.PdfReaderViewModel +import org.zotero.android.pdf.reader.PdfReaderVMInterface import org.zotero.android.pdf.reader.PdfReaderViewState import org.zotero.android.pdf.reader.PdfSidebarSearchBar import org.zotero.android.uicomponents.foundation.safeClickable @@ -32,11 +32,11 @@ import org.zotero.android.uicomponents.theme.CustomTheme @Composable internal fun PdfReaderSidebar( + vMInterface: PdfReaderVMInterface, viewState: PdfReaderViewState, layoutType: CustomLayoutSize.LayoutType, - viewModel: PdfReaderViewModel, focusRequester: FocusRequester, - lazyListState: LazyListState + lazyListState: LazyListState, ) { Box( modifier = Modifier @@ -49,16 +49,19 @@ internal fun PdfReaderSidebar( .padding(bottom = layoutType.calculateAllItemsBottomPanelHeight()) ) { Spacer(modifier = Modifier.height(16.dp)) - PdfSidebarSearchBar(viewState = viewState, viewModel = viewModel) + PdfSidebarSearchBar( + searchValue = viewState.searchTerm, + onSearch = vMInterface::onSearch, + ) Spacer(modifier = Modifier.height(8.dp)) LazyColumn( state = lazyListState, verticalArrangement = Arrangement.Absolute.spacedBy(13.dp), ) { itemsIndexed( - items = viewModel.viewState.sortedKeys + items = viewState.sortedKeys, ) { _, key -> - val annotation = viewModel.annotation(key) ?: return@itemsIndexed + val annotation = vMInterface.annotation(key) ?: return@itemsIndexed val isSelected = viewState.isAnnotationSelected(annotation.key) val horizontalPadding = if (isSelected) 13.dp else 16.dp var rowModifier: Modifier = Modifier @@ -79,16 +82,16 @@ internal fun PdfReaderSidebar( .safeClickable( interactionSource = remember { MutableInteractionSource() }, indication = null, - onClick = { viewModel.selectAnnotation(key) }, + onClick = { vMInterface.selectAnnotation(key) }, ) ) { val annotationColor = Color(android.graphics.Color.parseColor(annotation.displayColor)) val loadPreview = { val preview = - viewModel.annotationPreviewMemoryCache.getBitmap(annotation.key) + vMInterface.annotationPreviewMemoryCache.getBitmap(annotation.key) if (preview == null) { - viewModel.loadPreviews(listOf(annotation.key)) + vMInterface.loadPreviews(listOf(annotation.key)) } preview } @@ -97,7 +100,7 @@ internal fun PdfReaderSidebar( annotation = annotation, annotationColor = annotationColor, viewState = viewState, - viewModel = viewModel, + vMInterface = vMInterface, ) SidebarDivider() // Spacer(modifier = Modifier.height(8.dp)) @@ -105,7 +108,7 @@ internal fun PdfReaderSidebar( when (annotation.type) { AnnotationType.note -> SidebarNoteRow( annotation = annotation, - viewModel = viewModel, + vMInterface = vMInterface, viewState = viewState, focusRequester = focusRequester, ) @@ -113,24 +116,24 @@ internal fun PdfReaderSidebar( AnnotationType.highlight -> SidebarHighlightRow( annotation = annotation, annotationColor = annotationColor, - viewModel = viewModel, + vMInterface = vMInterface, viewState = viewState, focusRequester = focusRequester, ) AnnotationType.ink -> SidebarInkRow( - viewModel = viewModel, + vMInterface = vMInterface, viewState = viewState, annotation = annotation, loadPreview = loadPreview, ) AnnotationType.image -> SidebarImageRow( - viewModel = viewModel, - viewState = viewState, annotation = annotation, loadPreview = loadPreview, focusRequester = focusRequester, + vMInterface = vMInterface, + viewState = viewState, ) } } @@ -139,7 +142,7 @@ internal fun PdfReaderSidebar( } PdfReaderBottomPanel( layoutType = layoutType, - viewModel = viewModel, + vMInterface = vMInterface, viewState = viewState ) } diff --git a/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebarRowParts.kt b/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebarRowParts.kt index aa1269c8..9119c4c6 100644 --- a/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebarRowParts.kt +++ b/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebarRowParts.kt @@ -35,7 +35,7 @@ import org.zotero.android.R import org.zotero.android.androidx.content.pxToDp import org.zotero.android.database.objects.AnnotationType import org.zotero.android.pdf.data.Annotation -import org.zotero.android.pdf.reader.PdfReaderViewModel +import org.zotero.android.pdf.reader.PdfReaderVMInterface import org.zotero.android.pdf.reader.PdfReaderViewState import org.zotero.android.uicomponents.Drawables import org.zotero.android.uicomponents.Strings @@ -45,7 +45,7 @@ import org.zotero.android.uicomponents.theme.CustomTheme @Composable internal fun SidebarHeaderSection( - viewModel: PdfReaderViewModel, + vMInterface: PdfReaderVMInterface, viewState: PdfReaderViewState, annotation: Annotation, annotationColor: Color, @@ -83,7 +83,7 @@ internal fun SidebarHeaderSection( modifier = Modifier .size(22.dp) .safeClickable( - onClick = { viewModel.onMoreOptionsForItemClicked() }, + onClick = vMInterface::onMoreOptionsForItemClicked, interactionSource = remember { MutableInteractionSource() }, indication = rememberRipple(bounded = false) ), @@ -97,25 +97,29 @@ internal fun SidebarHeaderSection( @Composable internal fun SidebarTagsAndCommentsSection( - annotation: Annotation, - viewModel: PdfReaderViewModel, + vMInterface: PdfReaderVMInterface, viewState: PdfReaderViewState, + annotation: Annotation, focusRequester: FocusRequester, shouldAddTopPadding: Boolean, ) { SidebarCommentSection( - viewModel = viewModel, annotation = annotation, - viewState = viewState, focusRequester = focusRequester, - shouldAddTopPadding = shouldAddTopPadding + shouldAddTopPadding = shouldAddTopPadding, + vMInterface = vMInterface, + viewState = viewState, + ) + SidebarTagsSection( + annotation = annotation, + vMInterface = vMInterface, + viewState = viewState, ) - SidebarTagsSection(viewModel = viewModel, viewState = viewState, annotation = annotation) } @Composable private fun SidebarCommentSection( - viewModel: PdfReaderViewModel, + vMInterface: PdfReaderVMInterface, viewState: PdfReaderViewState, annotation: Annotation, shouldAddTopPadding: Boolean, @@ -129,7 +133,7 @@ private fun SidebarCommentSection( .padding(top = if (shouldAddTopPadding) 8.dp else 0.dp) .onFocusChanged { if (it.hasFocus) { - viewModel.onCommentFocusFieldChange(annotation.key) + vMInterface.onCommentFocusFieldChange(annotation.key) } }, value = if (annotation.key == viewState.commentFocusKey) { @@ -142,7 +146,7 @@ private fun SidebarCommentSection( hintColor = CustomTheme.colors.zoteroDefaultBlue, focusRequester = focusRequester, ignoreTabsAndCaretReturns = false, - onValueChange = { viewModel.onCommentTextChange(annotationKey = annotation.key, it) }) + onValueChange = { vMInterface.onCommentTextChange(annotationKey = annotation.key, it) }) } else if (annotation.comment.isNotBlank()) { Text( modifier = Modifier @@ -158,9 +162,9 @@ private fun SidebarCommentSection( @Composable internal fun SidebarTagsSection( - viewModel: PdfReaderViewModel, - viewState: PdfReaderViewState, annotation: Annotation, + vMInterface: PdfReaderVMInterface, + viewState: PdfReaderViewState, ) { val isSelected = viewState.isAnnotationSelected(annotation.key) val areTagsPresent = annotation.tags.isNotEmpty() @@ -173,12 +177,11 @@ internal fun SidebarTagsSection( .clickable( interactionSource = remember { MutableInteractionSource() }, indication = rememberRipple(bounded = true), - onClick = { viewModel.onTagsClicked(annotation) } + onClick = { vMInterface.onTagsClicked(annotation) } ) .sectionVerticalPadding() .fillMaxWidth() .height(22.dp) - , ) { if (areTagsPresent) { Text( @@ -230,7 +233,7 @@ internal fun SidebarHighlightedTextSection( @Composable internal fun SidebarImageSection( loadPreview: () -> Bitmap?, - viewModel: PdfReaderViewModel + vMInterface: PdfReaderVMInterface, ) { val cachedBitmap = loadPreview() if (cachedBitmap != null) { @@ -239,7 +242,7 @@ internal fun SidebarImageSection( .sectionHorizontalPadding() .sectionVerticalPadding() .fillMaxWidth() - .heightIn(max = viewModel.annotationMaxSideSize.pxToDp()), + .heightIn(max = vMInterface.annotationMaxSideSize.pxToDp()), bitmap = cachedBitmap.asImageBitmap(), contentDescription = null, ) diff --git a/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebarRows.kt b/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebarRows.kt index 3472e3ef..b4008ae5 100644 --- a/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebarRows.kt +++ b/app/src/main/java/org/zotero/android/pdf/reader/sidebar/PdfReaderSidebarRows.kt @@ -5,26 +5,26 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.graphics.Color import org.zotero.android.pdf.data.Annotation -import org.zotero.android.pdf.reader.PdfReaderViewModel +import org.zotero.android.pdf.reader.PdfReaderVMInterface import org.zotero.android.pdf.reader.PdfReaderViewState @Composable internal fun SidebarImageRow( - viewModel: PdfReaderViewModel, viewState: PdfReaderViewState, + vMInterface: PdfReaderVMInterface, annotation: Annotation, loadPreview: () -> Bitmap?, focusRequester: FocusRequester, ) { SidebarImageSection( loadPreview = loadPreview, - viewModel = viewModel + vMInterface = vMInterface, ) SidebarDivider() SidebarTagsAndCommentsSection( - annotation = annotation, - viewModel = viewModel, + vMInterface = vMInterface, viewState = viewState, + annotation = annotation, focusRequester = focusRequester, shouldAddTopPadding = true, ) @@ -32,26 +32,26 @@ internal fun SidebarImageRow( @Composable internal fun SidebarInkRow( - viewModel: PdfReaderViewModel, + vMInterface: PdfReaderVMInterface, viewState: PdfReaderViewState, annotation: Annotation, loadPreview: () -> Bitmap?, ) { - SidebarImageSection(loadPreview, viewModel) - SidebarTagsSection(viewModel = viewModel, viewState = viewState, annotation = annotation) + SidebarImageSection(loadPreview = loadPreview, vMInterface = vMInterface) + SidebarTagsSection(vMInterface = vMInterface, viewState = viewState, annotation = annotation) } @Composable internal fun SidebarNoteRow( annotation: Annotation, - viewModel: PdfReaderViewModel, + vMInterface: PdfReaderVMInterface, viewState: PdfReaderViewState, focusRequester: FocusRequester, ) { SidebarTagsAndCommentsSection( annotation = annotation, - viewModel = viewModel, viewState = viewState, + vMInterface = vMInterface, focusRequester = focusRequester, shouldAddTopPadding = true, ) @@ -60,8 +60,8 @@ internal fun SidebarNoteRow( @Composable internal fun SidebarHighlightRow( annotation: Annotation, - viewModel: PdfReaderViewModel, viewState: PdfReaderViewState, + vMInterface: PdfReaderVMInterface, annotationColor: Color, focusRequester: FocusRequester, ) { @@ -69,8 +69,8 @@ internal fun SidebarHighlightRow( SidebarTagsAndCommentsSection( annotation = annotation, - viewModel = viewModel, viewState = viewState, + vMInterface = vMInterface, focusRequester = focusRequester, shouldAddTopPadding = false, ) diff --git a/buildSrc/src/main/kotlin/BuildConfig.kt b/buildSrc/src/main/kotlin/BuildConfig.kt index 614668fe..36d7927e 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 = 86 // Must be updated on every build + val versionCode = 87 // Must be updated on every build val version = Version( major = 1, minor = 0,