mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Add missing files
This commit is contained in:
parent
839b364d13
commit
067e3a8976
3 changed files with 184 additions and 0 deletions
|
|
@ -0,0 +1,39 @@
|
|||
import SwiftUI
|
||||
import Views
|
||||
|
||||
struct InformationalSnackbar: View {
|
||||
let message: String?
|
||||
let undoAction: (() -> Void)?
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
HStack {
|
||||
if let message = message {
|
||||
Text(message)
|
||||
}
|
||||
Spacer()
|
||||
|
||||
if let undoAction = self.undoAction {
|
||||
Button(action: {
|
||||
undoAction()
|
||||
}, label: {
|
||||
Text("Undo")
|
||||
.bold()
|
||||
.foregroundColor(.blue)
|
||||
|
||||
})
|
||||
.padding(.trailing, 2)
|
||||
}
|
||||
}
|
||||
.padding(10)
|
||||
.frame(height: 50)
|
||||
.frame(maxWidth: 380)
|
||||
.background(Color(hex: "2A2A2A"))
|
||||
.foregroundColor(Color(hex: "EBEBEB"))
|
||||
.cornerRadius(4.0)
|
||||
}
|
||||
.padding(.bottom, 60)
|
||||
.padding(.horizontal, 10)
|
||||
.ignoresSafeArea(.all, edges: .bottom)
|
||||
}
|
||||
}
|
||||
66
apple/OmnivoreKit/Sources/App/Views/PDFContainerView.swift
Normal file
66
apple/OmnivoreKit/Sources/App/Views/PDFContainerView.swift
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
import Combine
|
||||
import Models
|
||||
import SwiftUI
|
||||
import Utils
|
||||
import Services
|
||||
|
||||
@MainActor final class PDFContainerViewModel: ObservableObject {
|
||||
func trackReadEvent(item: Models.LibraryItem, reader: String) {
|
||||
let itemID = item.unwrappedID
|
||||
let slug = item.unwrappedSlug
|
||||
let originalArticleURL = item.unwrappedPageURLString
|
||||
|
||||
EventTracker.track(
|
||||
.linkRead(
|
||||
linkID: itemID,
|
||||
slug: slug,
|
||||
reader: reader,
|
||||
originalArticleURL: originalArticleURL
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
struct PDFContainerView: View {
|
||||
let item: Models.LibraryItem
|
||||
let pdfItem: PDFItem?
|
||||
|
||||
|
||||
@EnvironmentObject var dataService: DataService
|
||||
@StateObject private var viewModel = PDFContainerViewModel()
|
||||
|
||||
init(item: Models.LibraryItem) {
|
||||
self.item = item
|
||||
self.pdfItem = PDFItem.make(item: item)
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationView {
|
||||
pdfContainerView
|
||||
.navigationBarBackButtonHidden(false)
|
||||
}
|
||||
.navigationViewStyle(.stack)
|
||||
.ignoresSafeArea(.all, edges: .bottom)
|
||||
.onAppear {
|
||||
viewModel.trackReadEvent(item: item, reader: "PDF")
|
||||
}
|
||||
}
|
||||
|
||||
@ViewBuilder private var pdfContainerView: some View {
|
||||
if let pdfItem = pdfItem, let pdfURL = pdfItem.pdfURL {
|
||||
#if os(iOS)
|
||||
PDFViewer(viewModel: PDFViewerViewModel(pdfItem: pdfItem))
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#elseif os(macOS)
|
||||
PDFWrapperView(pdfURL: pdfURL)
|
||||
#endif
|
||||
} else {
|
||||
HStack(alignment: .center) {
|
||||
Spacer()
|
||||
Text("Loading")
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
import CoreData
|
||||
import Foundation
|
||||
import Models
|
||||
import SwiftGraphQL
|
||||
|
||||
public extension DataService {
|
||||
func emptyTrash() async -> Bool {
|
||||
enum MutationResult {
|
||||
case result(success: Bool)
|
||||
case error(errorMessage: String)
|
||||
}
|
||||
|
||||
let selection = Selection<MutationResult, Unions.EmptyTrashResult> {
|
||||
try $0.on(
|
||||
emptyTrashError: .init { .error(errorMessage: try $0.errorCodes().first?.rawValue ?? "Unknown Error") },
|
||||
emptyTrashSuccess: .init {
|
||||
.result(success: try $0.success() ?? false)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
let mutation = Selection.Mutation {
|
||||
try $0.emptyTrash(selection: selection)
|
||||
}
|
||||
|
||||
let path = appEnvironment.graphqlPath
|
||||
let headers = networker.defaultHeaders
|
||||
let context = backgroundContext
|
||||
|
||||
return await withCheckedContinuation { continuation in
|
||||
send(mutation, to: path, headers: headers) { queryResult in
|
||||
guard let payload = try? queryResult.get() else {
|
||||
print("network error emptying trash")
|
||||
continuation.resume(returning: false)
|
||||
return
|
||||
}
|
||||
|
||||
switch (payload.data) {
|
||||
case let .result(success):
|
||||
if !success {
|
||||
print("server did not return success for emptying trash")
|
||||
continuation.resume(returning: false)
|
||||
return
|
||||
}
|
||||
default:
|
||||
print("server did not return success for emptying trash")
|
||||
continuation.resume(returning: false)
|
||||
return
|
||||
}
|
||||
|
||||
do {
|
||||
try context.performAndWait {
|
||||
let fetchRequest = LibraryItem.fetchRequest()
|
||||
fetchRequest.predicate = NSPredicate(
|
||||
format: "%K == %i OR %K == \"DELETED\"",
|
||||
#keyPath(Models.LibraryItem.serverSyncStatus), Int64(ServerSyncStatus.needsDeletion.rawValue),
|
||||
#keyPath(Models.LibraryItem.state)
|
||||
)
|
||||
for object in try context.fetch(fetchRequest) {
|
||||
context.delete(object)
|
||||
}
|
||||
do {
|
||||
try context.save()
|
||||
logger.debug("Empty trash completed")
|
||||
continuation.resume(returning: true)
|
||||
} catch {
|
||||
context.rollback()
|
||||
logger.debug("Failed to sync library item move: \(error.localizedDescription)")
|
||||
continuation.resume(returning: false)
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
print("error emptying trash", error)
|
||||
continuation.resume(returning: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue