Skip to content

Commit 6d14e7d

Browse files
feat: update main menu (#21)
1 parent 7324926 commit 6d14e7d

File tree

11 files changed

+233
-59
lines changed

11 files changed

+233
-59
lines changed

src/main/menu/main.ts

Lines changed: 114 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { createMenu } from '../components/menu'
22
import type { MenuItemConstructorOptions } from 'electron'
3-
import { dialog, app, BrowserWindow } from 'electron'
3+
import { shell, dialog, app, BrowserWindow } from 'electron'
44
import { version, author } from '../../../package.json'
55
import os from 'os'
66

@@ -78,10 +78,6 @@ const appMenu: MenuItemConstructorOptions[] = [
7878
]
7979

8080
const helpMenu: MenuItemConstructorOptions[] = [
81-
{
82-
label: 'Toogle Dev tools',
83-
role: 'toggleDevTools'
84-
},
8581
{
8682
label: 'About',
8783
click () {
@@ -100,6 +96,62 @@ const helpMenu: MenuItemConstructorOptions[] = [
10096
`
10197
})
10298
}
99+
},
100+
{
101+
label: 'Website',
102+
click: () => {
103+
shell.openExternal('https://masscode.io')
104+
}
105+
},
106+
{
107+
label: 'Change Log',
108+
click: () => {
109+
shell.openExternal(
110+
'https://github.com/massCodeIO/massCode/blob/master/CHANGELOG.md'
111+
)
112+
}
113+
},
114+
{
115+
label: 'Documentation',
116+
click: () => {
117+
shell.openExternal('https://masscode.io/documentation')
118+
}
119+
},
120+
{
121+
label: 'View in GitHub',
122+
click: () => {
123+
shell.openExternal('https://github.com/massCodeIO/massCode')
124+
}
125+
},
126+
{
127+
label: 'Report Issue',
128+
click: () => {
129+
shell.openExternal(
130+
'https://github.com/massCodeIO/massCode/issues/new/choose'
131+
)
132+
}
133+
},
134+
{
135+
type: 'separator'
136+
},
137+
{
138+
label: 'Donate',
139+
click: () => {
140+
shell.openExternal('https://opencollective.com/masscode')
141+
}
142+
},
143+
{
144+
label: 'Twitter',
145+
click: () => {
146+
shell.openExternal('https://twitter.com/anton_reshetov')
147+
}
148+
},
149+
{
150+
type: 'separator'
151+
},
152+
{
153+
label: 'Toggle Developer Tools',
154+
role: 'toggleDevTools'
103155
}
104156
]
105157

@@ -110,15 +162,72 @@ if (isDev) {
110162
})
111163
}
112164

165+
const fileMenu: MenuItemConstructorOptions[] = [
166+
{
167+
label: 'New Snippet',
168+
accelerator: 'CommandOrControl+N',
169+
click: () => {
170+
BrowserWindow.getFocusedWindow()?.webContents.send(
171+
'main-menu:new-snippet'
172+
)
173+
}
174+
},
175+
{
176+
label: 'New Fragment',
177+
accelerator: 'CommandOrControl+T',
178+
click: () => {
179+
BrowserWindow.getFocusedWindow()?.webContents.send(
180+
'main-menu:new-fragment'
181+
)
182+
}
183+
},
184+
{
185+
label: 'New Folder',
186+
accelerator: 'CommandOrControl+Shift+N',
187+
click: () => {
188+
BrowserWindow.getFocusedWindow()?.webContents.send('main-menu:new-folder')
189+
}
190+
}
191+
]
192+
193+
const editorMenu: MenuItemConstructorOptions[] = [
194+
{
195+
label: 'Copy Snippet to Clipboard',
196+
accelerator: 'Shift+CommandOrControl+C',
197+
click: () => {
198+
BrowserWindow.getFocusedWindow()?.webContents.send(
199+
'main-menu:copy-snippet'
200+
)
201+
}
202+
},
203+
{
204+
label: 'Preview Markdown',
205+
accelerator: 'Shift+CommandOrControl+M',
206+
click: () => {
207+
BrowserWindow.getFocusedWindow()?.webContents.send(
208+
'main-menu:preview-markdown'
209+
)
210+
}
211+
}
212+
]
213+
113214
const menuItems: MenuItemConstructorOptions[] = [
114215
{
115216
label: 'massCode',
116217
submenu: isMac ? appMenuMac : appMenu
117218
},
219+
{
220+
label: 'File',
221+
submenu: fileMenu
222+
},
118223
{
119224
label: 'Edit',
120225
role: 'editMenu'
121226
},
227+
{
228+
label: 'Editor',
229+
submenu: editorMenu
230+
},
122231
{
123232
label: 'Help',
124233
submenu: helpMenu

src/renderer/App.vue

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ import { ipc, store, track } from './electron'
2020
import { useAppStore } from './store/app'
2121
import { repository } from '../../package.json'
2222
import { useSnippetStore } from './store/snippets'
23+
import {
24+
onAddNewSnippet,
25+
onAddNewFragment,
26+
onAddNewFolder,
27+
onCopySnippet
28+
} from '@/composable'
2329
2430
// По какой то причине необходимо явно установить роут в '/'
2531
// для корректного поведения в продакшен сборке
@@ -84,9 +90,31 @@ ipc.on('main-menu:preferences', () => {
8490
router.push('/preferences')
8591
})
8692
87-
ipc.on('main:update-available', async () => {
93+
ipc.on('main:update-available', () => {
8894
isUpdateAvailable.value = true
8995
})
96+
97+
ipc.on('main-menu:new-folder', async () => {
98+
await onAddNewFolder()
99+
})
100+
101+
ipc.on('main-menu:new-snippet', async () => {
102+
await onAddNewSnippet()
103+
})
104+
105+
ipc.on('main-menu:new-fragment', () => {
106+
onAddNewFragment()
107+
})
108+
109+
ipc.on('main-menu:preview-markdown', async () => {
110+
if (snippetStore.currentLanguage === 'markdown') {
111+
snippetStore.isMarkdownPreview = !snippetStore.isMarkdownPreview
112+
}
113+
})
114+
115+
ipc.on('main-menu:copy-snippet', () => {
116+
onCopySnippet()
117+
})
90118
</script>
91119

92120
<style lang="scss">

src/renderer/components/sidebar/SidebarList.vue

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
</div>
2727
</div>
2828
<div
29-
ref="listRef"
29+
ref="bodyRef"
3030
class="body"
3131
:class="{ 'is-system': isSystem }"
3232
>
@@ -46,8 +46,9 @@
4646
</template>
4747

4848
<script setup lang="ts">
49-
import { computed } from 'vue'
49+
import { computed, nextTick, ref } from 'vue'
5050
import type { Tab, Tabs } from '@shared/types/renderer/sidebar'
51+
import { emitter, setScrollPosition } from '@/composable'
5152
5253
interface Props {
5354
title?: string
@@ -68,6 +69,8 @@ const props = withDefaults(defineProps<Props>(), {
6869
isSystem: false
6970
})
7071
72+
const bodyRef = ref<HTMLElement>()
73+
7174
const activeTab = computed({
7275
get: () => props.modelValue,
7376
set: v => {
@@ -78,6 +81,15 @@ const activeTab = computed({
7881
const onClickTab = (tab: Tab) => {
7982
activeTab.value = tab
8083
}
84+
85+
emitter.on('scroll-to:folder', id => {
86+
nextTick(() => {
87+
const el = document.querySelector<HTMLElement>(`[data-id='${id}']`)
88+
if (el) {
89+
setScrollPosition(bodyRef.value!, el.getBoundingClientRect().top + 210)
90+
}
91+
})
92+
})
8193
</script>
8294

8395
<style lang="scss" scoped>

src/renderer/components/sidebar/TheSidebar.vue

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
<template #default="{ node }">
5959
<SidebarListItem
6060
:id="node.id"
61+
:data-id="node.id"
6162
:is-folder="true"
6263
:model="node"
6364
@drop="onDrop($event, node.id)"
@@ -94,9 +95,9 @@ import Trash from '~icons/unicons/trash'
9495
import LabelAlt from '~icons/unicons/label-alt'
9596
import { useFolderStore } from '@/store/folders'
9697
import { useSnippetStore } from '@/store/snippets'
97-
import { ipc, store, track } from '@/electron'
98+
import { ipc, store } from '@/electron'
9899
import { useTagStore } from '@/store/tags'
99-
import { emitter } from '@/composable'
100+
import { emitter, onAddNewFolder } from '@/composable'
100101
import interact from 'interactjs'
101102
import { useAppStore } from '@/store/app'
102103
@@ -159,11 +160,6 @@ const contextMenuHandler = () => {
159160
})
160161
}
161162
162-
const onAddNewFolder = async () => {
163-
await folderStore.addNewFolder()
164-
track('folders/add-new')
165-
}
166-
167163
const onUpdate = async () => {
168164
await folderStore.updateFoldersTable()
169165
}

src/renderer/components/snippets/SnippetHeader.vue

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,10 @@
3333
</template>
3434

3535
<script setup lang="ts">
36-
import { emitter } from '@/composable'
37-
import { ipc, track } from '@/electron'
36+
import { emitter, onAddNewFragment, onCopySnippet } from '@/composable'
3837
import { useSnippetStore } from '@/store/snippets'
39-
import { useClipboard, useDebounceFn } from '@vueuse/core'
38+
import { useDebounceFn } from '@vueuse/core'
4039
import { computed, ref } from 'vue'
41-
import type { NotificationRequest } from '@shared/types/main'
4240
import { useAppStore } from '@/store/app'
4341
4442
const snippetStore = useSnippetStore()
@@ -57,21 +55,6 @@ const name = computed({
5755
)
5856
})
5957
60-
const onAddNewFragment = () => {
61-
snippetStore.addNewFragmentToSnippetsById(snippetStore.selectedId!)
62-
snippetStore.fragment = snippetStore.fragmentCount!
63-
track('snippets/add-fragment')
64-
}
65-
66-
const onCopySnippet = () => {
67-
const { copy } = useClipboard({ source: snippetStore.currentContent })
68-
copy()
69-
ipc.invoke<any, NotificationRequest>('main:notification', {
70-
body: 'Snippet copied'
71-
})
72-
track('snippets/copy')
73-
}
74-
7558
const onClickMarkdownPreview = () => {
7659
snippetStore.isMarkdownPreview = !snippetStore.isMarkdownPreview
7760
}

src/renderer/components/snippets/SnippetList.vue

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
</template>
3232

3333
<script setup lang="ts">
34-
import { emitter } from '@/composable'
34+
import { emitter, setScrollPosition } from '@/composable'
3535
import { useAppStore } from '@/store/app'
3636
import { useSnippetStore } from '@/store/snippets'
3737
import { onMounted, ref, watch } from 'vue'
@@ -45,11 +45,6 @@ const listRef = ref()
4545
const bodyRef = ref<HTMLElement>()
4646
const gutterRef = ref()
4747
48-
const setScrollPosition = (offset: number) => {
49-
const ps = bodyRef.value?.querySelector<HTMLElement>('.ps')
50-
if (ps) ps.scrollTop = offset
51-
}
52-
5348
onMounted(() => {
5449
interact(listRef.value).resizable({
5550
allowFrom: gutterRef.value,
@@ -71,12 +66,12 @@ watch(
7166
const el = document.querySelector<HTMLElement>(
7267
`[data-id='${snippetStore.selectedId!}']`
7368
)
74-
if (el?.offsetTop) setScrollPosition(el.offsetTop)
69+
if (el?.offsetTop) setScrollPosition(bodyRef.value!, el.offsetTop)
7570
}
7671
)
7772
7873
emitter.on('folder:click', () => {
79-
setScrollPosition(0)
74+
setScrollPosition(bodyRef.value!, 0)
8075
})
8176
</script>
8277

src/renderer/components/snippets/SnippetListHeader.vue

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,13 @@
2323
</template>
2424

2525
<script setup lang="ts">
26-
import { emitter } from '@/composable'
27-
import { useFolderStore } from '@/store/folders'
26+
import { onAddNewSnippet } from '@/composable'
2827
import { useSnippetStore } from '@/store/snippets'
2928
import { useDebounceFn } from '@vueuse/core'
3029
import { computed } from 'vue'
3130
import { track } from '@/electron'
3231
3332
const snippetStore = useSnippetStore()
34-
const folderStore = useFolderStore()
3533
3634
const query = computed({
3735
get: () => snippetStore.searchQuery,
@@ -43,18 +41,6 @@ const query = computed({
4341
}, 300)
4442
})
4543
46-
const onAddNewSnippet = async () => {
47-
if (folderStore.selectedAlias !== undefined) return
48-
if (!folderStore.selectedId) return
49-
50-
await snippetStore.addNewSnippet()
51-
await snippetStore.getSnippetsByFolderIds(folderStore.selectedIds!)
52-
await snippetStore.getSnippets()
53-
54-
emitter.emit('focus:snippet-name', true)
55-
track('snippets/add-new')
56-
}
57-
5844
const onReset = () => {
5945
snippetStore.searchQuery = undefined
6046
snippetStore.setSnippetsByAlias('all')

0 commit comments

Comments
 (0)