chore: replace local components with mdx-components lib

feat: directory selection working
feat: theme toggle working
This commit is contained in:
andres
2023-10-17 17:31:31 +02:00
parent ca68482061
commit 99ce64db38
31 changed files with 791 additions and 990 deletions

View File

@@ -3,11 +3,14 @@ import path from 'node:path'
import { join } from 'path'
import { electronApp, is, optimizer } from '@electron-toolkit/utils'
import { bundleMdx } from '@it-incubator/md-bundler'
import { bundleMdx, generateToc } from '@it-incubator/md-bundler'
import { BrowserWindow, app, ipcMain, shell } from 'electron'
import Store from 'electron-store'
import icon from '../../resources/icon.png?asset'
const chokidar = require('chokidar')
const store = new Store()
let mainWindow: BrowserWindow | null = null
@@ -35,6 +38,11 @@ function createWindow(): void {
return { action: 'deny' }
})
mainWindow.webContents.on('will-navigate', (event, url) => {
event.preventDefault()
shell.openExternal(url)
})
// HMR for renderer base on electron-vite cli.
// Load the remote URL for development or the local html file for production.
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
@@ -79,8 +87,10 @@ app.on('window-all-closed', () => {
})
let watcher: any = null
let currentContent: any = null
function setupWatcher(filePath: string) {
store.set('lastFilePath', filePath)
// Close the existing watcher if it exists
if (watcher) {
watcher.close()
@@ -101,13 +111,18 @@ function setupWatcher(filePath: string) {
// Send file content to renderer
if (mainWindow && !mainWindow.isDestroyed()) {
const bundled = await bundleMdx(content)
const toc = await generateToc(content, {})
const newContent = { ...bundled, fileName: path, toc }
mainWindow.webContents.send('file-changed', { ...bundled, fileName: path })
currentContent = newContent
mainWindow.webContents.send('current-content', newContent)
}
})
await shell.openPath(path)
// await shell.openPath(path)
}
bundleAndSend(filePath)
// Add your event listeners
watcher
.on('add', async (path: string) => {
@@ -119,15 +134,147 @@ function setupWatcher(filePath: string) {
.on('unlink', (path: string) => console.warn(`File ${path} has been removed`))
}
function prepareAndSendDir(dir: string) {
const files = fs.readdirSync(dir)
const dirName = path.basename(dir)
const data = [
{
children: getFilesRecursive(
dir,
['.md', '.mdx'],
['node_modules', 'README.md'],
true,
dir + '/'
),
name: dirName,
path: dir,
type: FsEntryType.Directory,
},
]
// Send the list of files to the renderer process
mainWindow?.webContents.send('directory-contents', { data, dir, dirName, files })
store.set('lastOpenDir', dir)
}
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.
event.returnValue = `Received ${arg.length} paths.`
if (!mainWindow) {
throw new Error('mainWindow is not defined')
}
if (arg.length > 0) {
setupWatcher(arg[0])
const pathToCheck = arg[0]
if (fs.statSync(pathToCheck).isDirectory()) {
// If it's a directory, get the list of files
prepareAndSendDir(pathToCheck)
} else {
setupWatcher(pathToCheck)
}
}
})
ipcMain.on('get-current-content', event => {
event.reply('current-content', currentContent)
})
ipcMain.on('get-current-dir', () => {
const lastOpenDir = store.get('lastOpenDir') as string | undefined
if (!lastOpenDir) {
return
}
prepareAndSendDir(lastOpenDir)
})
ipcMain.on('open-file', (_event, filePath) => {
setupWatcher(filePath)
})
const lastFilePath = store.get('lastFilePath') as string | undefined
const lastOpenDir = store.get('lastOpenDir') as string | undefined
if (lastOpenDir) {
prepareAndSendDir(lastOpenDir)
}
// Initially setup watcher for 'hello.md'
setupWatcher(path.resolve(__dirname, '../../../hello.md'))
setupWatcher(lastFilePath ?? path.resolve(__dirname, '../../../hello.md'))
function getFilesRecursive(
directory: string,
allowedExtensions: string[] = [],
ignoredPaths: string[] = [],
includeParent = true,
prefix = ''
): FileOrDirectory[] {
const fileList: FileOrDirectory[] = []
const filesAndDirs = fs.readdirSync(directory)
for (const fileOrDir of filesAndDirs) {
const absolutePath = path.join(directory, fileOrDir)
const relativePath = path.join(prefix, fileOrDir)
// Skip dotfiles and dot directories
if (fileOrDir.startsWith('.')) {
continue
}
// Skip ignored files and directories
if (ignoredPaths.some(ignoredPath => absolutePath.includes(ignoredPath))) {
continue
}
if (fs.statSync(absolutePath).isDirectory()) {
const nestedFiles = getFilesRecursive(
absolutePath,
allowedExtensions,
ignoredPaths,
includeParent,
relativePath + '/'
)
fileList.push({
children: nestedFiles,
name: fileOrDir,
path: relativePath,
type: FsEntryType.Directory,
})
} else {
const extension = path.extname(fileOrDir).toLowerCase()
// Check the file has an allowed extension
if (
allowedExtensions.length === 0 ||
allowedExtensions.map(e => e.toLowerCase()).includes(extension)
) {
fileList.push({
name: fileOrDir,
path: relativePath,
type: FsEntryType.File,
})
}
}
}
return fileList
}
enum FsEntryType {
Directory = 'directory',
File = 'file',
}
type File = {
name: string
path: string
type: FsEntryType.File
}
type Directory = {
children: Array<FileOrDirectory>
name: string
path: string
type: FsEntryType.Directory
}
type FileOrDirectory = Directory | File