Better handling of the label editor

This commit is contained in:
Jackson Harper
2023-11-10 20:33:05 +08:00
parent 59f1c144b3
commit 50f1213e93
5 changed files with 189 additions and 22 deletions

View File

@ -14,6 +14,7 @@ import Views
@MainActor
public struct EditLabelsSheet: View {
@State var text = ""
@State var isLabelsEntryFocused = false
@Environment(\.dismiss) private var dismiss
@EnvironmentObject var dataService: DataService
@ -56,6 +57,7 @@ public struct EditLabelsSheet: View {
VStack {
LabelsEntryView(
searchTerm: $labelsViewModel.labelSearchFilter,
isFocused: $isLabelsEntryFocused,
viewModel: labelsViewModel
)
.padding(.horizontal, 10)

View File

@ -20,7 +20,8 @@ public struct ShareExtensionView: View {
@State var showAddNoteModal = false
enum FocusField: Hashable {
case titleEditor
case noteEditor
case labelEditor
}
enum ViewState {
@ -39,6 +40,10 @@ public struct ShareExtensionView: View {
_viewModel = StateObject(wrappedValue: viewModel)
_labelsViewModel = StateObject(wrappedValue: labelsViewModel)
self.extensionContext = extensionContext
#if os(iOS)
UITextView.appearance().textContainerInset = UIEdgeInsets(top: 8, left: 4, bottom: 10, right: 4)
#endif
}
private func localImage(from url: URL) -> Image? {
@ -55,12 +60,13 @@ public struct ShareExtensionView: View {
}
var isSynced: Bool {
switch viewModel.status {
case .synced:
return true
default:
return false
}
true
// switch viewModel.status {
// case .synced:
// return true
// default:
// return false
// }
}
var articleInfoBox: some View {
@ -100,7 +106,7 @@ public struct ShareExtensionView: View {
Image(systemName: "checkmark.circle")
.frame(width: 15, height: 15)
.foregroundColor(.appGreenSuccess)
// .opacity(isSynced ? 1.0 : 0.0)
.opacity(isSynced ? 1.0 : 0.0)
}
}
@ -237,22 +243,32 @@ public struct ShareExtensionView: View {
Text("Saved to Omnivore")
.font(Font.system(size: 22, weight: .bold))
.frame(maxWidth: .infinity, alignment: .leading)
Spacer()
moreMenuButton
closeButton
#if os(iOS)
Spacer()
moreMenuButton
closeButton
#endif
}
}
var displayDismiss: Bool {
#if os(iOS)
if UIDevice.isIPhone {
return true
}
#endif
return false
#if os(iOS)
if UIDevice.isIPhone {
return false
}
#endif
return true
}
public var body: some View {
#if os(iOS)
iOSBody
#else
macOSBody
#endif
}
var iOSBody: some View {
VStack(alignment: .leading, spacing: 15) {
titleBar
.padding(.top, 15)
@ -262,32 +278,44 @@ public struct ShareExtensionView: View {
Spacer(minLength: 1)
HStack {
#if os(macOS)
moreMenuButton
.padding(.bottom, 15)
#endif
Spacer()
if displayDismiss {
Button(action: {
extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
}, label: {
Text("Dismiss")
#if os(iOS)
.font(Font.system(size: 17, weight: .semibold))
.tint(Color.appGrayText)
.padding(20)
#endif
})
#if os(iOS)
.frame(height: 50)
.cornerRadius(24)
.padding(.bottom, 15)
#endif
.padding(.bottom, 15)
}
Button(action: {
viewModel.handleReadNowAction(extensionContext: extensionContext)
}, label: {
Text("Read Now")
#if os(iOS)
.font(Font.system(size: 17, weight: .semibold))
.tint(Color.white)
.padding(20)
#endif
})
#if os(iOS)
.frame(height: 50)
.background(Color.blue)
.cornerRadius(24)
.padding(.bottom, 15)
#endif
.padding(.bottom, 15)
}.frame(maxWidth: .infinity)
}.padding(.horizontal, 15)
.background(Color.extensionBackground)
@ -295,4 +323,99 @@ public struct ShareExtensionView: View {
viewModel.savePage(extensionContext: extensionContext)
}
}
@State var notes = ""
@State var labelsSearch = ZWSP
@State var isLabelsEntryFocused = false
var macOSBody: some View {
VStack(alignment: .leading, spacing: 0) {
HStack(spacing: 10) {
Text("Saved to Omnivore")
.font(Font.system(size: 17))
Image(systemName: "checkmark.circle")
.foregroundColor(.appGreenSuccess)
.opacity(isSynced ? 1.0 : 0.0)
Spacer()
}.padding(15)
Divider()
ZStack(alignment: .topLeading) {
TextEditor(text: $notes)
.frame(maxWidth: .infinity)
.font(Font.system(size: 14))
.accentColor(.blue)
.introspectTextView { textView in
textView.textContainerInset = NSSize(width: 10, height: 10)
}
.focused($focusedField, equals: .noteEditor)
if notes.isEmpty {
Text("Notes")
.fontWeight(.light)
.font(Font.system(size: 14))
.foregroundColor(.black.opacity(0.25))
.padding(.leading, 15)
.padding(.top, 10)
.allowsHitTesting(false)
}
}
Divider()
ZStack(alignment: .topLeading) {
LabelsEntryView(searchTerm: $labelsSearch, isFocused: $isLabelsEntryFocused, viewModel: labelsViewModel)
.frame(maxWidth: .infinity)
.padding(.horizontal, 10)
.focused($focusedField, equals: .labelEditor)
.onHover { isHovered in
DispatchQueue.main.async {
if isHovered {
NSCursor.iBeam.push()
} else {
NSCursor.pop()
}
}
}
if !isLabelsEntryFocused, labelsViewModel.selectedLabels.isEmpty, labelsSearch == ZWSP {
Text("Add Labels")
.fontWeight(.light)
.font(Font.system(size: 14))
.foregroundColor(.black.opacity(0.25))
.padding(.leading, 15)
.padding(.top, 10)
.allowsHitTesting(false)
}
}
Divider()
HStack {
moreMenuButton
.padding(.bottom, 15)
Spacer()
Button(action: {
extensionContext?.completeRequest(returningItems: [], completionHandler: nil)
}, label: {
Text("Dismiss")
})
.padding(.bottom, 15)
Button(action: {
viewModel.handleReadNowAction(extensionContext: extensionContext)
}, label: {
Text("Read Now")
})
.padding(.bottom, 15)
}.padding(15)
}.frame(maxWidth: .infinity)
.background(Color.isDarkMode ? Color.systemBackground : Color.white)
.onAppear {
viewModel.savePage(extensionContext: extensionContext)
DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(100)) {
focusedField = .noteEditor
}
}
}
}

View File

@ -36,6 +36,7 @@ struct ApplyLabelsView: View {
@EnvironmentObject var dataService: DataService
@Environment(\.presentationMode) private var presentationMode
@StateObject var viewModel = LabelsViewModel()
@State var isLabelsEntryFocused = false
enum ViewState {
case mainView
@ -52,6 +53,7 @@ struct ApplyLabelsView: View {
VStack {
LabelsEntryView(
searchTerm: $viewModel.labelSearchFilter,
isFocused: $isLabelsEntryFocused,
viewModel: viewModel
)
.padding(.horizontal, 10)

View File

@ -25,6 +25,7 @@ private struct LabelEntry: Entry {
@MainActor
public struct LabelsEntryView: View {
@Binding var searchTerm: String
@Binding var isFocused: Bool
@State var viewModel: LabelsViewModel
@EnvironmentObject var dataService: DataService
@ -35,11 +36,13 @@ public struct LabelsEntryView: View {
public init(
searchTerm: Binding<String>,
isFocused: Binding<Bool>,
viewModel: LabelsViewModel
) {
self._searchTerm = searchTerm
self.viewModel = viewModel
self._isFocused = isFocused
self.viewModel = viewModel
self.entries = Array(viewModel.selectedLabels.map { LabelEntry(label: $0) })
}
@ -100,6 +103,7 @@ public struct LabelsEntryView: View {
.frame(height: 25)
.frame(width: textWidth)
.padding(5)
.accentColor(.blue)
.font(Font.system(size: 14))
.multilineTextAlignment(.leading)
.onChange(of: searchTerm, perform: { _ in
@ -121,6 +125,10 @@ public struct LabelsEntryView: View {
.onSubmit {
onTextSubmit()
}
#if os(macOS)
.textFieldStyle(.plain)
.background(Color.clear)
#endif
return result
}
@ -157,6 +165,7 @@ public struct LabelsEntryView: View {
textFieldFocused = true
}
.transaction { $0.animation = nil }
.onChange(of: textFieldFocused) { self.isFocused = $0 }
}
private func generateLabelsContent(in geom: GeometryProxy) -> some View {

View File

@ -66,11 +66,36 @@ import Views
let viewModel = ShareExtensionViewModel()
override func loadView() {
view = NSView(frame: NSRect(x: 0, y: 0, width: 400, height: 400))
view = NSView(frame: NSRect(x: 0, y: 0, width: 400, height: 300))
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
forName: Notification.Name("ShowAddNoteSheet"),
object: nil,
queue: OperationQueue.main
) { _ in
self.openSheet(AnyView(AddNoteSheet(viewModel: self.viewModel)))
}
NotificationCenter.default.addObserver(
forName: Notification.Name("ShowEditLabelsSheet"),
object: nil,
queue: OperationQueue.main
) { _ in
self.openSheet(AnyView(EditLabelsSheet(viewModel: self.viewModel, labelsViewModel: self.labelsViewModel)))
}
NotificationCenter.default.addObserver(
forName: Notification.Name("ShowEditInfoSheet"),
object: nil,
queue: OperationQueue.main
) { _ in
self.openSheet(AnyView(EditInfoSheet(viewModel: self.viewModel)))
}
embed(
childViewController: NSViewController.makeShareExtensionController(
viewModel: viewModel,
@ -79,6 +104,12 @@ import Views
)
)
}
func openSheet(_ rootView: AnyView) {
let hostingController = PlatformHostingController(rootView: rootView)
presentAsSheet(hostingController)
}
}
#endif