Skip to content

Commit 1efbc47

Browse files
committed
Merge branch 'release/1.16.1'
2 parents 5d9915a + 3a0682a commit 1efbc47

File tree

6 files changed

+36
-135
lines changed

6 files changed

+36
-135
lines changed

README-CHANGES.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@
651651
</c:change>
652652
</c:changes>
653653
</c:release>
654-
<c:release date="2025-05-20T08:40:27+00:00" is-open="true" ticket-system="org.lyrasis.jira" version="1.16.0">
654+
<c:release date="2025-05-28T09:56:23+00:00" is-open="true" ticket-system="org.lyrasis.jira" version="1.16.1">
655655
<c:changes>
656656
<c:change date="2025-04-28T00:00:00+00:00" summary="Completely rewrite all catalog views.">
657657
<c:tickets>
@@ -668,7 +668,7 @@
668668
<c:ticket id="PP-1855"/>
669669
</c:tickets>
670670
</c:change>
671-
<c:change date="2025-05-20T08:40:27+00:00" summary="New book details page.">
671+
<c:change date="2025-05-20T00:00:00+00:00" summary="New book details page.">
672672
<c:tickets>
673673
<c:ticket id="PP-1087"/>
674674
</c:tickets>

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ POM_SCM_CONNECTION=scm:git:git://github.com/ThePalaceProject/android-core
1111
POM_SCM_DEV_CONNECTION=scm:git:ssh://[email protected]/ThePalaceProject/android-core
1212
POM_SCM_URL=http://github.com/ThePalaceProject/android-core
1313
POM_URL=http://github.com/ThePalaceProject/android-core
14-
VERSION_NAME=1.16.0-SNAPSHOT
14+
VERSION_NAME=1.16.1
1515
VERSION_CODE_BASE=70000
1616

1717
android.useAndroidX=true

simplified-ui/src/main/java/org/nypl/simplified/ui/catalog/CatalogFeedPagingDataAdapter.kt

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class CatalogFeedPagingDataAdapter(
6565
private val onBookViewerOpen: (Book, BookFormat) -> Unit,
6666
private val onBookDelete: (CatalogBookStatus<*>) -> Unit,
6767
private val onShowTaskError: (TaskResult.Failure<*>) -> Unit,
68-
) : PagingDataAdapter<FeedEntry, CatalogFeedPagingDataAdapter.ViewHolder>(org.nypl.simplified.ui.catalog.CatalogFeedPagingDataAdapter.Companion.diffCallback) {
68+
) : PagingDataAdapter<FeedEntry, CatalogFeedPagingDataAdapter.ViewHolder>(diffCallback) {
6969

7070
companion object {
7171
private val loanEndFormatter =
@@ -785,26 +785,6 @@ class CatalogFeedPagingDataAdapter(
785785
this.idleButtons.removeAllViews()
786786
}
787787

788-
/**
789-
* XXX: This information really should be available somewhere else. This was ported from
790-
* existing code.
791-
*/
792-
793-
private fun getLoanDurationText(
794-
book: Book
795-
): String {
796-
val endDate = this.getLoanDuration(book)
797-
return if (endDate != null) {
798-
CatalogBookAvailabilityStrings.intervalStringLoanDuration(
799-
this.view.context.resources,
800-
DateTime.now(),
801-
endDate
802-
)
803-
} else {
804-
""
805-
}
806-
}
807-
808788
private fun getLoanDuration(
809789
book: Book
810790
): DateTime? {

simplified-ui/src/main/java/org/nypl/simplified/ui/catalog/CatalogFeedViewDetails2.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class CatalogFeedViewDetails2(
9191
private val covers: BookCoverProviderType,
9292
private val onToolbarBackPressed: () -> Unit,
9393
private val onShowErrorDetails: (TaskResult.Failure<*>) -> Unit,
94+
private val onBookSAMLDownloadRequested: (CatalogBookStatus<DownloadWaitingForExternalAuthentication>) -> Unit,
9495
private val onBookBorrowRequested: (CatalogBorrowParameters) -> Unit,
9596
private val onBookBorrowCancelRequested: (CatalogBookStatus<*>) -> Unit,
9697
private val onBookCanBeRevoked: (CatalogBookStatus<*>) -> Boolean,
@@ -761,6 +762,7 @@ class CatalogFeedViewDetails2(
761762
container: ViewGroup,
762763
covers: BookCoverProviderType,
763764
onShowErrorDetails: (TaskResult.Failure<*>) -> Unit,
765+
onBookSAMLDownloadRequested: (CatalogBookStatus<DownloadWaitingForExternalAuthentication>) -> Unit,
764766
onBookBorrowRequested: (CatalogBorrowParameters) -> Unit,
765767
onBookBorrowCancelRequested: (CatalogBookStatus<*>) -> Unit,
766768
onBookCanBeRevoked: (CatalogBookStatus<*>) -> Boolean,
@@ -777,6 +779,7 @@ class CatalogFeedViewDetails2(
777779
layoutInflater = layoutInflater,
778780
covers = covers,
779781
onToolbarBackPressed = onToolbarBackPressed,
782+
onBookSAMLDownloadRequested = onBookSAMLDownloadRequested,
780783
onShowErrorDetails = onShowErrorDetails,
781784
onBookBorrowRequested = onBookBorrowRequested,
782785
onBookBorrowCancelRequested = onBookBorrowCancelRequested,
@@ -1376,6 +1379,8 @@ class CatalogFeedViewDetails2(
13761379
this.setProgress(0.0)
13771380
}
13781381
}
1382+
1383+
this.onBookSAMLDownloadRequested(status)
13791384
}
13801385

13811386
private fun onBookStatusDownloadExternalAuthenticationInProgress(

simplified-ui/src/main/java/org/nypl/simplified/ui/catalog/CatalogFragment.kt

Lines changed: 26 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -36,14 +36,6 @@ import org.nypl.simplified.feeds.api.FeedEntry
3636
import org.nypl.simplified.feeds.api.FeedFacet
3737
import org.nypl.simplified.feeds.api.FeedLoaderType
3838
import org.nypl.simplified.feeds.api.FeedSearch
39-
import org.nypl.simplified.opds.core.OPDSAvailabilityHeld
40-
import org.nypl.simplified.opds.core.OPDSAvailabilityHeldReady
41-
import org.nypl.simplified.opds.core.OPDSAvailabilityHoldable
42-
import org.nypl.simplified.opds.core.OPDSAvailabilityLoanable
43-
import org.nypl.simplified.opds.core.OPDSAvailabilityLoaned
44-
import org.nypl.simplified.opds.core.OPDSAvailabilityMatcherType
45-
import org.nypl.simplified.opds.core.OPDSAvailabilityOpenAccess
46-
import org.nypl.simplified.opds.core.OPDSAvailabilityRevoked
4739
import org.nypl.simplified.profiles.controller.api.ProfileFeedRequest
4840
import org.nypl.simplified.profiles.controller.api.ProfilesControllerType
4941
import org.nypl.simplified.taskrecorder.api.TaskResult
@@ -84,6 +76,7 @@ import org.thepalaceproject.opds.client.OPDSState.LoadedFeedWithoutGroups
8476
import org.thepalaceproject.opds.client.OPDSState.Loading
8577
import java.net.URI
8678
import java.util.concurrent.TimeUnit
79+
import java.util.concurrent.atomic.AtomicReference
8780

8881
/**
8982
* The fragment used for the catalog.
@@ -316,20 +309,21 @@ sealed class CatalogFragment : Fragment(), MainBackButtonConsumerType {
316309
) {
317310
val view =
318311
CatalogFeedViewDetails2.create(
319-
layoutInflater = this.layoutInflater,
320-
screenSize = this.screenSize,
321312
container = this.contentContainer,
322313
covers = this.covers,
323-
onShowErrorDetails = this::onShowErrorDetails,
324-
onBookBorrowRequested = this::onBookBorrowRequested,
314+
layoutInflater = this.layoutInflater,
325315
onBookBorrowCancelRequested = this::onBookBorrowCancelRequested,
316+
onBookBorrowRequested = this::onBookBorrowRequested,
326317
onBookCanBeRevoked = this::onBookCanBeRevoked,
327318
onBookPreviewOpenRequested = this::onBookPreviewOpenRequested,
328319
onBookRevokeRequested = this::onBookRevokeRequested,
320+
onBookSAMLDownloadRequested = this::onBookSAMLDownloadRequested,
321+
onBookSelected = this::onBookSelected,
329322
onBookViewerOpen = this::onBookViewerOpen,
330-
onToolbarBackPressed = this::onToolbarBackPressed,
331323
onFeedSelected = this::onFeedSelected,
332-
onBookSelected = this::onBookSelected
324+
onShowErrorDetails = this::onShowErrorDetails,
325+
onToolbarBackPressed = this::onToolbarBackPressed,
326+
screenSize = this.screenSize
333327
)
334328

335329
when (val entry = this.opdsClient.entry.get()) {
@@ -373,8 +367,6 @@ sealed class CatalogFragment : Fragment(), MainBackButtonConsumerType {
373367
}
374368
}
375369

376-
this.onStateChangeToDetailsConfigureToolbar(newState, view)
377-
378370
/*
379371
* Subscribe to the entry on the OPDS client. We'll receive the initial
380372
* entry on subscription.
@@ -478,25 +470,6 @@ sealed class CatalogFragment : Fragment(), MainBackButtonConsumerType {
478470
}
479471
}
480472

481-
private fun onStateChangeToDetailsConfigureToolbar(
482-
newState: LoadedFeedEntry,
483-
view: CatalogFeedViewDetails2
484-
) {
485-
try {
486-
val account =
487-
this.profiles.profileCurrent()
488-
.account(newState.request.entry.accountID)
489-
490-
val title =
491-
when (val e = newState.request.entry) {
492-
is FeedEntry.FeedEntryCorrupt -> ""
493-
is FeedEntry.FeedEntryOPDS -> e.feedEntry.title
494-
}
495-
} catch (e: Throwable) {
496-
// Nothing sensible we can do about this.
497-
}
498-
}
499-
500473
private fun onBookBorrowRequested(
501474
parameters: CatalogBorrowParameters
502475
) {
@@ -577,64 +550,6 @@ sealed class CatalogFragment : Fragment(), MainBackButtonConsumerType {
577550
}
578551
}
579552

580-
/**
581-
* Determine whether or not a book can be "deleted".
582-
*
583-
* A book can be deleted if:
584-
*
585-
* * It is loaned, downloaded, and not revocable (because otherwise, a revocation is needed).
586-
* * It is loanable, but there is a book database entry for it
587-
* * It is open access but there is a book database entry for it
588-
*/
589-
590-
private fun onBookCanBeDeleted(
591-
status: CatalogBookStatus<*>
592-
): Boolean {
593-
return try {
594-
val services =
595-
Services.serviceDirectory()
596-
val profiles =
597-
services.requireService(ProfilesControllerType::class.java)
598-
val book =
599-
status.book
600-
val profile =
601-
profiles.profileCurrent()
602-
val account =
603-
profile.account(book.account)
604-
605-
return if (account.bookDatabase.books().contains(book.id)) {
606-
book.entry.availability.matchAvailability(
607-
object : OPDSAvailabilityMatcherType<Boolean, Exception> {
608-
override fun onHeldReady(availability: OPDSAvailabilityHeldReady): Boolean =
609-
false
610-
611-
override fun onHeld(availability: OPDSAvailabilityHeld): Boolean =
612-
false
613-
614-
override fun onHoldable(availability: OPDSAvailabilityHoldable): Boolean =
615-
false
616-
617-
override fun onLoaned(availability: OPDSAvailabilityLoaned): Boolean =
618-
availability.revoke.isNone && book.isDownloaded
619-
620-
override fun onLoanable(availability: OPDSAvailabilityLoanable): Boolean =
621-
true
622-
623-
override fun onOpenAccess(availability: OPDSAvailabilityOpenAccess): Boolean =
624-
true
625-
626-
override fun onRevoked(availability: OPDSAvailabilityRevoked): Boolean =
627-
false
628-
})
629-
} else {
630-
false
631-
}
632-
} catch (e: Throwable) {
633-
this.logger.debug("could not determine if the book could be deleted: ", e)
634-
false
635-
}
636-
}
637-
638553
private fun onBookCanBeRevoked(
639554
status: CatalogBookStatus<*>
640555
): Boolean {
@@ -702,12 +617,6 @@ sealed class CatalogFragment : Fragment(), MainBackButtonConsumerType {
702617
)
703618
}
704619

705-
private fun onBookResetStatusInitial(
706-
status: CatalogBookStatus<*>
707-
) {
708-
// XXX: Unclear what the point of this method ever was...
709-
}
710-
711620
private fun onBookViewerOpen(
712621
book: Book,
713622
bookFormat: BookFormat
@@ -725,12 +634,6 @@ sealed class CatalogFragment : Fragment(), MainBackButtonConsumerType {
725634
)
726635
}
727636

728-
private fun onBookReserveRequested(
729-
parameters: CatalogBorrowParameters
730-
) {
731-
this.onBookBorrowRequested(parameters)
732-
}
733-
734637
private fun onStateChangedToGroups(
735638
newState: LoadedFeedWithGroups
736639
) {
@@ -860,8 +763,8 @@ sealed class CatalogFragment : Fragment(), MainBackButtonConsumerType {
860763
) {
861764
val feedHandle =
862765
newState.handle
863-
val feedPosition =
864-
feedHandle.scrollPositionGet()
766+
val feedPositionInitial =
767+
AtomicReference(feedHandle.scrollPositionGet())
865768
val feed =
866769
feedHandle.feed()
867770

@@ -931,7 +834,7 @@ sealed class CatalogFragment : Fragment(), MainBackButtonConsumerType {
931834
val position =
932835
linearLayoutManager.findFirstVisibleItemPosition()
933836

934-
// logger.trace("Saving scroll position {}", position)
837+
logger.trace("Saving scroll position {}", position)
935838
feedHandle.scrollPositionSave(position)
936839
}
937840
})
@@ -995,11 +898,24 @@ sealed class CatalogFragment : Fragment(), MainBackButtonConsumerType {
995898
this.switchView(view)
996899

997900
/*
998-
* Set up a listener to restore the scroll position.
901+
* Set up a listener to restore the scroll position. This works around multiple pieces of
902+
* Android brokenness: Restoring the scroll position when we navigate to a book detail page
903+
* and back again, and also properly handling scrolling when new feed pages come in. With
904+
* the current RecyclerView, not explicitly storing and restoring the scroll position results
905+
* in all kinds of scroll issues when new pages are loaded.
999906
*/
1000907

1001908
feedAdapter.addOnPagesUpdatedListener {
1002-
// this.logger.trace("Restoring scroll position {}", feedPosition)
909+
val feedPosition: Int
910+
val initial = feedPositionInitial.get()
911+
if (initial == null) {
912+
feedPosition = feedHandle.scrollPositionGet()
913+
// this.logger.trace("Restoring scroll position {}", feedPosition)
914+
} else {
915+
feedPositionInitial.set(null)
916+
feedPosition = initial
917+
// this.logger.trace("Restoring scroll position (initial) {}", feedPosition)
918+
}
1003919
view.listView.scrollToPosition(feedPosition)
1004920
}
1005921
}

simplified-ui/src/main/java/org/nypl/simplified/ui/catalog/CatalogToolbar.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ class CatalogToolbar(
111111
this.searchText.visibility = View.VISIBLE
112112
this.text.visibility = View.INVISIBLE
113113

114-
this.text.postDelayed({ this.text.requestFocus() }, 100)
114+
this.text.postDelayed({ this.searchText.requestFocus() }, 100)
115115
this.text.postDelayed({ this.keyboardShow() }, 100)
116116
}
117117

0 commit comments

Comments
 (0)