Merge pull request #203 from omnivore-app/feature/reader-context-menu

This commit is contained in:
Satindar Dhillon
2022-03-08 19:53:00 -08:00
committed by GitHub
9 changed files with 136 additions and 51 deletions

View File

@ -15,7 +15,7 @@ struct FeedCardNavigationLink: View {
var body: some View {
NavigationLink(
destination: LinkItemDetailView(viewModel: LinkItemDetailViewModel(item: item)),
destination: LinkItemDetailView(viewModel: LinkItemDetailViewModel(item: item, homeFeedViewModel: viewModel)),
tag: item,
selection: $selectedLinkItem
) {
@ -48,7 +48,7 @@ struct GridCardNavigationLink: View {
var body: some View {
ZStack {
NavigationLink(
destination: LinkItemDetailView(viewModel: LinkItemDetailViewModel(item: item)),
destination: LinkItemDetailView(viewModel: LinkItemDetailViewModel(item: item, homeFeedViewModel: viewModel)),
isActive: $isActive
) {
EmptyView()

View File

@ -195,7 +195,7 @@ import Views
itemToRemove = item
confirmationShown = true
},
label: { Label("Delete Link", systemImage: "trash") }
label: { Label("Delete", systemImage: "trash") }
)
if FeatureFlag.enableSnooze {
Button {

View File

@ -51,7 +51,7 @@ import Views
itemToRemove = item
confirmationShown = true
},
label: { Label("Delete Link", systemImage: "trash") }
label: { Label("Delete", systemImage: "trash") }
)
if FeatureFlag.enableSnooze {
Button {

View File

@ -10,18 +10,23 @@ enum PDFProvider {
}
final class LinkItemDetailViewModel: ObservableObject {
let homeFeedViewModel: HomeFeedViewModel
@Published var item: FeedItem
@Published var webAppWrapperViewModel: WebAppWrapperViewModel?
enum Action {
case load
case updateReadStatus(markAsRead: Bool)
}
var subscriptions = Set<AnyCancellable>()
init(item: FeedItem) {
init(item: FeedItem, homeFeedViewModel: HomeFeedViewModel) {
self.item = item
self.homeFeedViewModel = homeFeedViewModel
}
func handleArchiveAction(dataService: DataService) {
homeFeedViewModel.setLinkArchived(dataService: dataService, linkId: item.id, archived: !item.isArchived)
}
func handleDeleteAction(dataService: DataService) {
homeFeedViewModel.removeLink(dataService: dataService, linkId: item.id)
}
func updateItemReadStatus(dataService: DataService) {
@ -103,6 +108,7 @@ struct LinkItemDetailView: View {
@ObservedObject private var viewModel: LinkItemDetailViewModel
@State private var showFontSizePopover = false
@State private var navBarVisibilityRatio = 1.0
@State private var showDeleteConfirmation = false
init(viewModel: LinkItemDetailViewModel) {
self.viewModel = viewModel
@ -147,6 +153,38 @@ struct LinkItemDetailView: View {
#endif
}
var navBariOS14: some View {
HStack(alignment: .center) {
Button(
action: { self.presentationMode.wrappedValue.dismiss() },
label: {
Image(systemName: "chevron.backward")
.font(.appTitleTwo)
.foregroundColor(.appGrayTextContrast)
.padding(.horizontal)
}
)
.scaleEffect(navBarVisibilityRatio)
Spacer()
Button(
action: { showFontSizePopover.toggle() },
label: {
Image(systemName: "textformat.size")
.font(.appTitleTwo)
}
)
.padding(.horizontal)
.scaleEffect(navBarVisibilityRatio)
}
.frame(height: readerViewNavBarHeight * navBarVisibilityRatio)
.opacity(navBarVisibilityRatio)
.background(Color.systemBackground)
.onTapGesture {
showFontSizePopover = false
}
}
@available(iOS 15.0, *)
var navBar: some View {
HStack(alignment: .center) {
Button(
@ -169,31 +207,43 @@ struct LinkItemDetailView: View {
)
.padding(.horizontal)
.scaleEffect(navBarVisibilityRatio)
if FeatureFlag.showLinkOptionsOnReaderView {
Menu(
content: {
Group {
Button(
action: {},
label: { Label("Archive", systemImage: "archivebox") }
)
Button(
action: {},
label: { Label("Delete Link", systemImage: "trash") }
)
}
},
label: {
Image.profile
.padding(.horizontal)
.scaleEffect(navBarVisibilityRatio)
Menu(
content: {
Group {
Button(
action: { viewModel.handleArchiveAction(dataService: dataService) },
label: {
Label(
viewModel.item.isArchived ? "Unarchive" : "Archive",
systemImage: viewModel.item.isArchived ? "tray.and.arrow.down.fill" : "archivebox"
)
}
)
Button(
action: { showDeleteConfirmation = true },
label: { Label("Delete", systemImage: "trash") }
)
}
)
}
},
label: {
Image.profile
.padding(.horizontal)
.scaleEffect(navBarVisibilityRatio)
}
)
}
.frame(height: readerViewNavBarHeight * navBarVisibilityRatio)
.opacity(navBarVisibilityRatio)
.background(Color.systemBackground)
.onTapGesture {
showFontSizePopover = false
}
.alert("Are you sure?", isPresented: $showDeleteConfirmation) {
Button("Remove Link", role: .destructive) {
viewModel.handleDeleteAction(dataService: dataService)
}
Button("Cancel", role: .cancel, action: {})
}
}
#if os(iOS)
@ -219,7 +269,7 @@ struct LinkItemDetailView: View {
fontAdjustmentPopoverView
.background(Color.appButtonBackground)
.cornerRadius(8)
.padding(.trailing, 5)
.padding(.trailing, 44)
}
Spacer()
}
@ -231,24 +281,47 @@ struct LinkItemDetailView: View {
}
)
}
if #available(iOS 15.0, *) {
VStack(spacing: 0) {
navBar
Spacer()
}
.navigationBarHidden(true)
} else {
VStack(spacing: 0) {
navBariOS14
Spacer()
}
.navigationBarHidden(true)
}
}
} else {
if #available(iOS 15.0, *) {
VStack(spacing: 0) {
navBar
Spacer()
}
.onAppear {
viewModel.loadWebAppWrapper(
dataService: dataService,
rawAuthCookie: authenticator.omnivoreAuthCookieString
)
}
.navigationBarHidden(true)
} else {
VStack(spacing: 0) {
navBariOS14
Spacer()
}
.onAppear {
viewModel.loadWebAppWrapper(
dataService: dataService,
rawAuthCookie: authenticator.omnivoreAuthCookieString
)
}
.navigationBarHidden(true)
}
.navigationBarHidden(true)
} else {
VStack(spacing: 0) {
navBar
Spacer()
}
.onAppear {
viewModel.loadWebAppWrapper(
dataService: dataService,
rawAuthCookie: authenticator.omnivoreAuthCookieString
)
}
.navigationBarHidden(true)
}
}
#endif

View File

@ -15,5 +15,4 @@ public enum FeatureFlag {
public static let enableShareButton = false
public static let enableSnooze = false
public static let showFeedItemTags = false
public static let showLinkOptionsOnReaderView = false
}

View File

@ -44,8 +44,10 @@ extension WebAppViewCoordinator: WKNavigationDelegate {
}
func webView(_ webView: WKWebView, didFinish _: WKNavigation!) {
webView.isOpaque = true
webView.backgroundColor = .systemBackground
#if os(iOS)
webView.isOpaque = true
webView.backgroundColor = .systemBackground
#endif
}
}

View File

@ -22,9 +22,18 @@ public extension Color {
static var systemBackground: Color { Color(.systemBackground) }
static var systemPlaceholder: Color { Color(.placeholderText) }
static var secondarySystemGroupedBackground: Color { Color(.secondarySystemGroupedBackground) }
static var systemLabel: Color {
if #available(iOS 15.0, *) {
return Color(uiColor: .label)
} else {
return Color.appGrayTextContrast
}
}
#elseif os(macOS)
static var systemBackground: Color { Color(.windowBackgroundColor) }
static var systemPlaceholder: Color { Color(.placeholderTextColor) }
static var systemLabel: Color { Color(.labelColor) }
// Just for compilation. secondarySystemGroupedBackground shouldn't be used on macOS
static var secondarySystemGroupedBackground: Color { Color(.windowBackgroundColor) }

View File

@ -53,7 +53,7 @@ public struct GridCard: View {
)
Button(
action: { menuActionHandler(.delete) },
label: { Label("Delete Link", systemImage: "trash") }
label: { Label("Delete", systemImage: "trash") }
)
}
}

View File

@ -30,13 +30,15 @@ public struct FontSizeAdjustmentPopoverView: View {
label: {
Image(systemName: "minus")
#if os(iOS)
.foregroundColor(.appGraySolid)
.foregroundColor(.systemLabel)
.padding()
#endif
}
)
.frame(width: 55, height: 40, alignment: .center)
Divider().frame(height: 30)
Divider()
.frame(height: 30)
.background(Color.systemLabel)
Button(
action: {
storedFontSize = min(storedFontSize + 2, 28)
@ -45,7 +47,7 @@ public struct FontSizeAdjustmentPopoverView: View {
label: {
Image(systemName: "plus")
#if os(iOS)
.foregroundColor(.appGraySolid)
.foregroundColor(.systemLabel)
.padding()
#endif
}