Merge pull request #1348 from omnivore-app/feat/ios-reader-actions

Add new action bar at bottom of iOS reader that shows when user reaches end
This commit is contained in:
Jackson Harper 2022-10-26 10:48:38 +08:00 committed by GitHub
commit 42f26a6fd9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 128 additions and 9 deletions

View file

@ -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)

View file

@ -24,6 +24,8 @@ struct WebReaderContainerView: View {
@State var showNavBarActionID: UUID?
@State var shareActionID: UUID?
@State var annotation = String()
@State var showBottomBar = false
@State private var bottomBarOpacity = 0.0
@EnvironmentObject var dataService: DataService
@EnvironmentObject var audioController: AudioController
@ -119,6 +121,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 +193,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 +214,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 +298,8 @@ struct WebReaderContainerView: View {
annotationSaveTransactionID: $annotationSaveTransactionID,
showNavBarActionID: $showNavBarActionID,
shareActionID: $shareActionID,
annotation: $annotation
annotation: $annotation,
showBottomBar: $showBottomBar
)
.onTapGesture {
withAnimation {
@ -319,6 +350,21 @@ struct WebReaderContainerView: View {
VStack(spacing: 0) {
navBar
Spacer()
if showBottomBar {
bottomButtons
.frame(height: 48)
.background(Color.webControlButtonBackground)
.cornerRadius(6)
.padding(.bottom, 34)
.shadow(color: .gray.opacity(0.13), radius: 8, x: 0, y: 4)
.opacity(bottomBarOpacity)
.onAppear {
withAnimation(Animation.linear(duration: 0.25)) { self.bottomBarOpacity = 1 }
}
.onDisappear {
self.bottomBarOpacity = 0
}
}
}
#endif
}
@ -336,4 +382,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() {}
}

View file

@ -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) {

View file

@ -19,6 +19,7 @@ public extension Color {
static var appTextDefault: Color { Color("_utilityTextDefault", bundle: .module) }
static var appPrimaryBackground: Color { Color("_appPrimaryBackground", bundle: .module) }
static var checkmarkBlue: Color { Color("_checkmarkBlue", bundle: .module) }
static var webControlButtonBackground: Color { Color("_webControlButtonBackground", bundle: .module) }
// Apple system UIColor equivalents
#if os(iOS)

View file

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "46",
"green" : "44",
"red" : "44"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}