mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Add new action bar at bottom of iOS reader that shows when user reaches end
This commit is contained in:
parent
fe62f24d85
commit
8eb204b4c0
3 changed files with 81 additions and 9 deletions
|
|
@ -16,6 +16,7 @@ struct WebReader: PlatformViewRepresentable {
|
|||
@Binding var showNavBarActionID: UUID?
|
||||
@Binding var shareActionID: UUID?
|
||||
@Binding var annotation: String
|
||||
@Binding var showBottomBar: Bool
|
||||
|
||||
func makeCoordinator() -> WebReaderCoordinator {
|
||||
WebReaderCoordinator()
|
||||
|
|
@ -70,6 +71,10 @@ struct WebReader: PlatformViewRepresentable {
|
|||
context.coordinator.linkHandler = openLinkAction
|
||||
context.coordinator.webViewActionHandler = webViewActionHandler
|
||||
context.coordinator.updateNavBarVisibilityRatio = navBarVisibilityRatioUpdater
|
||||
context.coordinator.updateShowBottomBar = { newValue in
|
||||
self.showBottomBar = newValue
|
||||
}
|
||||
|
||||
context.coordinator.articleContentID = articleContent.id
|
||||
loadContent(webView: webView)
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ struct WebReaderContainerView: View {
|
|||
@State var showNavBarActionID: UUID?
|
||||
@State var shareActionID: UUID?
|
||||
@State var annotation = String()
|
||||
@State var showBottomBar: Bool = false
|
||||
|
||||
@EnvironmentObject var dataService: DataService
|
||||
@EnvironmentObject var audioController: AudioController
|
||||
|
|
@ -119,6 +120,38 @@ struct WebReaderContainerView: View {
|
|||
}
|
||||
#endif
|
||||
|
||||
var bottomButtons: some View {
|
||||
HStack(alignment: .center) {
|
||||
Button(action: archive, label: {
|
||||
Image(systemName: item.isArchived ? "tray.and.arrow.down" : "archivebox")
|
||||
}).frame(width: 48, height: 48)
|
||||
.padding(.leading, 8)
|
||||
Divider().opacity(0.8)
|
||||
|
||||
Button(action: delete, label: {
|
||||
Image(systemName: "trash")
|
||||
}).frame(width: 48, height: 48)
|
||||
Divider().opacity(0.8)
|
||||
|
||||
Button(action: editLabels, label: {
|
||||
Image(systemName: "tag")
|
||||
}).frame(width: 48, height: 48)
|
||||
Divider().opacity(0.8)
|
||||
|
||||
Button(action: share, label: {
|
||||
Image(systemName: "square.and.arrow.up")
|
||||
}).frame(width: 48, height: 48)
|
||||
|
||||
// TODO: We don't have a single note function yet
|
||||
// Divider()
|
||||
//
|
||||
// Button(action: addNote, label: {
|
||||
// Image(systemName: "note")
|
||||
// }).frame(width: 48, height: 48)
|
||||
.padding(.trailing, 8)
|
||||
}.foregroundColor(.appGrayTextContrast)
|
||||
}
|
||||
|
||||
var navBar: some View {
|
||||
HStack(alignment: .center) {
|
||||
#if os(iOS)
|
||||
|
|
@ -159,16 +192,12 @@ struct WebReaderContainerView: View {
|
|||
label: { Label("Edit Title/Description", systemImage: "textbox") }
|
||||
)
|
||||
Button(
|
||||
action: { showLabelsModal = true },
|
||||
action: editLabels,
|
||||
label: { Label("Edit Labels", systemImage: "tag") }
|
||||
)
|
||||
Button(
|
||||
action: {
|
||||
dataService.archiveLink(objectID: item.objectID, archived: !item.isArchived)
|
||||
#if os(iOS)
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
#endif
|
||||
Snackbar.show(message: !item.isArchived ? "Link archived" : "Link moved to Inbox")
|
||||
archive()
|
||||
},
|
||||
label: {
|
||||
Label(
|
||||
|
|
@ -184,11 +213,11 @@ struct WebReaderContainerView: View {
|
|||
label: { Label("Reset Read Location", systemImage: "arrow.counterclockwise.circle") }
|
||||
)
|
||||
Button(
|
||||
action: { shareActionID = UUID() },
|
||||
action: share,
|
||||
label: { Label("Share Original", systemImage: "square.and.arrow.up") }
|
||||
)
|
||||
Button(
|
||||
action: { showDeleteConfirmation = true },
|
||||
action: delete,
|
||||
label: { Label("Delete", systemImage: "trash") }
|
||||
)
|
||||
}
|
||||
|
|
@ -268,7 +297,8 @@ struct WebReaderContainerView: View {
|
|||
annotationSaveTransactionID: $annotationSaveTransactionID,
|
||||
showNavBarActionID: $showNavBarActionID,
|
||||
shareActionID: $shareActionID,
|
||||
annotation: $annotation
|
||||
annotation: $annotation,
|
||||
showBottomBar: $showBottomBar
|
||||
)
|
||||
.onTapGesture {
|
||||
withAnimation {
|
||||
|
|
@ -319,6 +349,14 @@ struct WebReaderContainerView: View {
|
|||
VStack(spacing: 0) {
|
||||
navBar
|
||||
Spacer()
|
||||
bottomButtons
|
||||
.frame(height: 48)
|
||||
.background(Color.isDarkMode ? Color(red: 44 / 255.0, green: 44 / 255.0, blue: 46 / 255.0) : Color.white)
|
||||
.cornerRadius(6)
|
||||
.padding(.bottom, 34)
|
||||
.shadow(color: .gray.opacity(0.13), radius: 8, x: 0, y: 4)
|
||||
|
||||
.offset(y: showBottomBar ? 0.0 : 120.0)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
@ -336,4 +374,26 @@ struct WebReaderContainerView: View {
|
|||
WebViewManager.shared().loadHTMLString("<html></html>", baseURL: nil)
|
||||
}
|
||||
}
|
||||
|
||||
func archive() {
|
||||
dataService.archiveLink(objectID: item.objectID, archived: !item.isArchived)
|
||||
#if os(iOS)
|
||||
presentationMode.wrappedValue.dismiss()
|
||||
#endif
|
||||
Snackbar.show(message: !item.isArchived ? "Link archived" : "Link moved to Inbox")
|
||||
}
|
||||
|
||||
func share() {
|
||||
shareActionID = UUID()
|
||||
}
|
||||
|
||||
func delete() {
|
||||
showDeleteConfirmation = true
|
||||
}
|
||||
|
||||
func editLabels() {
|
||||
showLabelsModal = true
|
||||
}
|
||||
|
||||
func scrollToTop() {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ final class WebReaderCoordinator: NSObject {
|
|||
var previousShowNavBarActionID: UUID?
|
||||
var previousShareActionID: UUID?
|
||||
var updateNavBarVisibilityRatio: (Double) -> Void = { _ in }
|
||||
var updateShowBottomBar: (Bool) -> Void = { _ in }
|
||||
var articleContentID = UUID()
|
||||
private var yOffsetAtStartOfDrag: Double?
|
||||
private var lastYOffset: Double = 0
|
||||
|
|
@ -121,6 +122,12 @@ extension WebReaderCoordinator: WKNavigationDelegate {
|
|||
navBarVisibilityRatio = min(ratio, 1)
|
||||
scrollView.contentInset.top = navBarVisibilityRatio * readerViewNavBarHeight
|
||||
}
|
||||
|
||||
if yOffset + scrollView.visibleSize.height > scrollView.contentSize.height - 140 {
|
||||
updateShowBottomBar(true)
|
||||
} else {
|
||||
updateShowBottomBar(false)
|
||||
}
|
||||
}
|
||||
|
||||
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue