Skip to content
This repository was archived by the owner on Sep 12, 2024. It is now read-only.

Commit 738ddf6

Browse files
committed
Toggle sidebar without selecting snippet
1 parent 52efade commit 738ddf6

File tree

2 files changed

+169
-169
lines changed

2 files changed

+169
-169
lines changed

Snip/Components/CodeViewer/CodeActionsTopBar.swift

-18
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,6 @@ struct CodeActionsTopBar: View {
4747
bottom: 0,
4848
trailing: 16))
4949
.toolbar {
50-
ToolbarItem(placement: .navigation) {
51-
Button(action: viewModel.toggleSidebar) {
52-
Image(systemName: "sidebar.left")
53-
}
54-
.keyboardShortcut(KeyEquivalent.leftArrow, modifiers: [.command])
55-
.onHover { inside in
56-
if inside {
57-
NSCursor.pointingHand.push()
58-
} else {
59-
NSCursor.pop()
60-
}
61-
}
62-
}
63-
6450
ToolbarItem(placement: .status) {
6551
if syncManager.isAuthenticated {
6652
Button(action: viewModel.onUpload) {
@@ -278,10 +264,6 @@ final class CodeActionsViewModel: ObservableObject {
278264
}
279265
}
280266

281-
func toggleSidebar() {
282-
NSApp.keyWindow?.firstResponder?.tryToPerform(#selector(NSSplitViewController.toggleSidebar(_:)), with: nil)
283-
}
284-
285267
var syncStateColor: Color {
286268
switch syncState {
287269
case .local:

Snip/SnipViewApp.swift

+169-151
Original file line numberDiff line numberDiff line change
@@ -10,171 +10,189 @@ import SwiftUI
1010
import Combine
1111

1212
enum ModalView: Identifiable {
13-
case settings
14-
case welcome
15-
case external
16-
17-
var id: Int {
18-
hashValue
19-
}
13+
case settings
14+
case welcome
15+
case external
16+
17+
var id: Int {
18+
hashValue
19+
}
2020
}
2121

2222
struct SnipViewApp: View {
23-
24-
@ObservedObject var viewModel: SnipViewAppViewModel
25-
26-
@EnvironmentObject var appState: AppState
27-
@EnvironmentObject var settings: Settings
28-
29-
30-
var body: some View {
31-
appNavigation
32-
.frame(maxWidth: .infinity, maxHeight: .infinity)
33-
}
34-
35-
@ViewBuilder
36-
var appNavigation: some View {
37-
ZStack {
38-
NavigationView {
39-
40-
if let sidebarViewModel = viewModel.sidebarViewModel {
41-
Sidebar(viewModel: sidebarViewModel)
42-
.frame(minWidth: 300)
23+
24+
@ObservedObject var viewModel: SnipViewAppViewModel
25+
26+
@EnvironmentObject var appState: AppState
27+
@EnvironmentObject var settings: Settings
28+
29+
30+
var body: some View {
31+
appNavigation
32+
.frame(maxWidth: .infinity, maxHeight: .infinity)
33+
}
34+
35+
@ViewBuilder
36+
var appNavigation: some View {
37+
ZStack {
38+
NavigationView {
39+
40+
if let sidebarViewModel = viewModel.sidebarViewModel {
41+
Sidebar(viewModel: sidebarViewModel)
42+
.frame(minWidth: 300)
43+
}
44+
45+
if let codeViewerViewModel = viewModel.codeViewerViewModel {
46+
CodeViewer(viewModel: codeViewerViewModel)
47+
}
48+
49+
}
4350
}
44-
45-
if let codeViewerViewModel = viewModel.codeViewerViewModel {
46-
CodeViewer(viewModel: codeViewerViewModel)
51+
.frame(maxWidth: .infinity, maxHeight: .infinity)
52+
.environment(\.themePrimaryColor, settings.snipAppTheme == .auto ? .primary : .primaryTheme)
53+
.environment(\.themeSecondaryColor, settings.snipAppTheme == .auto ? .secondary : .secondaryTheme)
54+
.environment(\.themeTextColor, settings.snipAppTheme == .auto ? .text : .white)
55+
.environment(\.themeShadowColor, settings.snipAppTheme == .auto ? .shadow : .shadowTheme)
56+
.onAppear {
57+
SyncManager.shared.initialize()
58+
viewModel.trigger(action: .syncGists())
4759
}
48-
49-
}
50-
}
51-
.frame(maxWidth: .infinity, maxHeight: .infinity)
52-
.environment(\.themePrimaryColor, settings.snipAppTheme == .auto ? .primary : .primaryTheme)
53-
.environment(\.themeSecondaryColor, settings.snipAppTheme == .auto ? .secondary : .secondaryTheme)
54-
.environment(\.themeTextColor, settings.snipAppTheme == .auto ? .text : .white)
55-
.environment(\.themeShadowColor, settings.snipAppTheme == .auto ? .shadow : .shadowTheme)
56-
.onAppear {
57-
SyncManager.shared.initialize()
58-
viewModel.trigger(action: .syncGists())
59-
}
60-
.sheet(item: $viewModel.modalView) { content in
61-
62-
switch content {
63-
case .welcome:
64-
WelcomeView(viewModel: WelcomeViewModel(isVisible: $appState.shouldOpenWelcome))
65-
.frame(width: 800, height: 600)
66-
case .settings:
67-
SettingsView(viewModel: SettingsViewModel(isVisible: $settings.shouldOpenSettings))
68-
.frame(width: 800, height: 600)
69-
case .external:
70-
ExternalSnippet(viewModel: ExternalSnippetViewModel(isVisible: $viewModel.snippetManager.hasExternalSnippetQueued,
71-
snipItem: $viewModel.snippetManager.tempSnipItem,
72-
onTrigger: viewModel.trigger(action:)))
73-
.frame(width: 800, height: 600)
74-
}
75-
}
76-
.toolbar {
77-
ToolbarItem(placement: .primaryAction) {
78-
Button(action: viewModel.openExtensionLink) {
79-
Image(systemName: "square.3.stack.3d.middle.fill")
60+
.sheet(item: $viewModel.modalView) { content in
61+
62+
switch content {
63+
case .welcome:
64+
WelcomeView(viewModel: WelcomeViewModel(isVisible: $appState.shouldOpenWelcome))
65+
.frame(width: 800, height: 600)
66+
case .settings:
67+
SettingsView(viewModel: SettingsViewModel(isVisible: $settings.shouldOpenSettings))
68+
.frame(width: 800, height: 600)
69+
case .external:
70+
ExternalSnippet(viewModel: ExternalSnippetViewModel(isVisible: $viewModel.snippetManager.hasExternalSnippetQueued,
71+
snipItem: $viewModel.snippetManager.tempSnipItem,
72+
onTrigger: viewModel.trigger(action:)))
73+
.frame(width: 800, height: 600)
74+
}
8075
}
81-
.help(NSLocalizedString("Extract_Stack", comment: ""))
82-
.onHover { inside in
83-
if inside {
84-
NSCursor.pointingHand.push()
85-
} else {
86-
NSCursor.pop()
87-
}
76+
.toolbar {
77+
ToolbarItem(placement: .navigation) {
78+
Button(action: viewModel.toggleSidebar) {
79+
Image(systemName: "sidebar.left")
80+
}
81+
.keyboardShortcut(KeyEquivalent.leftArrow, modifiers: [.command])
82+
.onHover { inside in
83+
if inside {
84+
NSCursor.pointingHand.push()
85+
} else {
86+
NSCursor.pop()
87+
}
88+
}
89+
}
90+
91+
ToolbarItem(placement: .primaryAction) {
92+
Button(action: viewModel.openExtensionLink) {
93+
Image(systemName: "square.3.stack.3d.middle.fill")
94+
}
95+
.help(NSLocalizedString("Extract_Stack", comment: ""))
96+
.onHover { inside in
97+
if inside {
98+
NSCursor.pointingHand.push()
99+
} else {
100+
NSCursor.pop()
101+
}
102+
}
103+
}
104+
}
105+
.onOpenURL { url in
106+
DeepLinkManager.handleDeepLink(url: url)
88107
}
89-
}
90-
}
91-
.onOpenURL { url in
92-
DeepLinkManager.handleDeepLink(url: url)
93108
}
94-
}
95109
}
96110

97111

98112
final class SnipViewAppViewModel: ObservableObject {
99-
100-
@Published var snippets: [SnipItem] = []
101-
@Published var selectionSnipItem: SnipItem?
102-
@Published var snippetManager = SnippetManager.shared
103-
@Published var modalView: ModalView?
104-
105-
var appState: AppState
106-
var settings: Settings
107-
108-
var cancellables: Set<AnyCancellable> = []
109-
110-
var sidebarViewModel: SideBarViewModel?
111-
var codeViewerViewModel: CodeViewerViewModel?
112-
113-
init(appState: AppState,
114-
settings: Settings) {
115-
116-
self.appState = appState
117-
self.settings = settings
118-
119-
SnippetManager
120-
.shared
121-
.snipets
122-
.sink { [weak self] (snippets) in
123-
guard let this = self else { return }
124-
this.snippets = snippets
125-
this.selectionSnipItem = snippets.flatternSnippets.first(where: { $0.id == appState.selectedSnippetId })
126-
}
127-
.store(in: &stores)
128-
129-
Publishers.CombineLatest3(settings.$shouldOpenSettings, appState.$shouldOpenWelcome, snippetManager.$hasExternalSnippetQueued)
130-
.map(triggerModalOpening(openSettings:openWelcome:openExternalSnippet:))
131-
.sink { [weak self] (modalView) in
132-
guard let this = self else { return }
133-
this.modalView = modalView
134-
}
135-
.store(in: &stores)
136-
137-
sidebarViewModel = SideBarViewModel(snippets: $snippets.eraseToAnyPublisher(),
138-
onTrigger: trigger(action:),
139-
onSnippetSelection: didSelectSnipItem(_:filter:))
140-
141-
codeViewerViewModel = CodeViewerViewModel(snipItem: $selectionSnipItem.eraseToAnyPublisher(),
142-
onTrigger: trigger(action:),
143-
onDimiss: didDeselectSnipItem)
144-
}
145-
146-
func trigger(action: SnipItemsListAction) {
147-
SnippetManager.shared.trigger(action: action)
148-
}
149-
150-
func triggerModalOpening(openSettings: Bool, openWelcome: Bool, openExternalSnippet: Bool) -> ModalView? {
151-
if openWelcome {
152-
return .welcome
113+
114+
@Published var snippets: [SnipItem] = []
115+
@Published var selectionSnipItem: SnipItem?
116+
@Published var snippetManager = SnippetManager.shared
117+
@Published var modalView: ModalView?
118+
119+
var appState: AppState
120+
var settings: Settings
121+
122+
var cancellables: Set<AnyCancellable> = []
123+
124+
var sidebarViewModel: SideBarViewModel?
125+
var codeViewerViewModel: CodeViewerViewModel?
126+
127+
init(appState: AppState,
128+
settings: Settings) {
129+
130+
self.appState = appState
131+
self.settings = settings
132+
133+
SnippetManager
134+
.shared
135+
.snipets
136+
.sink { [weak self] (snippets) in
137+
guard let this = self else { return }
138+
this.snippets = snippets
139+
this.selectionSnipItem = snippets.flatternSnippets.first(where: { $0.id == appState.selectedSnippetId })
140+
}
141+
.store(in: &stores)
142+
143+
Publishers.CombineLatest3(settings.$shouldOpenSettings, appState.$shouldOpenWelcome, snippetManager.$hasExternalSnippetQueued)
144+
.map(triggerModalOpening(openSettings:openWelcome:openExternalSnippet:))
145+
.sink { [weak self] (modalView) in
146+
guard let this = self else { return }
147+
this.modalView = modalView
148+
}
149+
.store(in: &stores)
150+
151+
sidebarViewModel = SideBarViewModel(snippets: $snippets.eraseToAnyPublisher(),
152+
onTrigger: trigger(action:),
153+
onSnippetSelection: didSelectSnipItem(_:filter:))
154+
155+
codeViewerViewModel = CodeViewerViewModel(snipItem: $selectionSnipItem.eraseToAnyPublisher(),
156+
onTrigger: trigger(action:),
157+
onDimiss: didDeselectSnipItem)
153158
}
154-
else if openSettings {
155-
return .settings
159+
160+
func trigger(action: SnipItemsListAction) {
161+
SnippetManager.shared.trigger(action: action)
156162
}
157-
else if openExternalSnippet {
158-
return .external
163+
164+
func triggerModalOpening(openSettings: Bool, openWelcome: Bool, openExternalSnippet: Bool) -> ModalView? {
165+
if openWelcome {
166+
return .welcome
167+
}
168+
else if openSettings {
169+
return .settings
170+
}
171+
else if openExternalSnippet {
172+
return .external
173+
}
174+
else {
175+
return nil
176+
}
159177
}
160-
else {
161-
return nil
178+
179+
func didSelectSnipItem(_ snip: SnipItem, filter: ModelFilter) {
180+
appState.selectedSnippetId = snip.id
181+
appState.selectedSnippetFilter = filter
182+
selectionSnipItem = snip
183+
}
184+
185+
func didDeselectSnipItem() {
186+
appState.selectedSnippetId = nil
187+
selectionSnipItem = nil
188+
}
189+
190+
func openExtensionLink() {
191+
guard let url = URL(string: "https://cutt.ly/whQTNO3") else { return }
192+
NSWorkspace.shared.open(url)
193+
}
194+
195+
func toggleSidebar() {
196+
NSApp.keyWindow?.firstResponder?.tryToPerform(#selector(NSSplitViewController.toggleSidebar(_:)), with: nil)
162197
}
163-
}
164-
165-
func didSelectSnipItem(_ snip: SnipItem, filter: ModelFilter) {
166-
appState.selectedSnippetId = snip.id
167-
appState.selectedSnippetFilter = filter
168-
selectionSnipItem = snip
169-
}
170-
171-
func didDeselectSnipItem() {
172-
appState.selectedSnippetId = nil
173-
selectionSnipItem = nil
174-
}
175-
176-
func openExtensionLink() {
177-
guard let url = URL(string: "https://cutt.ly/whQTNO3") else { return }
178-
NSWorkspace.shared.open(url)
179-
}
180198
}

0 commit comments

Comments
 (0)