mirror of
https://github.com/dscyrescotti/Memola.git
synced 2026-04-01 15:03:18 +02:00
feat: add find keyboard shortcut
This commit is contained in:
@@ -25,7 +25,6 @@
|
||||
EC2002D52C416033002EBD5F /* FileCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2002D42C416033002EBD5F /* FileCommands.swift */; };
|
||||
EC2002D72C4160EF002EBD5F /* EditCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2002D62C4160EF002EBD5F /* EditCommands.swift */; };
|
||||
EC2002D92C4161ED002EBD5F /* ViewCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2002D82C4161ED002EBD5F /* ViewCommands.swift */; };
|
||||
EC2002DB2C4162E5002EBD5F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2002DA2C4162E5002EBD5F /* AppDelegate.swift */; };
|
||||
EC2002DD2C4163E8002EBD5F /* AppCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2002DC2C4163E8002EBD5F /* AppCommands.swift */; };
|
||||
EC2002E12C416470002EBD5F /* Shortcut.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2002E02C416470002EBD5F /* Shortcut.swift */; };
|
||||
EC2002E52C416551002EBD5F /* Shortcuts.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC2002E42C416551002EBD5F /* Shortcuts.swift */; };
|
||||
@@ -45,6 +44,9 @@
|
||||
EC50500D2BF6674400B4D86E /* OnDragViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC50500C2BF6674400B4D86E /* OnDragViewModifier.swift */; };
|
||||
EC5D40812C21CE270067F090 /* PhotoBackgroundRenderPass.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC5D40802C21CE270067F090 /* PhotoBackgroundRenderPass.swift */; };
|
||||
EC5E83902BFDB69C00261D9C /* MovingAverage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC5E838F2BFDB69C00261D9C /* MovingAverage.swift */; };
|
||||
EC6E3BD72C43C6A400DD20F3 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6E3BD62C43C6A400DD20F3 /* Application.swift */; };
|
||||
EC6E3BD92C43C6C000DD20F3 /* OnDismissSearchViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6E3BD82C43C6C000DD20F3 /* OnDismissSearchViewModifier.swift */; };
|
||||
EC6E3BDB2C43C78700DD20F3 /* NavigationSplitViewVisibility++.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC6E3BDA2C43C78700DD20F3 /* NavigationSplitViewVisibility++.swift */; };
|
||||
EC7F6BEC2BE5E6E300A34A7B /* MemolaApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = EC7F6BEB2BE5E6E300A34A7B /* MemolaApp.swift */; };
|
||||
EC7F6BF02BE5E6E400A34A7B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EC7F6BEF2BE5E6E400A34A7B /* Assets.xcassets */; };
|
||||
EC7F6BF32BE5E6E400A34A7B /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EC7F6BF22BE5E6E400A34A7B /* Preview Assets.xcassets */; };
|
||||
@@ -160,7 +162,6 @@
|
||||
EC2002D42C416033002EBD5F /* FileCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileCommands.swift; sourceTree = "<group>"; };
|
||||
EC2002D62C4160EF002EBD5F /* EditCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditCommands.swift; sourceTree = "<group>"; };
|
||||
EC2002D82C4161ED002EBD5F /* ViewCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewCommands.swift; sourceTree = "<group>"; };
|
||||
EC2002DA2C4162E5002EBD5F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
EC2002DC2C4163E8002EBD5F /* AppCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppCommands.swift; sourceTree = "<group>"; };
|
||||
EC2002E02C416470002EBD5F /* Shortcut.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shortcut.swift; sourceTree = "<group>"; };
|
||||
EC2002E42C416551002EBD5F /* Shortcuts.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shortcuts.swift; sourceTree = "<group>"; };
|
||||
@@ -181,6 +182,9 @@
|
||||
EC50500E2BF670EA00B4D86E /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
EC5D40802C21CE270067F090 /* PhotoBackgroundRenderPass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoBackgroundRenderPass.swift; sourceTree = "<group>"; };
|
||||
EC5E838F2BFDB69C00261D9C /* MovingAverage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MovingAverage.swift; sourceTree = "<group>"; };
|
||||
EC6E3BD62C43C6A400DD20F3 /* Application.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
|
||||
EC6E3BD82C43C6C000DD20F3 /* OnDismissSearchViewModifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnDismissSearchViewModifier.swift; sourceTree = "<group>"; };
|
||||
EC6E3BDA2C43C78700DD20F3 /* NavigationSplitViewVisibility++.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NavigationSplitViewVisibility++.swift"; sourceTree = "<group>"; };
|
||||
EC7F6BE82BE5E6E300A34A7B /* Memola.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Memola.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
EC7F6BEB2BE5E6E300A34A7B /* MemolaApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MemolaApp.swift; sourceTree = "<group>"; };
|
||||
EC7F6BEF2BE5E6E400A34A7B /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
@@ -492,6 +496,7 @@
|
||||
EC50500B2BF6673300B4D86E /* ViewModifiers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EC6E3BD82C43C6C000DD20F3 /* OnDismissSearchViewModifier.swift */,
|
||||
EC50500C2BF6674400B4D86E /* OnDragViewModifier.swift */,
|
||||
EC0D14272BF7BF20009BFE5F /* ContextMenuViewModifier.swift */,
|
||||
);
|
||||
@@ -585,7 +590,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EC7F6BEB2BE5E6E300A34A7B /* MemolaApp.swift */,
|
||||
EC2002DA2C4162E5002EBD5F /* AppDelegate.swift */,
|
||||
EC6E3BD62C43C6A400DD20F3 /* Application.swift */,
|
||||
);
|
||||
path = App;
|
||||
sourceTree = "<group>";
|
||||
@@ -950,6 +955,7 @@
|
||||
ECF7B2CF2C39169C004D2C57 /* Extensions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
EC6E3BDA2C43C78700DD20F3 /* NavigationSplitViewVisibility++.swift */,
|
||||
ECF7B2BD2C39169C004D2C57 /* Array++.swift */,
|
||||
ECF7B2BE2C39169C004D2C57 /* CGAffineTransform++.swift */,
|
||||
ECF7B2BF2C39169C004D2C57 /* CGFloat++.swift */,
|
||||
@@ -1120,6 +1126,7 @@
|
||||
EC2002E52C416551002EBD5F /* Shortcuts.swift in Sources */,
|
||||
EC2002DD2C4163E8002EBD5F /* AppCommands.swift in Sources */,
|
||||
EC1815082C2D980B00541369 /* Sort.swift in Sources */,
|
||||
EC6E3BD92C43C6C000DD20F3 /* OnDismissSearchViewModifier.swift in Sources */,
|
||||
ECA7387D2BE5EF4B00A4542E /* MemoView.swift in Sources */,
|
||||
ECDDD40D2C366B3B00DF9D5E /* PreviewRenderPass.swift in Sources */,
|
||||
ECF7B2E12C39169C004D2C57 /* View++.swift in Sources */,
|
||||
@@ -1129,6 +1136,7 @@
|
||||
ECFA15202BEF21EF00455818 /* MemoObject.swift in Sources */,
|
||||
ECE883C12C00C9CB0045C53D /* StrokeStyle.swift in Sources */,
|
||||
EC37FB122C1B2DD90008D976 /* ToolSelection.swift in Sources */,
|
||||
EC6E3BDB2C43C78700DD20F3 /* NavigationSplitViewVisibility++.swift in Sources */,
|
||||
ECA738C62BE60E9D00A4542E /* EraserPenStyle.swift in Sources */,
|
||||
ECA738A62BE6023F00A4542E /* GridUniforms.swift in Sources */,
|
||||
ECA738D72BE60FC100A4542E /* SolidPointStrokeGenerator.swift in Sources */,
|
||||
@@ -1139,6 +1147,7 @@
|
||||
ECA738862BE5FF2500A4542E /* Canvas.swift in Sources */,
|
||||
ECF7B2DE2C39169C004D2C57 /* NSManagedObjectContext++.swift in Sources */,
|
||||
ECA738882BE5FF4400A4542E /* Renderer.swift in Sources */,
|
||||
EC6E3BD72C43C6A400DD20F3 /* Application.swift in Sources */,
|
||||
EC8C9DCE2C39882500A8F3C4 /* NSSyncScrollView.swift in Sources */,
|
||||
ECF7B2D72C39169C004D2C57 /* Color++.swift in Sources */,
|
||||
EC01512C2C306BEF008A115E /* MemoCard.swift in Sources */,
|
||||
@@ -1179,7 +1188,6 @@
|
||||
ECDAC07B2C318DBC0000ED77 /* ElementToolbar.swift in Sources */,
|
||||
EC50500D2BF6674400B4D86E /* OnDragViewModifier.swift in Sources */,
|
||||
EC9AB09F2C1401A40076AF58 /* EraserObject.swift in Sources */,
|
||||
EC2002DB2C4162E5002EBD5F /* AppDelegate.swift in Sources */,
|
||||
ECBE529C2C1D94A4006BDB3D /* CameraView.swift in Sources */,
|
||||
ECA7389E2BE601CB00A4542E /* QuadVertex.swift in Sources */,
|
||||
ECA738B32BE60D9E00A4542E /* CanvasView.swift in Sources */,
|
||||
|
||||
@@ -1,19 +1,26 @@
|
||||
//
|
||||
// AppDelegate.swift
|
||||
// Application.swift
|
||||
// Memola
|
||||
//
|
||||
// Created by Dscyre Scotti on 7/12/24.
|
||||
//
|
||||
|
||||
import Combine
|
||||
import SwiftUI
|
||||
|
||||
class AppDelegate: NSObject, ObservableObject { }
|
||||
class Application: NSObject, ObservableObject {
|
||||
|
||||
}
|
||||
|
||||
#if os(macOS)
|
||||
extension AppDelegate: NSApplicationDelegate {
|
||||
extension Application: NSApplicationDelegate {
|
||||
func applicationDidFinishLaunching(_ notification: Notification) {
|
||||
NSWindow.allowsAutomaticWindowTabbing = false
|
||||
UserDefaults.standard.register(defaults: ["NSQuitAlwaysKeepsWindows": false])
|
||||
}
|
||||
}
|
||||
#else
|
||||
extension Application: UIApplicationDelegate {
|
||||
func applicationDidFinishLaunching(_ application: UIApplication) { }
|
||||
}
|
||||
#endif
|
||||
@@ -10,9 +10,11 @@ import SwiftUI
|
||||
@main
|
||||
struct MemolaApp: App {
|
||||
#if os(macOS)
|
||||
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
||||
@NSApplicationDelegateAdaptor(Application.self) var application
|
||||
#else
|
||||
@UIApplicationDelegateAdaptor(Application.self) var application
|
||||
#endif
|
||||
|
||||
|
||||
var body: some Scene {
|
||||
WindowGroup {
|
||||
DashboardView()
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import SwiftUI
|
||||
import Foundation
|
||||
|
||||
struct ContextMenuViewModifier<MenuContent: View, Preview: View>: ViewModifier {
|
||||
private struct ContextMenuViewModifier<MenuContent: View, Preview: View>: ViewModifier {
|
||||
let condition: Bool
|
||||
let menuItems: () -> MenuContent
|
||||
let preview: () -> Preview
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// OnDismissSearchViewModifier.swift
|
||||
// Memola
|
||||
//
|
||||
// Created by Dscyre Scotti on 7/14/24.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
private struct OnDismissSearchViewModifier: ViewModifier {
|
||||
@Environment(\.dismissSearch) var dismissSearch
|
||||
|
||||
@Binding var isActive: Bool
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
.onChange(of: isActive) { oldValue, newValue in
|
||||
if !newValue {
|
||||
dismissSearch()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension View {
|
||||
func onDismissSearch(isActive: Binding<Bool>) -> some View {
|
||||
modifier(OnDismissSearchViewModifier(isActive: isActive))
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
import SwiftUI
|
||||
import Foundation
|
||||
|
||||
struct OnDragViewModifier<Preview: View>: ViewModifier {
|
||||
private struct OnDragViewModifier<Preview: View>: ViewModifier {
|
||||
let condition: Bool
|
||||
let data: () -> NSItemProvider
|
||||
let preview: () -> Preview
|
||||
|
||||
@@ -13,12 +13,13 @@ struct DashboardView: View {
|
||||
@StateObject var memoManager: MemoManager = .shared
|
||||
|
||||
@State var sidebarItem: SidebarItem? = .memos
|
||||
@AppStorage("memola.app.scene.side-bar.column-visibility") var columnVisibility: NavigationSplitViewVisibility = .all
|
||||
|
||||
@Namespace var namespace
|
||||
|
||||
var body: some View {
|
||||
#if os(macOS)
|
||||
NavigationSplitView {
|
||||
NavigationSplitView(columnVisibility: $columnVisibility) {
|
||||
Sidebar(sidebarItem: $sidebarItem, horizontalSizeClass: horizontalSizeClass)
|
||||
} detail: {
|
||||
switch sidebarItem {
|
||||
@@ -45,7 +46,7 @@ struct DashboardView: View {
|
||||
}
|
||||
}
|
||||
#else
|
||||
NavigationSplitView {
|
||||
NavigationSplitView(columnVisibility: $columnVisibility) {
|
||||
Sidebar(sidebarItem: $sidebarItem, horizontalSizeClass: horizontalSizeClass)
|
||||
} detail: {
|
||||
switch sidebarItem {
|
||||
|
||||
@@ -15,6 +15,7 @@ struct MemosView: View {
|
||||
|
||||
@State var query: String = ""
|
||||
@State var currentDate: Date = .now
|
||||
@State var isActiveSearch: Bool = false
|
||||
|
||||
@AppStorage("memola.memo-objects.memos.sort") var sort: Sort = .recent
|
||||
@AppStorage("memola.memo-objects.memos.filter") var filter: Filter = .none
|
||||
@@ -43,12 +44,16 @@ struct MemosView: View {
|
||||
MemoGrid(memoObjects: memoObjects, placeholder: placeholder) { memoObject, cellWidth in
|
||||
memoCard(memoObject, cellWidth)
|
||||
}
|
||||
.onDismissSearch(isActive: $isActiveSearch)
|
||||
.focusedSceneValue(\.activeSceneKey, .memos)
|
||||
.navigationTitle(horizontalSizeClass == .compact ? "Memos" : "")
|
||||
#if os(iOS)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#endif
|
||||
.searchable(text: $query, placement: .toolbar, prompt: Text("Search"))
|
||||
.searchable(text: $query, isPresented: $isActiveSearch, placement: .toolbar, prompt: Text("Search"))
|
||||
.onSubmit(of: .search) {
|
||||
isActiveSearch = false
|
||||
}
|
||||
.toolbar {
|
||||
#if os(macOS)
|
||||
ToolbarItem(placement: .navigation) {
|
||||
|
||||
@@ -16,6 +16,7 @@ struct TrashView: View {
|
||||
@State var query: String = ""
|
||||
@State var restoredMemo: MemoObject?
|
||||
@State var deletedMemo: MemoObject?
|
||||
@State var isActiveSearch: Bool = false
|
||||
|
||||
@Binding var sidebarItem: SidebarItem?
|
||||
|
||||
@@ -44,12 +45,16 @@ struct TrashView: View {
|
||||
MemoGrid(memoObjects: memoObjects, placeholder: placeholder) { memoObject, cellWidth in
|
||||
memoCard(memoObject, cellWidth)
|
||||
}
|
||||
.onDismissSearch(isActive: $isActiveSearch)
|
||||
.focusedSceneValue(\.activeSceneKey, .trash)
|
||||
.navigationTitle(horizontalSizeClass == .compact ? "Trash" : "")
|
||||
#if os(iOS)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
#endif
|
||||
.searchable(text: $query, placement: .toolbar, prompt: Text("Search"))
|
||||
.searchable(text: $query, isPresented: $isActiveSearch, placement: .toolbar, prompt: Text("Search"))
|
||||
.onSubmit(of: .search) {
|
||||
isActiveSearch = false
|
||||
}
|
||||
.toolbar {
|
||||
#if os(macOS)
|
||||
ToolbarItem(placement: .navigation) {
|
||||
|
||||
@@ -8,7 +8,23 @@
|
||||
import SwiftUI
|
||||
|
||||
struct ViewCommands: Commands {
|
||||
@FocusedValue(\.activeSceneKey) var appScene
|
||||
|
||||
var body: some Commands {
|
||||
CommandGroup(replacing: .toolbar) { }
|
||||
CommandGroup(replacing: .toolbar) {
|
||||
if appScene == .trash || appScene == .memos {
|
||||
Button {
|
||||
#if os(macOS)
|
||||
guard let toolbar = NSApp.keyWindow?.toolbar else { return }
|
||||
if let search = toolbar.items.first(where: { $0.itemIdentifier.rawValue == "com.apple.SwiftUI.search" }) as? NSSearchToolbarItem {
|
||||
search.beginSearchInteraction()
|
||||
}
|
||||
#endif
|
||||
} label: {
|
||||
Text("Find Memo")
|
||||
}
|
||||
.keyboardShortcut("f", modifiers: [.command])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import Combine
|
||||
import Foundation
|
||||
|
||||
class Shortcut: ObservableObject {
|
||||
class Shortcut {
|
||||
static let shared: Shortcut = .init()
|
||||
|
||||
private let shortcutPublisher = PassthroughSubject<Shortcuts, Never>()
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
//
|
||||
// NavigationSplitViewVisibility++.swift
|
||||
// Memola
|
||||
//
|
||||
// Created by Dscyre Scotti on 7/14/24.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
extension NavigationSplitViewVisibility: RawRepresentable {
|
||||
public init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .all
|
||||
case 1: self = .automatic
|
||||
case 2: self = .detailOnly
|
||||
case 3: self = .doubleColumn
|
||||
default: self = .all
|
||||
}
|
||||
}
|
||||
|
||||
public var rawValue: Int {
|
||||
switch self {
|
||||
case .all: 0
|
||||
case .automatic: 1
|
||||
case .detailOnly: 2
|
||||
case .doubleColumn: 3
|
||||
default: -1
|
||||
}
|
||||
}
|
||||
|
||||
public typealias RawValue = Int
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user