Skip to content

Commit 5a744f5

Browse files
feat(snippets): add snippet link (#230)
1 parent af56bd3 commit 5a744f5

21 files changed

Lines changed: 201 additions & 20 deletions

File tree

config/electron-builder.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,12 @@ export default {
5252
extraMetadata: {
5353
main: 'src/main/index.js'
5454
},
55+
protocols: [
56+
{
57+
name: 'massCode',
58+
schemes: ['masscode']
59+
}
60+
],
5561
files: [
5662
'!**/node_modules/*/{CHANGELOG.md,README.md,README,readme.md,readme}',
5763
'!**/node_modules/*/{test,__tests__,tests,powered-test,example,examples}',

src/main/index.ts

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,24 @@ import { checkForUpdateWithInterval } from './services/update-check'
1212

1313
const isDev = process.env.NODE_ENV === 'development'
1414
const isMac = process.platform === 'darwin'
15+
const gotTheLock = app.requestSingleInstanceLock()
16+
17+
let mainWindow: BrowserWindow
1518

1619
createDb()
1720
const apiServer = new ApiServer()
1821

1922
subscribeToChannels()
2023
subscribeToDialog()
2124

25+
if (!gotTheLock) {
26+
// @ts-ignore
27+
return app.quit()
28+
}
29+
2230
function createWindow () {
2331
const bounds = store.app.get('bounds')
24-
const mainWindow = new BrowserWindow({
32+
mainWindow = new BrowserWindow({
2533
width: 1000,
2634
height: 600,
2735
...bounds,
@@ -54,6 +62,16 @@ const storeBounds = debounce((mainWindow: BrowserWindow) => {
5462
store.app.set('bounds', mainWindow.getBounds())
5563
}, 300)
5664

65+
if (process.defaultApp) {
66+
if (process.argv.length >= 2) {
67+
app.setAsDefaultProtocolClient('masscode', process.execPath, [
68+
path.resolve(process.argv[1])
69+
])
70+
}
71+
} else {
72+
app.setAsDefaultProtocolClient('masscode')
73+
}
74+
5775
app.whenReady().then(async () => {
5876
createWindow()
5977

@@ -74,6 +92,22 @@ app.on('browser-window-focus', () => {
7492
BrowserWindow.getFocusedWindow()?.webContents.send('main:focus')
7593
})
7694

95+
app.on('second-instance', (e, argv) => {
96+
if (mainWindow) {
97+
if (mainWindow.isMinimized()) mainWindow.restore()
98+
mainWindow.focus()
99+
}
100+
101+
if (process.platform !== 'darwin') {
102+
const url = argv.find(i => i.startsWith('masscode://'))
103+
BrowserWindow.getFocusedWindow()?.webContents.send('main:app-protocol', url)
104+
}
105+
})
106+
107+
app.on('open-url', (event, url) => {
108+
BrowserWindow.getFocusedWindow()?.webContents.send('main:app-protocol', url)
109+
})
110+
77111
ipcMain.handle('main:restart-api', () => {
78112
apiServer.restart()
79113
})

src/main/services/analytics/index.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,10 @@ export const track = (event: TrackEvents, payload?: string) => {
1919
? `${version}/${os}/${event}/${payload}`
2020
: `${version}/${os}/${event}`
2121

22-
if (isDev && process.env.DEBUG?.includes('analytics')) {
23-
console.log('[analytics]:', path)
22+
if (isDev) {
23+
if (process.env.DEBUG?.includes('analytics')) {
24+
console.log('[analytics]:', path)
25+
}
2426
} else {
2527
analytics.pageview(path).send()
2628
}

src/main/services/api/server.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,10 @@ export class ApiServer {
151151
}
152152
}
153153

154+
// Почему то на windows API сервер падает, не смотря на то,
155+
// что порт API свободен, поэтому просто обрабатываем ошибку
156+
server.on('error', err => console.error(err))
157+
154158
return server
155159
}
156160

src/main/services/i18n/locales/en/common.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,5 +59,6 @@
5959
"show": "Show",
6060
"collapse-all": "Collapse All",
6161
"expand-all": "Expand All",
62-
"restore": "Restore"
62+
"restore": "Restore",
63+
"copy-snippet-link": "Copy Snippet Link"
6364
}

src/main/services/i18n/locales/ru/common.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,5 +58,6 @@
5858
"show": "Show",
5959
"collapse-all": "Закрыть все",
6060
"expand-all": "Открыть все",
61-
"restore": "Восстановить"
61+
"restore": "Восстановить",
62+
"copy-snippet-link": "Скопировать ссылку"
6263
}

src/main/services/ipc/context-menu.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,17 @@ export const subscribeToContextMenu = () => {
7575
}
7676
},
7777
{ type: 'separator' },
78+
{
79+
label: i18n.t('copy-snippet-link'),
80+
click: () => {
81+
resolve({
82+
action: 'copy-snippet-link',
83+
type,
84+
data: true
85+
})
86+
}
87+
},
88+
{ type: 'separator' },
7889
{
7990
label: i18n.t('duplicate'),
8091
click: () => {

src/renderer/App.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ import {
3737
onCopySnippet,
3838
emitter,
3939
onCreateSnippet,
40-
onAddDescription
40+
onAddDescription,
41+
goToSnippet
4142
} from '@/composable'
4243
import { useRoute } from 'vue-router'
4344
import type { Snippet } from '@shared/types/main/db'
@@ -164,6 +165,13 @@ ipc.on('main:focus', () => {
164165
showSupportToast()
165166
})
166167
168+
ipc.on('main:app-protocol', (event, payload: string) => {
169+
if (/^masscode:\/\/snippets/.test(payload)) {
170+
const snippetId = payload.split('/').pop()
171+
if (snippetId) goToSnippet(snippetId)
172+
}
173+
})
174+
167175
ipc.on('main-menu:preferences', () => {
168176
router.push('/preferences')
169177
})

src/renderer/assets/scss/themes.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@
300300
}
301301

302302
[data-theme^="dark"] {
303-
a {
303+
> a {
304304
color: var(--color-contrast-medium);
305305
&:hover {
306306
color: var(--color-text);

src/renderer/components/markdown/TheMarkdown.vue

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ import { computed, onBeforeUnmount, onMounted, ref, watch, nextTick } from 'vue'
1515
import { ipc, store } from '@/electron'
1616
import { marked } from 'marked'
1717
import mermaid from 'mermaid'
18-
import { useHljsTheme } from '@/composable'
18+
import { useHljsTheme, goToSnippet } from '@/composable'
1919
import { useCodemirror } from '@/composable/codemirror'
20-
2120
import { nanoid } from 'nanoid'
2221
2322
const isDev = import.meta.env.DEV
@@ -75,7 +74,12 @@ const init = () => {
7574
}
7675
},
7776
link (href: string, title: string, text: string) {
78-
return `<a href="${href}" class="external">${text}</a>`
77+
if (/^masscode:\/\/snippets/.test(href)) {
78+
const id = href.split('/').pop()
79+
return `<a href="${href}" class="snippet-link" data-snippet-id="${id}">${text}</a>`
80+
} else {
81+
return `<a href="${href}" class="external">${text}</a>`
82+
}
7983
}
8084
}
8185
@@ -181,9 +185,11 @@ const render = () => {
181185
'type',
182186
'checked',
183187
'disabled',
184-
'id'
188+
'id',
189+
'data-*'
185190
]
186-
}
191+
},
192+
allowedSchemes: ['http', 'https', 'masscode']
187193
})
188194
189195
const re = /src="\.\//g
@@ -196,12 +202,18 @@ const render = () => {
196202
renderedHtml.value = html
197203
}
198204
199-
const openExternal = (e: Event) => {
205+
const onLink = async (e: Event) => {
200206
const el = e.target as HTMLAnchorElement
201207
e.preventDefault()
208+
202209
if (el.classList.contains('external')) {
203210
ipc.invoke('main:open-url', el.href)
204211
}
212+
213+
if (el.classList.contains('snippet-link')) {
214+
const { snippetId } = el.dataset
215+
if (snippetId) goToSnippet(snippetId)
216+
}
205217
}
206218
207219
const height = computed(() => {
@@ -257,11 +269,11 @@ watch(
257269
init()
258270
259271
onMounted(() => {
260-
document.addEventListener('click', openExternal)
272+
document.addEventListener('click', onLink)
261273
})
262274
263275
onBeforeUnmount(() => {
264-
document.removeEventListener('click', openExternal)
276+
document.removeEventListener('click', onLink)
265277
})
266278
267279
window.addEventListener('resize', () => {

0 commit comments

Comments
 (0)