mirror of
https://github.com/ershisan99/md-preview-desktop.git
synced 2025-12-16 20:59:24 +00:00
feat: add d'n'd listener to open files on drop
chore: apply eslint-config
This commit is contained in:
@@ -1,9 +1,3 @@
|
||||
module.exports = {
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:react/recommended',
|
||||
'plugin:react/jsx-runtime',
|
||||
'@electron-toolkit/eslint-config-ts/recommended',
|
||||
'@electron-toolkit/eslint-config-prettier'
|
||||
]
|
||||
extends: '@it-incubator/eslint-config',
|
||||
}
|
||||
15
.idea/git_toolbox_prj.xml
generated
Normal file
15
.idea/git_toolbox_prj.xml
generated
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="GitToolBoxProjectSettings">
|
||||
<option name="commitMessageIssueKeyValidationOverride">
|
||||
<BoolValueOverride>
|
||||
<option name="enabled" value="true" />
|
||||
</BoolValueOverride>
|
||||
</option>
|
||||
<option name="commitMessageValidationEnabledOverride">
|
||||
<BoolValueOverride>
|
||||
<option name="enabled" value="true" />
|
||||
</BoolValueOverride>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
||||
1
.idea/prettier.xml
generated
1
.idea/prettier.xml
generated
@@ -3,5 +3,6 @@
|
||||
<component name="PrettierConfiguration">
|
||||
<option name="myConfigurationMode" value="AUTOMATIC" />
|
||||
<option name="myRunOnSave" value="true" />
|
||||
<option name="myFilesPattern" value="{**/*,*}.{js,ts,jsx,tsx,vue,astro,css,cjs,mjs,json,scss}" />
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
6
.idea/vcs.xml
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
3
.prettierrc.cjs
Normal file
3
.prettierrc.cjs
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
...require('@it-incubator/prettier-config'),
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
singleQuote: true
|
||||
semi: false
|
||||
printWidth: 100
|
||||
trailingComma: none
|
||||
3
.stylelintrc.cjs
Normal file
3
.stylelintrc.cjs
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
extends: '@it-incubator/stylelint-config',
|
||||
}
|
||||
@@ -1,11 +1,10 @@
|
||||
import { resolve } from 'path'
|
||||
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
||||
|
||||
import react from '@vitejs/plugin-react'
|
||||
import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
||||
|
||||
export default defineConfig({
|
||||
main: {
|
||||
// plugins: [externalizeDepsPlugin({ exclude: ['@it-incubator/md-bundler', 'builtin-modules'] })],
|
||||
plugins: [externalizeDepsPlugin({ exclude: ['rehype-slug'] })],
|
||||
build: {
|
||||
rollupOptions: {
|
||||
// external: ['builtin-modules'],
|
||||
@@ -22,18 +21,20 @@ export default defineConfig({
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
// plugins: [externalizeDepsPlugin({ exclude: ['@it-incubator/md-bundler', 'builtin-modules'] })],
|
||||
plugins: [externalizeDepsPlugin({ exclude: ['rehype-slug'] })],
|
||||
},
|
||||
preload: {
|
||||
plugins: [externalizeDepsPlugin()]
|
||||
plugins: [externalizeDepsPlugin()],
|
||||
},
|
||||
renderer: {
|
||||
plugins: [react()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@renderer': resolve('src/renderer/src')
|
||||
}
|
||||
'@renderer': resolve('src/renderer/src'),
|
||||
},
|
||||
},
|
||||
plugins: [react()]
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
"@electron-toolkit/preload": "^2.0.0",
|
||||
"@electron-toolkit/utils": "^2.0.0",
|
||||
"@fontsource/roboto": "^5.0.8",
|
||||
"@it-incubator/mdx-components": "^0.0.2",
|
||||
"@it-incubator/ui-kit": "^0.2.7",
|
||||
"builtin-modules": "^3.3.0",
|
||||
"chokidar": "^3.5.3",
|
||||
@@ -38,6 +39,9 @@
|
||||
"@electron-toolkit/eslint-config-prettier": "^1.0.1",
|
||||
"@electron-toolkit/eslint-config-ts": "^1.0.0",
|
||||
"@electron-toolkit/tsconfig": "^1.0.1",
|
||||
"@it-incubator/eslint-config": "^1.0.1",
|
||||
"@it-incubator/prettier-config": "^0.1.2",
|
||||
"@it-incubator/stylelint-config": "^0.1.5",
|
||||
"@types/node": "^18.17.5",
|
||||
"@types/react": "^18.2.20",
|
||||
"@types/react-dom": "^18.2.7",
|
||||
|
||||
1092
pnpm-lock.yaml
generated
1092
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -9,8 +9,9 @@ import { BundledMdx } from './types'
|
||||
|
||||
export const bundleMdx = async (source: string): Promise<BundledMdx> => {
|
||||
return await bundleMDX({
|
||||
source,
|
||||
globals: {},
|
||||
globals: {
|
||||
components: '@it-incubator/mdx-components',
|
||||
},
|
||||
mdxOptions(options) {
|
||||
options.rehypePlugins = [
|
||||
...(options.rehypePlugins ?? []),
|
||||
@@ -19,7 +20,13 @@ export const bundleMdx = async (source: string): Promise<BundledMdx> => {
|
||||
[
|
||||
rehypePrettyCode,
|
||||
{
|
||||
theme,
|
||||
filterMetaString: (meta: string) => meta.replace(CODE_BLOCK_FILENAME_REGEX, ''),
|
||||
onVisitHighlightedChars(node: any) {
|
||||
node.properties.className = ['highlighted']
|
||||
},
|
||||
onVisitHighlightedLine(node: any) {
|
||||
node.properties.className.push('highlighted')
|
||||
},
|
||||
onVisitLine(node: any) {
|
||||
// Prevent lines from collapsing in `display: grid` mode, and
|
||||
// allow empty lines to be copy/pasted
|
||||
@@ -27,19 +34,14 @@ export const bundleMdx = async (source: string): Promise<BundledMdx> => {
|
||||
node.children = [{ type: 'text', value: ' ' }]
|
||||
}
|
||||
},
|
||||
onVisitHighlightedLine(node: any) {
|
||||
node.properties.className.push('highlighted')
|
||||
},
|
||||
onVisitHighlightedChars(node: any) {
|
||||
node.properties.className = ['highlighted']
|
||||
},
|
||||
filterMetaString: (meta: string) => meta.replace(CODE_BLOCK_FILENAME_REGEX, '')
|
||||
}
|
||||
theme,
|
||||
},
|
||||
],
|
||||
attachMeta
|
||||
attachMeta,
|
||||
]
|
||||
|
||||
return options
|
||||
}
|
||||
},
|
||||
source,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,33 +1,37 @@
|
||||
import { app, shell, BrowserWindow } from 'electron'
|
||||
import { join } from 'path'
|
||||
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
||||
import icon from '../../resources/icon.png?asset'
|
||||
import path from 'node:path'
|
||||
import fs from 'fs'
|
||||
import path from 'node:path'
|
||||
import { join } from 'path'
|
||||
|
||||
import { electronApp, is, optimizer } from '@electron-toolkit/utils'
|
||||
import { BrowserWindow, app, ipcMain, shell } from 'electron'
|
||||
|
||||
import icon from '../../resources/icon.png?asset'
|
||||
import { bundleMdx } from './bundle-mdx'
|
||||
const chokidar = require('chokidar')
|
||||
|
||||
let mainWindow: BrowserWindow | null = null
|
||||
|
||||
function createWindow(): void {
|
||||
// Create the browser window.
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 900,
|
||||
autoHideMenuBar: true,
|
||||
height: 670,
|
||||
show: false,
|
||||
autoHideMenuBar: true,
|
||||
width: 900,
|
||||
...(process.platform === 'linux' ? { icon } : {}),
|
||||
webPreferences: {
|
||||
preload: join(__dirname, '../preload/index.js'),
|
||||
sandbox: false
|
||||
}
|
||||
sandbox: false,
|
||||
},
|
||||
})
|
||||
|
||||
mainWindow.on('ready-to-show', () => {
|
||||
mainWindow?.show()
|
||||
})
|
||||
|
||||
mainWindow.webContents.setWindowOpenHandler((details) => {
|
||||
mainWindow.webContents.setWindowOpenHandler(details => {
|
||||
shell.openExternal(details.url)
|
||||
|
||||
return { action: 'deny' }
|
||||
})
|
||||
|
||||
@@ -59,7 +63,9 @@ app.whenReady().then(() => {
|
||||
app.on('activate', function () {
|
||||
// On macOS it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (BrowserWindow.getAllWindows().length === 0) createWindow()
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
@@ -71,32 +77,57 @@ app.on('window-all-closed', () => {
|
||||
app.quit()
|
||||
}
|
||||
})
|
||||
console.log('dirname', __dirname)
|
||||
// In this file you can include the rest of your app"s specific main process
|
||||
// code. You can also put them in separate files and require them here.
|
||||
const watcher = chokidar.watch(path.resolve(__dirname, '../../../hello.md'), {
|
||||
ignored: /(^|[\/\\])\../, // ignore dotfiles
|
||||
persistent: true
|
||||
})
|
||||
|
||||
// Something to use when events are received.
|
||||
const log = console.log.bind(console)
|
||||
// Add event listeners.
|
||||
watcher
|
||||
.on('add', (path) => log(`File ${path} has been added`))
|
||||
.on('change', (path) => {
|
||||
let watcher: any = null
|
||||
|
||||
function setupWatcher(filePath: string) {
|
||||
// Close the existing watcher if it exists
|
||||
if (watcher) {
|
||||
watcher.close()
|
||||
}
|
||||
|
||||
watcher = chokidar.watch(filePath, {
|
||||
ignored: /(^|[/\\])\../, // ignore dotfiles
|
||||
persistent: true,
|
||||
})
|
||||
|
||||
const bundleAndSend = async (path: string) => {
|
||||
fs.readFile(path, 'utf8', async (err, content) => {
|
||||
if (err) {
|
||||
console.error('Error reading the file:', err)
|
||||
|
||||
return
|
||||
}
|
||||
console.log('content', content)
|
||||
// Send file content to renderer
|
||||
if (mainWindow && !mainWindow.isDestroyed()) {
|
||||
const bundled = await bundleMdx(content)
|
||||
// const toc = generateToc(content, {})
|
||||
mainWindow.webContents.send('file-changed', bundled)
|
||||
|
||||
mainWindow.webContents.send('file-changed', { ...bundled, fileName: path })
|
||||
}
|
||||
})
|
||||
})
|
||||
.on('unlink', (path) => log(`File ${path} has been removed`))
|
||||
await shell.openPath(path)
|
||||
}
|
||||
|
||||
// Add your event listeners
|
||||
watcher
|
||||
.on('add', async (path: string) => {
|
||||
await bundleAndSend(path)
|
||||
|
||||
console.warn(`File ${path} has been added`)
|
||||
})
|
||||
.on('change', bundleAndSend)
|
||||
.on('unlink', (path: string) => console.warn(`File ${path} has been removed`))
|
||||
}
|
||||
|
||||
ipcMain.on('dropped-file', (event, arg) => {
|
||||
console.warn('Dropped File(s):', arg)
|
||||
event.returnValue = `Received ${arg.length} paths.` // Synchronous reply
|
||||
|
||||
// Assuming the user only dropped one file, update the watcher to watch that file.
|
||||
if (arg.length > 0) {
|
||||
setupWatcher(arg[0])
|
||||
}
|
||||
})
|
||||
|
||||
// Initially setup watcher for 'hello.md'
|
||||
setupWatcher(path.resolve(__dirname, '../../../hello.md'))
|
||||
|
||||
@@ -15,8 +15,8 @@ function visit(node, tagNames, handler) {
|
||||
|
||||
export const parseMeta =
|
||||
({ defaultShowCopyCode }) =>
|
||||
(tree) => {
|
||||
visit(tree, ['pre'], (preEl) => {
|
||||
tree => {
|
||||
visit(tree, ['pre'], preEl => {
|
||||
const [codeEl] = preEl.children
|
||||
|
||||
// Add default language `text` for code-blocks without languages
|
||||
@@ -31,8 +31,8 @@ export const parseMeta =
|
||||
})
|
||||
}
|
||||
|
||||
export const attachMeta = () => (tree) => {
|
||||
visit(tree, ['div', 'pre'], (node) => {
|
||||
export const attachMeta = () => tree => {
|
||||
visit(tree, ['div', 'pre'], node => {
|
||||
if ('data-rehype-pretty-code-fragment' in node.properties) {
|
||||
// remove <div data-rehype-pretty-code-fragment /> element that wraps <pre /> element
|
||||
// because we'll wrap with our own <div />
|
||||
|
||||
2
src/preload/index.d.ts
vendored
2
src/preload/index.d.ts
vendored
@@ -2,7 +2,7 @@ import { ElectronAPI } from '@electron-toolkit/preload'
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
electron: ElectronAPI
|
||||
api: unknown
|
||||
electron: ElectronAPI
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { contextBridge } from 'electron'
|
||||
import { electronAPI } from '@electron-toolkit/preload'
|
||||
import { contextBridge } from 'electron'
|
||||
|
||||
// Custom APIs for renderer
|
||||
const api = {}
|
||||
|
||||
@@ -1,50 +1,64 @@
|
||||
import { ComponentProps, ReactElement, useEffect, useState } from 'react'
|
||||
|
||||
import { IpcRendererListener } from '@electron-toolkit/preload'
|
||||
import * as components from '@it-incubator/mdx-components'
|
||||
import { ImagePreview, Typography } from '@it-incubator/ui-kit'
|
||||
import { getMDXComponent } from 'mdx-bundler/client'
|
||||
|
||||
import s from './view.module.scss'
|
||||
|
||||
import { Pre } from './components/pre'
|
||||
import { ImagePreview } from '@it-incubator/ui-kit'
|
||||
function App() {
|
||||
const [code, setCode] = useState<any>()
|
||||
const [code, setCode] = useState<string>('')
|
||||
const [fileName, setFileName] = useState<string>('')
|
||||
const [srcPreview, setSrcPreview] = useState<string>('')
|
||||
console.log(code)
|
||||
|
||||
useEffect(() => {
|
||||
const listener = (event, content) => {
|
||||
console.log('file-changed', event, content)
|
||||
const listener: IpcRendererListener = (_event, content) => {
|
||||
setCode(content.code)
|
||||
setFileName(content.fileName)
|
||||
}
|
||||
console.log(window.electron)
|
||||
|
||||
window.electron.ipcRenderer.on('file-changed', listener)
|
||||
|
||||
return () => {
|
||||
window.electron.ipcRenderer.removeAllListeners('file-changed')
|
||||
}
|
||||
}, [])
|
||||
if (!code) return null
|
||||
const Component = getMDXComponent(code)
|
||||
|
||||
if (!code) {
|
||||
return null
|
||||
}
|
||||
|
||||
const Component = getMDXComponent(code, { components: components })
|
||||
|
||||
return (
|
||||
<article className={s.root}>
|
||||
<ImagePreview open={!!srcPreview} src={srcPreview} onClose={() => setSrcPreview('')} />
|
||||
<Component
|
||||
components={{
|
||||
code: Code,
|
||||
pre: Pre,
|
||||
img: (props) => (
|
||||
<img
|
||||
{...props}
|
||||
onClick={() => setSrcPreview(props.src || '')}
|
||||
style={{ cursor: 'pointer' }}
|
||||
/>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</article>
|
||||
<div>
|
||||
<Typography.H1>{fileName}</Typography.H1>
|
||||
<article className={s.root}>
|
||||
<ImagePreview onClose={() => setSrcPreview('')} open={!!srcPreview} src={srcPreview} />
|
||||
<Component
|
||||
components={{
|
||||
code: Code,
|
||||
img: props => (
|
||||
<img
|
||||
{...props}
|
||||
onClick={() => setSrcPreview(props.src || '')}
|
||||
style={{ cursor: 'pointer' }}
|
||||
/>
|
||||
),
|
||||
pre: Pre,
|
||||
}}
|
||||
/>
|
||||
</article>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
||||
const Code = ({ children, ...props }: ComponentProps<'code'>): ReactElement => {
|
||||
return (
|
||||
<code className={s.inline} dir="ltr" {...props}>
|
||||
<code className={s.inline} dir={'ltr'} {...props}>
|
||||
{children}
|
||||
</code>
|
||||
)
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { useState } from 'react'
|
||||
|
||||
function Versions(): JSX.Element {
|
||||
function Versions() {
|
||||
const [versions] = useState(window.electron.process.versions)
|
||||
|
||||
return (
|
||||
<ul className="versions">
|
||||
<li className="electron-version">Electron v{versions.electron}</li>
|
||||
<li className="chrome-version">Chromium v{versions.chrome}</li>
|
||||
<li className="node-version">Node v{versions.node}</li>
|
||||
<li className="v8-version">V8 v{versions.v8}</li>
|
||||
<ul className={'versions'}>
|
||||
<li className={'electron-version'}>Electron v{versions.electron}</li>
|
||||
<li className={'chrome-version'}>Chromium v{versions.chrome}</li>
|
||||
<li className={'node-version'}>Node v{versions.node}</li>
|
||||
<li className={'v8-version'}>V8 v{versions.v8}</li>
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,13 @@ import type { ComponentProps, ReactElement } from 'react'
|
||||
|
||||
export function CheckIcon(props: ComponentProps<'svg'>): ReactElement {
|
||||
return (
|
||||
<svg viewBox="0 0 20 20" width="1em" height="1em" fill="currentColor" {...props}>
|
||||
<svg fill={'currentColor'} height={'1em'} viewBox={'0 0 20 20'} width={'1em'} {...props}>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clipRule="evenodd"
|
||||
clipRule={'evenodd'}
|
||||
d={
|
||||
'M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z'
|
||||
}
|
||||
fillRule={'evenodd'}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { ComponentProps, ReactElement } from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { ComponentProps, ReactElement, useCallback, useEffect, useState } from 'react'
|
||||
|
||||
import { clsx } from 'clsx'
|
||||
|
||||
import s from './copy-to-clipboard.module.scss'
|
||||
|
||||
import { CheckIcon } from './check'
|
||||
import { CopyIcon } from './copy'
|
||||
import s from './copy-to-clipboard.module.scss'
|
||||
|
||||
export const CopyToClipboard = ({
|
||||
getValue,
|
||||
@@ -16,7 +16,9 @@ export const CopyToClipboard = ({
|
||||
const [isCopied, setCopied] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
if (!isCopied) return
|
||||
if (!isCopied) {
|
||||
return
|
||||
}
|
||||
const timerId = setTimeout(() => {
|
||||
setCopied(false)
|
||||
}, 2000)
|
||||
@@ -41,7 +43,7 @@ export const CopyToClipboard = ({
|
||||
const IconToUse = isCopied ? CheckIcon : CopyIcon
|
||||
|
||||
return (
|
||||
<button onClick={handleClick} className={s.button} title="Copy code" tabIndex={0} {...props}>
|
||||
<button className={s.button} onClick={handleClick} tabIndex={0} title={'Copy code'} {...props}>
|
||||
<IconToUse className={clsx('nextra-copy-icon', s.root)} />
|
||||
</button>
|
||||
)
|
||||
|
||||
@@ -3,29 +3,31 @@ import type { ComponentProps, ReactElement } from 'react'
|
||||
export function CopyIcon(props: ComponentProps<'svg'>): ReactElement {
|
||||
return (
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
stroke="currentColor"
|
||||
fill={'none'}
|
||||
height={'24'}
|
||||
stroke={'currentColor'}
|
||||
viewBox={'0 0 24 24'}
|
||||
width={'24'}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<rect
|
||||
x="9"
|
||||
y="9"
|
||||
width="13"
|
||||
height="13"
|
||||
rx="2"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
height={'13'}
|
||||
rx={'2'}
|
||||
strokeLinecap={'round'}
|
||||
strokeLinejoin={'round'}
|
||||
strokeWidth={'2'}
|
||||
width={'13'}
|
||||
x={'9'}
|
||||
y={'9'}
|
||||
/>
|
||||
<path
|
||||
d="M5 15H4C2.89543 15 2 14.1046 2 13V4C2 2.89543 2.89543 2 4 2H13C14.1046 2 15 2.89543 15 4V5"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
d={
|
||||
'M5 15H4C2.89543 15 2 14.1046 2 13V4C2 2.89543 2.89543 2 4 2H13C14.1046 2 15 2.89543 15 4V5'
|
||||
}
|
||||
strokeLinecap={'round'}
|
||||
strokeLinejoin={'round'}
|
||||
strokeWidth={'2'}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
@@ -3,8 +3,9 @@ import { ComponentProps, ReactElement, useRef } from 'react'
|
||||
import { Scrollbar } from '@it-incubator/ui-kit'
|
||||
import { clsx } from 'clsx'
|
||||
|
||||
import { CopyToClipboard } from './copy-to-clipboard'
|
||||
import styles from './pre.module.scss'
|
||||
|
||||
import { CopyToClipboard } from './copy-to-clipboard'
|
||||
export const Pre = ({
|
||||
children,
|
||||
className,
|
||||
|
||||
@@ -1,12 +1,34 @@
|
||||
import React from 'react'
|
||||
|
||||
import ReactDOM from 'react-dom/client'
|
||||
|
||||
import './assets/index.css'
|
||||
import '@fontsource/roboto/400.css'
|
||||
import '@fontsource/roboto/500.css'
|
||||
import '@fontsource/roboto/700.css'
|
||||
import '@it-incubator/mdx-components/dist/style.css'
|
||||
import '@it-incubator/ui-kit/dist/style.css'
|
||||
import './assets/index.css'
|
||||
|
||||
import App from './App'
|
||||
|
||||
document.addEventListener('dragover', e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
})
|
||||
|
||||
document.addEventListener('drop', event => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
if (!event?.dataTransfer?.files.length) {
|
||||
return
|
||||
}
|
||||
const pathArr: string[] = []
|
||||
|
||||
for (const f of event.dataTransfer.files) {
|
||||
pathArr.push(f.path) // assemble array for main.js
|
||||
}
|
||||
window.electron.ipcRenderer.sendSync('dropped-file', pathArr)
|
||||
})
|
||||
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
|
||||
Reference in New Issue
Block a user