mirror of
https://github.com/JannisX11/blockbench.git
synced 2025-04-06 17:31:09 +08:00
Setup vite electron
This commit is contained in:
parent
22eba0c062
commit
c9426c4465
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,5 +1,6 @@
|
||||
/dist/
|
||||
/dist-vite/
|
||||
/dist-electron/
|
||||
index.php
|
||||
electron-builder.env
|
||||
node_modules/
|
||||
|
23
.vscode/debug.script.mjs
vendored
Normal file
23
.vscode/debug.script.mjs
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import { createRequire } from 'node:module'
|
||||
import { spawn } from 'node:child_process'
|
||||
|
||||
const pkg = createRequire(import.meta.url)('../package.json')
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
// write .debug.env
|
||||
const envContent = Object.entries(pkg.debug.env).map(([key, val]) => `${key}=${val}`)
|
||||
fs.writeFileSync(path.join(__dirname, '.debug.env'), envContent.join('\n'))
|
||||
|
||||
// bootstrap
|
||||
spawn(
|
||||
// TODO: terminate `npm run dev` when Debug exits.
|
||||
process.platform === 'win32' ? 'npm.cmd' : 'npm',
|
||||
['run', 'dev'],
|
||||
{
|
||||
stdio: 'inherit',
|
||||
env: Object.assign(process.env, { VSCODE_DEBUG: 'true' }),
|
||||
},
|
||||
)
|
53
.vscode/launch.json
vendored
Normal file
53
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Debug App",
|
||||
"preLaunchTask": "Before Debug",
|
||||
"configurations": [
|
||||
"Debug Main Process",
|
||||
"Debug Renderer Process"
|
||||
],
|
||||
"presentation": {
|
||||
"hidden": false,
|
||||
"group": "",
|
||||
"order": 1
|
||||
},
|
||||
"stopAll": true
|
||||
}
|
||||
],
|
||||
"configurations": [
|
||||
{
|
||||
"name": "Debug Main Process",
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron",
|
||||
"windows": {
|
||||
"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"
|
||||
},
|
||||
"runtimeArgs": [
|
||||
"--remote-debugging-port=9229",
|
||||
"."
|
||||
],
|
||||
"envFile": "${workspaceFolder}/.vscode/.debug.env",
|
||||
"console": "integratedTerminal"
|
||||
},
|
||||
{
|
||||
"name": "Debug Renderer Process",
|
||||
"port": 9229,
|
||||
"request": "attach",
|
||||
"type": "chrome",
|
||||
"timeout": 60000,
|
||||
"skipFiles": [
|
||||
"<node_internals>/**",
|
||||
"${workspaceRoot}/node_modules/**",
|
||||
"${workspaceRoot}/dist-electron/**",
|
||||
// Skip files in host(VITE_DEV_SERVER_URL)
|
||||
"http://127.0.0.1:3344/**"
|
||||
]
|
||||
},
|
||||
]
|
||||
}
|
13
.vscode/settings.json
vendored
Normal file
13
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
"json.schemas": [
|
||||
{
|
||||
"fileMatch": [
|
||||
"/*electron-builder.json5",
|
||||
"/*electron-builder.json"
|
||||
],
|
||||
"url": "https://json.schemastore.org/electron-builder"
|
||||
}
|
||||
]
|
||||
}
|
24
.vscode/tasks.json
vendored
24
.vscode/tasks.json
vendored
@ -10,6 +10,30 @@
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "Before Debug",
|
||||
"type": "shell",
|
||||
"command": "node .vscode/.debug.script.mjs",
|
||||
"isBackground": true,
|
||||
"problemMatcher": {
|
||||
"owner": "typescript",
|
||||
"fileLocation": "relative",
|
||||
"pattern": {
|
||||
// TODO: correct "regexp"
|
||||
"regexp": "^([a-zA-Z]\\:\/?([\\w\\-]\/?)+\\.\\w+):(\\d+):(\\d+): (ERROR|WARNING)\\: (.*)$",
|
||||
"file": 1,
|
||||
"line": 3,
|
||||
"column": 4,
|
||||
"code": 5,
|
||||
"message": 6
|
||||
},
|
||||
"background": {
|
||||
"activeOnStart": true,
|
||||
"beginsPattern": "^.*VITE v.* ready in \\d* ms.*$",
|
||||
"endsPattern": "^.*\\[startup\\] Electron App.*$"
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
23
electron/electron-env.d.ts
vendored
Normal file
23
electron/electron-env.d.ts
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/// <reference types="vite-plugin-electron/electron-env" />
|
||||
|
||||
declare namespace NodeJS {
|
||||
interface ProcessEnv {
|
||||
VSCODE_DEBUG?: 'true'
|
||||
/**
|
||||
* The built directory structure
|
||||
*
|
||||
* ```tree
|
||||
* ├─┬ dist-electron
|
||||
* │ ├─┬ main
|
||||
* │ │ └── index.js > Electron-Main
|
||||
* │ └─┬ preload
|
||||
* │ └── index.mjs > Preload-Scripts
|
||||
* ├─┬ dist
|
||||
* │ └── index.html > Electron-Renderer
|
||||
* ```
|
||||
*/
|
||||
APP_ROOT: string
|
||||
/** /dist/ or /public/ */
|
||||
VITE_PUBLIC: string
|
||||
}
|
||||
}
|
@ -1,315 +1,364 @@
|
||||
const {app, BrowserWindow, Menu, ipcMain, shell} = require('electron')
|
||||
const path = require('path')
|
||||
const url = require('url')
|
||||
const { autoUpdater } = require('electron-updater');
|
||||
const fs = require('fs');
|
||||
const {getColorHexRGB} = require('electron-color-picker')
|
||||
require('@electron/remote/main').initialize()
|
||||
|
||||
let orig_win;
|
||||
let all_wins = [];
|
||||
let load_project_data;
|
||||
|
||||
(() => {
|
||||
// Allow advanced users to specify a custom userData directory.
|
||||
// Useful for portable installations, and for setting up development environments.
|
||||
const index = process.argv.findIndex(arg => arg === '--userData');
|
||||
if (index !== -1) {
|
||||
if (!process.argv.at(index + 1)) {
|
||||
console.error('No path specified after --userData')
|
||||
process.exit(1)
|
||||
}
|
||||
app.setPath('userData', process.argv[index + 1]);
|
||||
}
|
||||
})()
|
||||
|
||||
const LaunchSettings = {
|
||||
path: path.join(app.getPath('userData'), 'launch_settings.json'),
|
||||
settings: {},
|
||||
get(key) {
|
||||
return this.settings[key]
|
||||
},
|
||||
set(key, value) {
|
||||
this.settings[key] = value;
|
||||
let content = JSON.stringify(this.settings, null, '\t');
|
||||
fs.writeFileSync(this.path, content);
|
||||
},
|
||||
load() {
|
||||
try {
|
||||
if (fs.existsSync(this.path)) {
|
||||
let content = fs.readFileSync(this.path, 'utf-8');
|
||||
this.settings = JSON.parse(content);
|
||||
}
|
||||
} catch (error) {}
|
||||
return this;
|
||||
}
|
||||
}.load();
|
||||
|
||||
if (LaunchSettings.get('hardware_acceleration') == false) {
|
||||
app.disableHardwareAcceleration();
|
||||
}
|
||||
|
||||
function createWindow(second_instance, options = {}) {
|
||||
if (app.requestSingleInstanceLock && !app.requestSingleInstanceLock()) {
|
||||
app.quit()
|
||||
return;
|
||||
}
|
||||
let win_options = {
|
||||
icon: 'icon.ico',
|
||||
show: false,
|
||||
backgroundColor: '#21252b',
|
||||
frame: LaunchSettings.get('native_window_frame') === true,
|
||||
titleBarStyle: 'hidden',
|
||||
minWidth: 640,
|
||||
minHeight: 480,
|
||||
width: 1080,
|
||||
height: 720,
|
||||
webPreferences: {
|
||||
webgl: true,
|
||||
webSecurity: true,
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false,
|
||||
enableRemoteModule: true
|
||||
}
|
||||
};
|
||||
if (options.position) {
|
||||
win_options.x = options.position[0] - 300;
|
||||
win_options.y = Math.max(options.position[1] - 100, 0);
|
||||
}
|
||||
let win = new BrowserWindow(win_options)
|
||||
if (!orig_win) orig_win = win;
|
||||
all_wins.push(win);
|
||||
|
||||
require('@electron/remote/main').enable(win.webContents)
|
||||
|
||||
var index_path = path.join(__dirname, 'index.html')
|
||||
if (process.platform === 'darwin') {
|
||||
|
||||
let template = [
|
||||
{
|
||||
"label": "Blockbench",
|
||||
"submenu": [
|
||||
{
|
||||
"role": "hide"
|
||||
},
|
||||
{
|
||||
"role": "hideothers"
|
||||
},
|
||||
{
|
||||
"role": "unhide"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"role": "quit"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Edit",
|
||||
"submenu": [
|
||||
{
|
||||
"role": "cut"
|
||||
},
|
||||
{
|
||||
"role": "copy"
|
||||
},
|
||||
{
|
||||
"role": "paste"
|
||||
},
|
||||
{
|
||||
"role": "selectall"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Window",
|
||||
"role": "window",
|
||||
"submenu": [
|
||||
{
|
||||
"label": "Toggle Full Screen",
|
||||
"accelerator": "Ctrl+Command+F"
|
||||
},
|
||||
{
|
||||
"role": "minimize"
|
||||
},
|
||||
{
|
||||
"role": "close"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"role": "front"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
var osxMenu = Menu.buildFromTemplate(template);
|
||||
Menu.setApplicationMenu(osxMenu)
|
||||
} else {
|
||||
win.setMenu(null);
|
||||
}
|
||||
|
||||
if (options.maximize !== false) win.maximize()
|
||||
win.show()
|
||||
|
||||
win.loadURL(url.format({
|
||||
pathname: index_path,
|
||||
protocol: 'file:',
|
||||
slashes: true
|
||||
}))
|
||||
win.webContents.openDevTools()
|
||||
win.on('closed', () => {
|
||||
win = null;
|
||||
all_wins.splice(all_wins.indexOf(win), 1);
|
||||
})
|
||||
if (second_instance === true) {
|
||||
win.webContents.second_instance = true;
|
||||
}
|
||||
return win;
|
||||
}
|
||||
|
||||
app.commandLine.appendSwitch('ignore-gpu-blacklist')
|
||||
app.commandLine.appendSwitch('ignore-gpu-blocklist')
|
||||
app.commandLine.appendSwitch('enable-accelerated-video')
|
||||
|
||||
app.on('second-instance', function (event, argv, cwd) {
|
||||
process.argv = argv;
|
||||
let win = all_wins.find(win => !win.isDestroyed());
|
||||
if (win && argv[argv.length-1 || 1] && argv[argv.length-1 || 1].substr(0, 2) !== '--') {
|
||||
win.webContents.send('open-model', argv[argv.length-1 || 1]);
|
||||
win.focus();
|
||||
} else {
|
||||
createWindow(true);
|
||||
}
|
||||
})
|
||||
app.on('open-file', function (event, path) {
|
||||
process.argv[process.argv.length-1 || 1] = path;
|
||||
let win = all_wins.find(win => !win.isDestroyed());
|
||||
if (win) {
|
||||
win.webContents.send('open-model', path);
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('edit-launch-setting', (event, arg) => {
|
||||
LaunchSettings.set(arg.key, arg.value);
|
||||
})
|
||||
ipcMain.on('add-recent-project', (event, path) => {
|
||||
app.addRecentDocument(path);
|
||||
})
|
||||
ipcMain.on('dragging-tab', (event, value) => {
|
||||
all_wins.forEach(win => {
|
||||
if (win.isDestroyed() || win.id == event.sender.id) return;
|
||||
win.webContents.send('accept-detached-tab', JSON.parse(value));
|
||||
})
|
||||
})
|
||||
ipcMain.on('new-window', (event, data, position) => {
|
||||
if (typeof data == 'string') load_project_data = JSON.parse(data);
|
||||
if (position) {
|
||||
position = JSON.parse(position)
|
||||
let place_in_window = all_wins.find(win => {
|
||||
if (win.isDestroyed() || win.webContents == event.sender || win.isMinimized()) return false;
|
||||
let pos = win.getPosition();
|
||||
let size = win.getSize();
|
||||
return (position.offset[0] >= pos[0] && position.offset[0] <= pos[0] + size[0]
|
||||
&& position.offset[1] >= pos[1] && position.offset[1] <= pos[1] + size[1]);
|
||||
})
|
||||
if (place_in_window) {
|
||||
place_in_window.send('load-tab', load_project_data);
|
||||
place_in_window.focus();
|
||||
load_project_data = null;
|
||||
} else {
|
||||
createWindow(true, {
|
||||
maximize: false,
|
||||
position: position.offset
|
||||
});
|
||||
}
|
||||
} else {
|
||||
createWindow(true);
|
||||
}
|
||||
})
|
||||
ipcMain.on('close-detached-project', async (event, window_id, uuid) => {
|
||||
let window = all_wins.find(win => win.id == window_id);
|
||||
if (window) window.send('close-detached-project', uuid);
|
||||
})
|
||||
ipcMain.on('request-color-picker', async (event, arg) => {
|
||||
const color = await getColorHexRGB().catch((error) => {
|
||||
console.warn('[Error] Failed to pick color', error)
|
||||
return ''
|
||||
})
|
||||
if (color) {
|
||||
all_wins.forEach(win => {
|
||||
if (win.isDestroyed() || (!arg.sync && win.webContents.getProcessId() != event.sender.getProcessId())) return;
|
||||
win.webContents.send('set-main-color', color)
|
||||
})
|
||||
}
|
||||
})
|
||||
ipcMain.on('show-item-in-folder', async (event, path) => {
|
||||
shell.showItemInFolder(path);
|
||||
})
|
||||
ipcMain.on('open-in-default-app', async (event, path) => {
|
||||
shell.openPath(path);
|
||||
})
|
||||
|
||||
app.on('ready', () => {
|
||||
|
||||
createWindow()
|
||||
|
||||
let app_was_loaded = false;
|
||||
ipcMain.on('app-loaded', () => {
|
||||
|
||||
if (load_project_data) {
|
||||
all_wins[all_wins.length-1].send('load-tab', load_project_data);
|
||||
load_project_data = null;
|
||||
}
|
||||
|
||||
if (app_was_loaded) {
|
||||
console.log('[Blockbench] App reloaded or new window opened')
|
||||
return;
|
||||
}
|
||||
|
||||
app_was_loaded = true;
|
||||
if (process.execPath && process.execPath.match(/node_modules[\\\/]electron/)) {
|
||||
|
||||
console.log('[Blockbench] App launched in development mode')
|
||||
|
||||
} else {
|
||||
|
||||
autoUpdater.autoInstallOnAppQuit = true;
|
||||
autoUpdater.autoDownload = false;
|
||||
if (LaunchSettings.get('update_to_prereleases') === true) {
|
||||
autoUpdater.allowPrerelease = true;
|
||||
//autoUpdater.channel = 'beta';
|
||||
}
|
||||
|
||||
autoUpdater.on('update-available', (a) => {
|
||||
console.log('update-available', a)
|
||||
ipcMain.on('allow-auto-update', () => {
|
||||
autoUpdater.downloadUpdate()
|
||||
})
|
||||
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-available', a);
|
||||
})
|
||||
autoUpdater.on('update-downloaded', (a) => {
|
||||
console.log('update-downloaded', a)
|
||||
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-downloaded', a)
|
||||
})
|
||||
autoUpdater.on('error', (a) => {
|
||||
console.log('update-error', a)
|
||||
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-error', a)
|
||||
})
|
||||
autoUpdater.on('download-progress', (a) => {
|
||||
console.log('update-progress', a)
|
||||
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-progress', a)
|
||||
})
|
||||
autoUpdater.checkForUpdates().catch(err => {})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
app.quit()
|
||||
})
|
||||
import {app, BrowserWindow, Menu, ipcMain, shell} from 'electron'
|
||||
import path from 'path'
|
||||
import url from 'url'
|
||||
import { createRequire } from 'node:module'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
import fs from 'node:fs'
|
||||
import {getColorHexRGB} from 'electron-color-picker'
|
||||
|
||||
const require = createRequire(import.meta.url)
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
|
||||
const { autoUpdater } = require('electron-updater');
|
||||
const remote = require('@electron/remote/main')
|
||||
remote.initialize();
|
||||
|
||||
let all_wins = [];
|
||||
let orig_win;
|
||||
let load_project_data;
|
||||
|
||||
(() => {
|
||||
// Allow advanced users to specify a custom userData directory.
|
||||
// Useful for portable installations, and for setting up development environments.
|
||||
const index = process.argv.findIndex(arg => arg === '--userData');
|
||||
if (index !== -1) {
|
||||
if (!process.argv.at(index + 1)) {
|
||||
console.error('No path specified after --userData')
|
||||
process.exit(1)
|
||||
}
|
||||
app.setPath('userData', process.argv[index + 1]);
|
||||
}
|
||||
})()
|
||||
|
||||
|
||||
process.env.APP_ROOT = path.join(__dirname, '../..')
|
||||
|
||||
export const MAIN_DIST = path.join(process.env.APP_ROOT, 'dist-electron')
|
||||
export const RENDERER_DIST = path.join(process.env.APP_ROOT, 'dist-vite')
|
||||
export const VITE_DEV_SERVER_URL = process.env.VITE_DEV_SERVER_URL
|
||||
|
||||
process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL ? path.join(process.env.APP_ROOT, 'public') : RENDERER_DIST
|
||||
|
||||
const preload = path.join(__dirname, '../preload/index.mjs')
|
||||
const indexHtml = path.join(RENDERER_DIST, 'index.html')
|
||||
|
||||
|
||||
|
||||
const LaunchSettings = {
|
||||
path: path.join(app.getPath('userData'), 'launch_settings.json'),
|
||||
settings: {},
|
||||
get(key) {
|
||||
return this.settings[key]
|
||||
},
|
||||
set(key, value) {
|
||||
this.settings[key] = value;
|
||||
let content = JSON.stringify(this.settings, null, '\t');
|
||||
fs.writeFileSync(this.path, content);
|
||||
},
|
||||
load() {
|
||||
try {
|
||||
if (fs.existsSync(this.path)) {
|
||||
let content = fs.readFileSync(this.path, 'utf-8');
|
||||
this.settings = JSON.parse(content);
|
||||
}
|
||||
} catch (error) {}
|
||||
return this;
|
||||
}
|
||||
}.load();
|
||||
|
||||
if (LaunchSettings.get('hardware_acceleration') == false) {
|
||||
app.disableHardwareAcceleration();
|
||||
}
|
||||
|
||||
function createWindow(second_instance, options = {}) {
|
||||
if (app.requestSingleInstanceLock && !app.requestSingleInstanceLock()) {
|
||||
app.quit()
|
||||
return;
|
||||
}
|
||||
let win_options = {
|
||||
icon: 'icon.ico',
|
||||
show: false,
|
||||
backgroundColor: '#21252b',
|
||||
frame: LaunchSettings.get('native_window_frame') === true,
|
||||
titleBarStyle: 'hidden',
|
||||
minWidth: 640,
|
||||
minHeight: 480,
|
||||
width: 1080,
|
||||
height: 720,
|
||||
webPreferences: {
|
||||
webgl: true,
|
||||
webSecurity: true,
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false,
|
||||
enableRemoteModule: true
|
||||
}
|
||||
};
|
||||
if (options.position) {
|
||||
win_options.x = options.position[0] - 300;
|
||||
win_options.y = Math.max(options.position[1] - 100, 0);
|
||||
}
|
||||
let win = new BrowserWindow(win_options)
|
||||
if (!orig_win) orig_win = win;
|
||||
all_wins.push(win);
|
||||
|
||||
remote.enable(win.webContents)
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
|
||||
let template = [
|
||||
{
|
||||
"label": "Blockbench",
|
||||
"submenu": [
|
||||
{
|
||||
"role": "hide"
|
||||
},
|
||||
{
|
||||
"role": "hideothers"
|
||||
},
|
||||
{
|
||||
"role": "unhide"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"role": "quit"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Edit",
|
||||
"submenu": [
|
||||
{
|
||||
"role": "cut"
|
||||
},
|
||||
{
|
||||
"role": "copy"
|
||||
},
|
||||
{
|
||||
"role": "paste"
|
||||
},
|
||||
{
|
||||
"role": "selectall"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"label": "Window",
|
||||
"role": "window",
|
||||
"submenu": [
|
||||
{
|
||||
"label": "Toggle Full Screen",
|
||||
"accelerator": "Ctrl+Command+F"
|
||||
},
|
||||
{
|
||||
"role": "minimize"
|
||||
},
|
||||
{
|
||||
"role": "close"
|
||||
},
|
||||
{
|
||||
"type": "separator"
|
||||
},
|
||||
{
|
||||
"role": "front"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
var osxMenu = Menu.buildFromTemplate(template);
|
||||
Menu.setApplicationMenu(osxMenu)
|
||||
} else {
|
||||
win.setMenu(null);
|
||||
}
|
||||
|
||||
if (options.maximize !== false) win.maximize()
|
||||
win.show()
|
||||
|
||||
if (VITE_DEV_SERVER_URL) { // #298
|
||||
win.loadURL(VITE_DEV_SERVER_URL)
|
||||
// Open devTool if the app is not packaged
|
||||
win.webContents.openDevTools()
|
||||
} else {
|
||||
win.loadFile(indexHtml)
|
||||
}
|
||||
|
||||
// Test actively push message to the Electron-Renderer
|
||||
win.webContents.on('did-finish-load', () => {
|
||||
win?.webContents.send('main-process-message', new Date().toLocaleString())
|
||||
})
|
||||
|
||||
// Make all links open with the browser, not with the application
|
||||
win.webContents.setWindowOpenHandler(({ url }) => {
|
||||
if (url.startsWith('https:')) shell.openExternal(url)
|
||||
return { action: 'deny' }
|
||||
})
|
||||
|
||||
/*win.webContents.session.webRequest.onBeforeSendHeaders(
|
||||
(details, callback) => {
|
||||
callback({ requestHeaders: { Origin: '*', ...details.requestHeaders } });
|
||||
},
|
||||
);
|
||||
|
||||
win.webContents.session.webRequest.onHeadersReceived((details, callback) => {
|
||||
callback({
|
||||
responseHeaders: {
|
||||
'Access-Control-Allow-Origin': ['*'],
|
||||
...details.responseHeaders,
|
||||
},
|
||||
});
|
||||
});*/
|
||||
|
||||
win.webContents.openDevTools()
|
||||
win.on('closed', () => {
|
||||
win = null;
|
||||
all_wins.splice(all_wins.indexOf(win), 1);
|
||||
})
|
||||
if (second_instance === true) {
|
||||
win.webContents.second_instance = true;
|
||||
}
|
||||
return win;
|
||||
}
|
||||
|
||||
app.commandLine.appendSwitch('ignore-gpu-blacklist')
|
||||
app.commandLine.appendSwitch('ignore-gpu-blocklist')
|
||||
app.commandLine.appendSwitch('enable-accelerated-video')
|
||||
|
||||
app.on('second-instance', function (event, argv, cwd) {
|
||||
process.argv = argv;
|
||||
let win = all_wins.find(win => !win.isDestroyed());
|
||||
if (win && argv[argv.length-1 || 1] && argv[argv.length-1 || 1].substr(0, 2) !== '--') {
|
||||
win.webContents.send('open-model', argv[argv.length-1 || 1]);
|
||||
win.focus();
|
||||
} else {
|
||||
createWindow(true);
|
||||
}
|
||||
})
|
||||
app.on('open-file', function (event, path) {
|
||||
process.argv[process.argv.length-1 || 1] = path;
|
||||
let win = all_wins.find(win => !win.isDestroyed());
|
||||
if (win) {
|
||||
win.webContents.send('open-model', path);
|
||||
}
|
||||
})
|
||||
|
||||
ipcMain.on('edit-launch-setting', (event, arg) => {
|
||||
LaunchSettings.set(arg.key, arg.value);
|
||||
})
|
||||
ipcMain.on('add-recent-project', (event, path) => {
|
||||
app.addRecentDocument(path);
|
||||
})
|
||||
ipcMain.on('dragging-tab', (event, value) => {
|
||||
all_wins.forEach(win => {
|
||||
if (win.isDestroyed() || win.id == event.sender.id) return;
|
||||
win.webContents.send('accept-detached-tab', JSON.parse(value));
|
||||
})
|
||||
})
|
||||
ipcMain.on('new-window', (event, data, position) => {
|
||||
if (typeof data == 'string') load_project_data = JSON.parse(data);
|
||||
if (position) {
|
||||
position = JSON.parse(position)
|
||||
let place_in_window = all_wins.find(win => {
|
||||
if (win.isDestroyed() || win.webContents == event.sender || win.isMinimized()) return false;
|
||||
let pos = win.getPosition();
|
||||
let size = win.getSize();
|
||||
return (position.offset[0] >= pos[0] && position.offset[0] <= pos[0] + size[0]
|
||||
&& position.offset[1] >= pos[1] && position.offset[1] <= pos[1] + size[1]);
|
||||
})
|
||||
if (place_in_window) {
|
||||
place_in_window.send('load-tab', load_project_data);
|
||||
place_in_window.focus();
|
||||
load_project_data = null;
|
||||
} else {
|
||||
createWindow(true, {
|
||||
maximize: false,
|
||||
position: position.offset
|
||||
});
|
||||
}
|
||||
} else {
|
||||
createWindow(true);
|
||||
}
|
||||
})
|
||||
ipcMain.on('close-detached-project', async (event, window_id, uuid) => {
|
||||
let window = all_wins.find(win => win.id == window_id);
|
||||
if (window) window.send('close-detached-project', uuid);
|
||||
})
|
||||
ipcMain.on('request-color-picker', async (event, arg) => {
|
||||
const color = await getColorHexRGB().catch((error) => {
|
||||
console.warn('[Error] Failed to pick color', error)
|
||||
return ''
|
||||
})
|
||||
if (color) {
|
||||
all_wins.forEach(win => {
|
||||
if (win.isDestroyed() || (!arg.sync && win.webContents.getProcessId() != event.sender.getProcessId())) return;
|
||||
win.webContents.send('set-main-color', color)
|
||||
})
|
||||
}
|
||||
})
|
||||
ipcMain.on('show-item-in-folder', async (event, path) => {
|
||||
shell.showItemInFolder(path);
|
||||
})
|
||||
ipcMain.on('open-in-default-app', async (event, path) => {
|
||||
shell.openPath(path);
|
||||
})
|
||||
|
||||
app.on('ready', () => {
|
||||
|
||||
createWindow()
|
||||
|
||||
let app_was_loaded = false;
|
||||
ipcMain.on('app-loaded', () => {
|
||||
|
||||
if (load_project_data) {
|
||||
all_wins[all_wins.length-1].send('load-tab', load_project_data);
|
||||
load_project_data = null;
|
||||
}
|
||||
|
||||
if (app_was_loaded) {
|
||||
console.log('[Blockbench] App reloaded or new window opened')
|
||||
return;
|
||||
}
|
||||
|
||||
app_was_loaded = true;
|
||||
if (process.execPath && process.execPath.match(/node_modules[\\\/]electron/)) {
|
||||
|
||||
console.log('[Blockbench] App launched in development mode')
|
||||
|
||||
} else {
|
||||
|
||||
autoUpdater.autoInstallOnAppQuit = true;
|
||||
autoUpdater.autoDownload = false;
|
||||
if (LaunchSettings.get('update_to_prereleases') === true) {
|
||||
autoUpdater.allowPrerelease = true;
|
||||
//autoUpdater.channel = 'beta';
|
||||
}
|
||||
|
||||
autoUpdater.on('update-available', (a) => {
|
||||
console.log('update-available', a)
|
||||
ipcMain.on('allow-auto-update', () => {
|
||||
autoUpdater.downloadUpdate()
|
||||
})
|
||||
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-available', a);
|
||||
})
|
||||
autoUpdater.on('update-downloaded', (a) => {
|
||||
console.log('update-downloaded', a)
|
||||
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-downloaded', a)
|
||||
})
|
||||
autoUpdater.on('error', (a) => {
|
||||
console.log('update-error', a)
|
||||
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-error', a)
|
||||
})
|
||||
autoUpdater.on('download-progress', (a) => {
|
||||
console.log('update-progress', a)
|
||||
if (!orig_win.isDestroyed()) orig_win.webContents.send('update-progress', a)
|
||||
})
|
||||
autoUpdater.checkForUpdates().catch(err => {})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
app.quit()
|
||||
})
|
118
electron/preload/index.ts
Normal file
118
electron/preload/index.ts
Normal file
@ -0,0 +1,118 @@
|
||||
import { ipcRenderer, contextBridge } from 'electron'
|
||||
|
||||
// --------- Expose some API to the Renderer process ---------
|
||||
contextBridge.exposeInMainWorld('ipcRenderer', {
|
||||
on(...args: Parameters<typeof ipcRenderer.on>) {
|
||||
const [channel, listener] = args
|
||||
return ipcRenderer.on(channel, (event, ...args) => listener(event, ...args))
|
||||
},
|
||||
off(...args: Parameters<typeof ipcRenderer.off>) {
|
||||
const [channel, ...omit] = args
|
||||
return ipcRenderer.off(channel, ...omit)
|
||||
},
|
||||
send(...args: Parameters<typeof ipcRenderer.send>) {
|
||||
const [channel, ...omit] = args
|
||||
return ipcRenderer.send(channel, ...omit)
|
||||
},
|
||||
invoke(...args: Parameters<typeof ipcRenderer.invoke>) {
|
||||
const [channel, ...omit] = args
|
||||
return ipcRenderer.invoke(channel, ...omit)
|
||||
},
|
||||
|
||||
// You can expose other APTs you need here.
|
||||
// ...
|
||||
})
|
||||
|
||||
// --------- Preload scripts loading ---------
|
||||
function domReady(condition: DocumentReadyState[] = ['complete', 'interactive']) {
|
||||
return new Promise((resolve) => {
|
||||
if (condition.includes(document.readyState)) {
|
||||
resolve(true)
|
||||
} else {
|
||||
document.addEventListener('readystatechange', () => {
|
||||
if (condition.includes(document.readyState)) {
|
||||
resolve(true)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const safeDOM = {
|
||||
append(parent: HTMLElement, child: HTMLElement) {
|
||||
if (!Array.from(parent.children).find(e => e === child)) {
|
||||
return parent.appendChild(child)
|
||||
}
|
||||
},
|
||||
remove(parent: HTMLElement, child: HTMLElement) {
|
||||
if (Array.from(parent.children).find(e => e === child)) {
|
||||
return parent.removeChild(child)
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* https://tobiasahlin.com/spinkit
|
||||
* https://connoratherton.com/loaders
|
||||
* https://projects.lukehaas.me/css-loaders
|
||||
* https://matejkustec.github.io/SpinThatShit
|
||||
*/
|
||||
function useLoading() {
|
||||
const className = `loaders-css__square-spin`
|
||||
const styleContent = `
|
||||
@keyframes square-spin {
|
||||
25% { transform: perspective(100px) rotateX(180deg) rotateY(0); }
|
||||
50% { transform: perspective(100px) rotateX(180deg) rotateY(180deg); }
|
||||
75% { transform: perspective(100px) rotateX(0) rotateY(180deg); }
|
||||
100% { transform: perspective(100px) rotateX(0) rotateY(0); }
|
||||
}
|
||||
.${className} > div {
|
||||
animation-fill-mode: both;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: #fff;
|
||||
animation: square-spin 3s 0s cubic-bezier(0.09, 0.57, 0.49, 0.9) infinite;
|
||||
}
|
||||
.app-loading-wrap {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: #282c34;
|
||||
z-index: 9;
|
||||
}
|
||||
`
|
||||
const oStyle = document.createElement('style')
|
||||
const oDiv = document.createElement('div')
|
||||
|
||||
oStyle.id = 'app-loading-style'
|
||||
oStyle.innerHTML = styleContent
|
||||
oDiv.className = 'app-loading-wrap'
|
||||
oDiv.innerHTML = `<div class="${className}"><div></div></div>`
|
||||
|
||||
return {
|
||||
appendLoading() {
|
||||
safeDOM.append(document.head, oStyle)
|
||||
safeDOM.append(document.body, oDiv)
|
||||
},
|
||||
removeLoading() {
|
||||
safeDOM.remove(document.head, oStyle)
|
||||
safeDOM.remove(document.body, oDiv)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const { appendLoading, removeLoading } = useLoading()
|
||||
domReady().then(appendLoading)
|
||||
|
||||
window.onmessage = (ev) => {
|
||||
ev.data.payload === 'removeLoading' && removeLoading()
|
||||
}
|
||||
|
||||
setTimeout(removeLoading, 4999)
|
@ -1,3 +1,5 @@
|
||||
import Wintersky from 'wintersky';
|
||||
|
||||
export class AnimationControllerState {
|
||||
constructor(controller, data = 0) {
|
||||
this.controller = controller;
|
||||
|
@ -1,3 +1,6 @@
|
||||
import MolangParser from "molangjs";
|
||||
import Wintersky from 'wintersky';
|
||||
|
||||
export const Animator = {
|
||||
get possible_channels() {
|
||||
let obj = {};
|
||||
@ -7,7 +10,7 @@ export const Animator = {
|
||||
open: false,
|
||||
get animations() {return Animation.all},
|
||||
get selected() {return Animation.selected},
|
||||
MolangParser: new Molang(),
|
||||
MolangParser: new MolangParser(),
|
||||
motion_trail: new THREE.Object3D(),
|
||||
onion_skin_object: new THREE.Object3D(),
|
||||
motion_trail_lock: false,
|
||||
@ -1496,5 +1499,6 @@ Interface.definePanels(function() {
|
||||
|
||||
Object.assign(window, {
|
||||
Animator,
|
||||
Wintersky,
|
||||
WinterskyScene
|
||||
});
|
||||
|
@ -1,3 +1,5 @@
|
||||
import Wintersky from 'wintersky';
|
||||
|
||||
export class GeneralAnimator {
|
||||
constructor(uuid, animation) {
|
||||
this.animation = animation;
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { Blockbench } from "./api";
|
||||
import { ipcRenderer } from "./desktop";
|
||||
import { loadInstalledPlugins } from "./plugin_loader";
|
||||
import { animate } from "./preview/preview";
|
||||
import { initializeWebApp, loadInfoFromURL } from "./web";
|
||||
|
@ -1,12 +1,10 @@
|
||||
export const electron = require('@electron/remote');
|
||||
console.log('REMOTE', electron)
|
||||
export const {clipboard, shell, nativeImage, ipcRenderer, dialog, webUtils} = require('electron');
|
||||
export const app = electron.app;
|
||||
export const fs = require('fs');
|
||||
export const NodeBuffer = require('buffer');
|
||||
export const zlib = require('zlib');
|
||||
export const exec = require('child_process').exec;
|
||||
export const originalFs = require('original-fs');
|
||||
export const https = require('https');
|
||||
export const PathModule = require('path');
|
||||
|
||||
@ -588,6 +586,7 @@ BARS.defineActions(() => {
|
||||
|
||||
//Close
|
||||
window.onbeforeunload = function (event) {
|
||||
console.log('BEFORE UNLOAD')
|
||||
try {
|
||||
updateRecentProjectData()
|
||||
} catch(err) {}
|
||||
@ -756,13 +755,12 @@ ipcRenderer.on('update-available', (event, arg) => {
|
||||
|
||||
Object.assign(window, {
|
||||
electron,
|
||||
clipboard,
|
||||
clipboard, shell, nativeImage, ipcRenderer, dialog, webUtils,
|
||||
app,
|
||||
fs,
|
||||
NodeBuffer,
|
||||
zlib,
|
||||
exec,
|
||||
originalFs,
|
||||
https,
|
||||
PathModule,
|
||||
currentwindow,
|
||||
|
@ -1,4 +1,4 @@
|
||||
var ground_animation = false;
|
||||
|
||||
var ground_timer = 0
|
||||
var display_slot = 'thirdperson_righthand';
|
||||
var display_presets;
|
||||
@ -540,7 +540,7 @@ export class refModel {
|
||||
DisplayMode.vue.reference_model = this.id;
|
||||
|
||||
if (display_slot == 'ground') {
|
||||
ground_animation = this.id != 'fox';
|
||||
Canvas.ground_animation = this.id != 'fox';
|
||||
}
|
||||
|
||||
ReferenceImage.updateAll()
|
||||
@ -1529,7 +1529,7 @@ export function loadDisp(key) { //Loads The Menu and slider values, common for a
|
||||
display_preview.loadAnglePreset(display_angle_preset)
|
||||
}
|
||||
display_preview.controls.enabled = true;
|
||||
ground_animation = false;
|
||||
Canvas.ground_animation = false;
|
||||
$('#display_crosshair').detach()
|
||||
if (display_preview.orbit_gizmo) display_preview.orbit_gizmo.unhide();
|
||||
display_preview.camPers.setFocalLength(45)
|
||||
@ -1626,7 +1626,7 @@ DisplayMode.loadGround = function() { //Loader
|
||||
target: [0, 3, 0]
|
||||
})
|
||||
setDisplayArea(8, 4, 8, 0, 0, 0, 1, 1, 1)
|
||||
ground_animation = true;
|
||||
Canvas.ground_animation = true;
|
||||
ground_timer = 0
|
||||
displayReferenceObjects.bar(['block', 'fox'])
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import MolangParser from "molangjs";
|
||||
|
||||
export const Toolbars = {};
|
||||
export const BarItems = {};
|
||||
//Bars
|
||||
@ -1066,7 +1068,7 @@ export class NumSlider extends Widget {
|
||||
this.dispatchEvent('update');
|
||||
}
|
||||
}
|
||||
NumSlider.MolangParser = new Molang()
|
||||
NumSlider.MolangParser = new MolangParser()
|
||||
|
||||
export class BarSlider extends Widget {
|
||||
constructor(id, data) {
|
||||
|
@ -90,8 +90,8 @@ export class Panel extends EventSystem {
|
||||
//updateInterfacePanels()
|
||||
})
|
||||
}
|
||||
this.vue = this.inside_vue = new Vue(data.component).$mount(component_mount);
|
||||
scope.vue.$el.classList.add('panel_vue_wrapper');
|
||||
this.vue = this.inside_vue = new Vue(data.component).$mount(component_mount);
|
||||
this.vue.$el.classList.add('panel_vue_wrapper');
|
||||
}
|
||||
|
||||
if (!Blockbench.isMobile) {
|
||||
|
@ -1,5 +1,6 @@
|
||||
//import { createApp } from 'vue'
|
||||
//import App from './App.vue'
|
||||
|
||||
import "../lib/libs"
|
||||
import "../lib/vue.min.js"
|
||||
import "../lib/vue_sortable.js"
|
||||
@ -23,8 +24,6 @@ import "../lib/three_custom.js"
|
||||
import "../lib/CanvasFrame.js"
|
||||
import "../lib/canvas2apng.js"
|
||||
//import "../lib/fik.min.js"
|
||||
import "../lib/molang.umd.js"
|
||||
import "../lib/wintersky.umd.js"
|
||||
import "../lib/easing.js"
|
||||
|
||||
import "./preview/OrbitControls.js"
|
||||
@ -59,8 +58,8 @@ import "./interface/action_control.js"
|
||||
import "./copy_paste.js"
|
||||
import "./undo.js"
|
||||
|
||||
//import './desktop.js'
|
||||
import './web.js'
|
||||
import './desktop.js'
|
||||
//import './web.js'
|
||||
|
||||
import "./edit_sessions.js"
|
||||
import "./validator.js"
|
||||
@ -88,7 +87,6 @@ import "./texturing/texture_flipbook.js"
|
||||
import "./texturing/uv.js"
|
||||
import "./texturing/painter.js"
|
||||
import "./texturing/texture_generator.js"
|
||||
import "./texturing/color.js"
|
||||
import "./texturing/edit_image.js"
|
||||
import "./display_mode.js"
|
||||
import "./animations/animation_mode.js"
|
||||
@ -106,6 +104,7 @@ import "./io/format.js"
|
||||
import "./io/project.js"
|
||||
import "./io/io.js"
|
||||
import "./io/share.js"
|
||||
import "./texturing/color.js"
|
||||
import "./io/formats/generic.js"
|
||||
import "./io/formats/bbmodel.js"
|
||||
import "./io/formats/java_block.js"
|
||||
|
@ -555,3 +555,5 @@ BARS.defineActions(() => {
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
Object.assign(window, {MirrorModeling});
|
||||
|
@ -192,7 +192,7 @@ BARS.defineActions(function() {
|
||||
Outliner.elements.forEach(cube => {
|
||||
if (cube.preview_controller.updatePixelGrid) cube.preview_controller.updatePixelGrid(cube);
|
||||
})
|
||||
$('#main_colorpicker').spectrum('set', ColorPanel.vue._data.main_color);
|
||||
$('#main_colorpicker').spectrum('set', ColorPanel.panel.vue._data.main_color);
|
||||
if (StateMemory.color_picker_rgb) {
|
||||
BarItems.slider_color_red.update();
|
||||
BarItems.slider_color_green.update();
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { Property } from "../util/property";
|
||||
|
||||
export class MeshFace extends Face {
|
||||
constructor(mesh, data) {
|
||||
super(data);
|
||||
|
@ -282,7 +282,7 @@ export class Plugin {
|
||||
|
||||
// Download files
|
||||
async function copyFileToDrive(origin_filename, target_filename, callback) {
|
||||
var file = originalFs.createWriteStream(PathModule.join(Plugins.path, target_filename));
|
||||
var file = fs.createWriteStream(PathModule.join(Plugins.path, target_filename));
|
||||
https.get(Plugins.api_path+'/'+origin_filename, function(response) {
|
||||
response.pipe(file);
|
||||
if (callback) response.on('end', callback);
|
||||
@ -406,7 +406,7 @@ export class Plugin {
|
||||
// Save
|
||||
if (isApp) {
|
||||
await new Promise((resolve, reject) => {
|
||||
let file = originalFs.createWriteStream(Plugins.path+this.id+'.js')
|
||||
let file = fs.createWriteStream(Plugins.path+this.id+'.js')
|
||||
https.get(url, (response) => {
|
||||
response.pipe(file);
|
||||
response.on('end', resolve)
|
||||
|
@ -116,6 +116,7 @@ export const Canvas = {
|
||||
// Pivot marker
|
||||
pivot_marker: rot_origin,
|
||||
gizmos: [rot_origin],
|
||||
ground_animation: false,
|
||||
outlineMaterial: new THREE.LineBasicMaterial({
|
||||
linewidth: 2,
|
||||
depthTest: settings.seethrough_outline.value == false,
|
||||
@ -856,9 +857,9 @@ export const Canvas = {
|
||||
obj.was_visible = obj.visible
|
||||
obj.visible = false
|
||||
})
|
||||
var ground_anim_before = ground_animation
|
||||
if (Modes.display && ground_animation) {
|
||||
ground_animation = false
|
||||
var ground_anim_before = Canvas.ground_animation
|
||||
if (Modes.display && Canvas.ground_animation) {
|
||||
Canvas.ground_animation = false
|
||||
}
|
||||
updateCubeHighlights(null, true);
|
||||
|
||||
@ -873,7 +874,7 @@ export const Canvas = {
|
||||
delete obj.was_visible
|
||||
})
|
||||
if (Modes.display && ground_anim_before) {
|
||||
ground_animation = ground_anim_before
|
||||
Canvas.ground_animation = ground_anim_before
|
||||
}
|
||||
updateCubeHighlights();
|
||||
},
|
||||
|
@ -2112,7 +2112,7 @@ export function animate() {
|
||||
}
|
||||
})
|
||||
framespersecond++;
|
||||
if (Modes.display === true && ground_animation === true && !Transformer.hoverAxis) {
|
||||
if (Modes.display === true && Canvas.ground_animation === true && !Transformer.hoverAxis) {
|
||||
DisplayMode.groundAnimation()
|
||||
}
|
||||
Blockbench.dispatchEvent('render_frame');
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
export class Property {
|
||||
constructor(target_class, type = 'boolean', name, options = 0) {
|
||||
constructor(target_class, type = 'boolean', name, options = {}) {
|
||||
if (!target_class.properties) {
|
||||
target_class.properties = {};
|
||||
}
|
||||
|
@ -1,9 +0,0 @@
|
||||
{
|
||||
"include": [
|
||||
"js/**/*",
|
||||
"types/**/*"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"module": "ES6"
|
||||
}
|
||||
}
|
File diff suppressed because one or more lines are too long
1837
lib/wintersky.umd.js
1837
lib/wintersky.umd.js
File diff suppressed because one or more lines are too long
80
package-lock.json
generated
80
package-lock.json
generated
@ -14,13 +14,18 @@
|
||||
"electron-updater": "^6.3.4",
|
||||
"gifenc": "^1.0.3",
|
||||
"jquery": "^3.7.1",
|
||||
"tinycolor2": "^1.6.0"
|
||||
"molangjs": "^1.6.5",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"wintersky": "^1.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/notarize": "^2.5.0",
|
||||
"electron": "^33.3.1",
|
||||
"electron-builder": "^24.13.3",
|
||||
"typescript": "^5.8.2",
|
||||
"vite": "^6.2.0",
|
||||
"vite-plugin-electron": "^0.29.0",
|
||||
"vite-plugin-electron-renderer": "^0.14.6",
|
||||
"vite-plugin-pwa": "^0.21.1",
|
||||
"workbox-build": "^6.5.3"
|
||||
}
|
||||
@ -4169,20 +4174,6 @@
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/config-file-ts/node_modules/typescript": {
|
||||
"version": "5.7.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
|
||||
"integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/convert-source-map": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
|
||||
@ -6304,6 +6295,12 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/molangjs": {
|
||||
"version": "1.6.5",
|
||||
"resolved": "https://registry.npmjs.org/molangjs/-/molangjs-1.6.5.tgz",
|
||||
"integrity": "sha512-XekNpUZ3RP5fsOHqic+tj9wOOTrN2vU6Ynrk8oM7lt9jlYoBzz1mzM1FxeSMqqpuDQrjEINS46Zxz6K1oOEnbA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
@ -7502,6 +7499,12 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/three": {
|
||||
"version": "0.134.0",
|
||||
"resolved": "https://registry.npmjs.org/three/-/three-0.134.0.tgz",
|
||||
"integrity": "sha512-LbBerg7GaSPjYtTOnu41AMp7tV6efUNR3p4Wk5NzkSsNTBuA5mDGOfwwZL1jhhVMLx9V20HolIUo0+U3AXehbg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tiny-typed-emitter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz",
|
||||
@ -7609,6 +7612,20 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.8.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz",
|
||||
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/unbox-primitive": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz",
|
||||
@ -7843,6 +7860,28 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-electron": {
|
||||
"version": "0.29.0",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-electron/-/vite-plugin-electron-0.29.0.tgz",
|
||||
"integrity": "sha512-HP0DI9Shg41hzt55IKYVnbrChWXHX95QtsEQfM+szQBpWjVhVGMlqRjVco6ebfQjWNr+Ga+PeoBjMIl8zMaufw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"vite-plugin-electron-renderer": "*"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"vite-plugin-electron-renderer": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/vite-plugin-electron-renderer": {
|
||||
"version": "0.14.6",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-electron-renderer/-/vite-plugin-electron-renderer-0.14.6.tgz",
|
||||
"integrity": "sha512-oqkWFa7kQIkvHXG7+Mnl1RTroA4sP0yesKatmAy0gjZC4VwUqlvF9IvOpHd1fpLWsqYX/eZlVxlhULNtaQ78Jw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vite-plugin-pwa": {
|
||||
"version": "0.21.1",
|
||||
"resolved": "https://registry.npmjs.org/vite-plugin-pwa/-/vite-plugin-pwa-0.21.1.tgz",
|
||||
@ -8328,6 +8367,17 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/wintersky": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/wintersky/-/wintersky-1.3.2.tgz",
|
||||
"integrity": "sha512-QnhQF9/5dApuy55xqkhsGTsYpXjsPRTIRcoY3eFGkmtOXmj+AGXusvLg66EIApzYBAYQzyQetePkN4Tr0OxpYQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"molangjs": "^1.6.3",
|
||||
"three": "^0.134.0",
|
||||
"tinycolor2": "^1.4.2"
|
||||
}
|
||||
},
|
||||
"node_modules/workbox-background-sync": {
|
||||
"version": "6.5.3",
|
||||
"resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.3.tgz",
|
||||
|
32
package.json
32
package.json
@ -12,8 +12,13 @@
|
||||
"type": "git",
|
||||
"url": "https://github.com/JannisX11/blockbench"
|
||||
},
|
||||
"main": "main.js",
|
||||
"main": "electron/main.js",
|
||||
"type": "module",
|
||||
"debug": {
|
||||
"env": {
|
||||
"VITE_DEV_SERVER_URL": "http://127.0.0.1:3344/"
|
||||
}
|
||||
},
|
||||
"build": {
|
||||
"afterSign": "scripts/notarize.js",
|
||||
"appId": "blockbench",
|
||||
@ -115,22 +120,25 @@
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"dev-electron": "electron . && vite",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"dist": "electron-builder",
|
||||
"build-beta": "electron-builder --windows portable",
|
||||
"publish-windows": "npm run build && electron-builder -w --publish=onTagOrDraft && node ./scripts/rename_portable.js && electron-builder --windows portable --publish=onTagOrDraft",
|
||||
"prepublish": "npm run build",
|
||||
"prepublish-beta": "node ./scripts/enable_beta.js && npm run build",
|
||||
"dev": "vite --config vite.electron.config.js",
|
||||
"dev-web": "vite --config vite.web.config.js",
|
||||
"build-web": "vite build --config vite.web.config.js",
|
||||
"build-electron": "vite build --config vite.web.electron.js",
|
||||
"preview": "vite preview --config vite.web.config.js",
|
||||
"build-beta": "npm run build-electron && electron-builder --windows portable",
|
||||
"publish-windows": "npm run build-electron && electron-builder -w --publish=onTagOrDraft && node ./scripts/rename_portable.js && electron-builder --windows portable --publish=onTagOrDraft",
|
||||
"prepublish": "npm run build-web",
|
||||
"prepublish-beta": "node ./scripts/enable_beta.js && npm run build-web",
|
||||
"webapp": "git checkout gh-pages && git pull && git merge master && git push && git checkout master"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron/notarize": "^2.5.0",
|
||||
"electron": "^33.3.1",
|
||||
"electron-builder": "^24.13.3",
|
||||
"typescript": "^5.8.2",
|
||||
"vite": "^6.2.0",
|
||||
"vite-plugin-electron": "^0.29.0",
|
||||
"vite-plugin-electron-renderer": "^0.14.6",
|
||||
"vite-plugin-pwa": "^0.21.1",
|
||||
"workbox-build": "^6.5.3"
|
||||
},
|
||||
@ -140,6 +148,8 @@
|
||||
"electron-updater": "^6.3.4",
|
||||
"gifenc": "^1.0.3",
|
||||
"jquery": "^3.7.1",
|
||||
"tinycolor2": "^1.6.0"
|
||||
"molangjs": "^1.6.5",
|
||||
"tinycolor2": "^1.6.0",
|
||||
"wintersky": "^1.3.2"
|
||||
}
|
||||
}
|
||||
|
20
tsconfig.json
Normal file
20
tsconfig.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"include": [
|
||||
"js/**/*",
|
||||
"types/**/*"
|
||||
],
|
||||
"compilerOptions": {
|
||||
"target": "ES6",
|
||||
"useDefineForClassFields": true,
|
||||
"module": "ES6",
|
||||
"moduleResolution": "Node",
|
||||
"jsx": "preserve",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"esModuleInterop": true,
|
||||
"lib": ["ES6", "DOM"],
|
||||
"skipLibCheck": true,
|
||||
"noEmit": true,
|
||||
"allowJs": true
|
||||
}
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
import { fileURLToPath, URL } from 'node:url'
|
||||
|
||||
import { defineConfig } from 'vite'
|
||||
import { VitePWA } from 'vite-plugin-pwa'
|
||||
// import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
build: {
|
||||
outDir: './dist-vite'
|
||||
},
|
||||
plugins: [
|
||||
VitePWA({
|
||||
registerType: 'autoUpdate',
|
||||
workbox: {
|
||||
cacheId: 'blockbench',
|
||||
globDirectory: './',
|
||||
globPatterns: [
|
||||
'./index.html',
|
||||
'./favicon.png',
|
||||
'./icon_maskable.png',
|
||||
|
||||
'./js/**/*',
|
||||
'./bundle.js',
|
||||
'./lib/**/*',
|
||||
'./css/**/*',
|
||||
'./assets/**/*',
|
||||
'./font/*',
|
||||
],
|
||||
swDest: './service_worker.js',
|
||||
maximumFileSizeToCacheInBytes: 4_096_000,
|
||||
sourcemap: false
|
||||
}
|
||||
|
||||
})
|
||||
//vue(),
|
||||
],
|
||||
/*
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||
}
|
||||
}
|
||||
*/
|
||||
})
|
74
vite.electron.config.js
Normal file
74
vite.electron.config.js
Normal file
@ -0,0 +1,74 @@
|
||||
import fs from 'node:fs'
|
||||
import { defineConfig } from 'vite'
|
||||
import electron from 'vite-plugin-electron/simple'
|
||||
import pkg from './package.json'
|
||||
|
||||
// import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
fs.rmSync('dist-electron', { recursive: true, force: true })
|
||||
|
||||
const isServe = command === 'serve'
|
||||
const isBuild = command === 'build'
|
||||
const sourcemap = isServe || !!process.env.VSCODE_DEBUG
|
||||
|
||||
return {
|
||||
build: {
|
||||
outDir: './dist-vite'
|
||||
},
|
||||
plugins: [
|
||||
// vue(),
|
||||
electron({
|
||||
main: {
|
||||
// Shortcut of `build.lib.entry`
|
||||
entry: 'electron/main.js',
|
||||
onstart({ startup }) {
|
||||
if (process.env.VSCODE_DEBUG) {
|
||||
console.log(/* For `.vscode/.debug.script.mjs` */'[startup] Electron App')
|
||||
} else {
|
||||
startup()
|
||||
}
|
||||
},
|
||||
vite: {
|
||||
build: {
|
||||
sourcemap,
|
||||
minify: isBuild,
|
||||
outDir: 'dist-electron/main',
|
||||
rollupOptions: {
|
||||
// Some third-party Node.js libraries may not be built correctly by Vite, especially `C/C++` addons,
|
||||
// we can use `external` to exclude them to ensure they work correctly.
|
||||
// Others need to put them in `dependencies` to ensure they are collected into `app.asar` after the app is built.
|
||||
// Of course, this is not absolute, just this way is relatively simple. :)
|
||||
external: Object.keys('dependencies' in pkg ? pkg.dependencies : {}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
preload: {
|
||||
// Shortcut of `build.rollupOptions.input`.
|
||||
// Preload scripts may contain Web assets, so use the `build.rollupOptions.input` instead `build.lib.entry`.
|
||||
input: 'electron/preload/index.ts',
|
||||
vite: {
|
||||
build: {
|
||||
sourcemap: sourcemap ? 'inline' : undefined, // #332
|
||||
minify: isBuild,
|
||||
outDir: 'dist-electron/preload',
|
||||
rollupOptions: {
|
||||
external: Object.keys('dependencies' in pkg ? pkg.dependencies : {}),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
// Ployfill the Electron and Node.js API for Renderer process.
|
||||
// If you want use Node.js in Renderer process, the `nodeIntegration` needs to be enabled in the Main process.
|
||||
// See 👉 https://github.com/electron-vite/vite-plugin-electron-renderer
|
||||
renderer: {},
|
||||
}),
|
||||
],
|
||||
server: {
|
||||
cors: false,
|
||||
},
|
||||
clearScreen: false,
|
||||
}
|
||||
})
|
41
vite.web.config.js
Normal file
41
vite.web.config.js
Normal file
@ -0,0 +1,41 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import { VitePWA } from 'vite-plugin-pwa'
|
||||
import pkg from './package.json'
|
||||
|
||||
// import vue from '@vitejs/plugin-vue'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig(({ command, mode }) => {
|
||||
|
||||
return {
|
||||
build: {
|
||||
outDir: './dist-vite'
|
||||
},
|
||||
plugins: [
|
||||
// vue(),
|
||||
VitePWA({
|
||||
registerType: 'autoUpdate',
|
||||
workbox: {
|
||||
cacheId: 'blockbench',
|
||||
globDirectory: './',
|
||||
globPatterns: [
|
||||
'./index.html',
|
||||
'./favicon.png',
|
||||
'./icon_maskable.png',
|
||||
|
||||
'./js/**/*',
|
||||
'./bundle.js',
|
||||
'./lib/**/*',
|
||||
'./css/**/*',
|
||||
'./assets/**/*',
|
||||
'./font/*',
|
||||
],
|
||||
swDest: './service_worker.js',
|
||||
maximumFileSizeToCacheInBytes: 4_096_000,
|
||||
sourcemap: false
|
||||
}
|
||||
}),
|
||||
],
|
||||
clearScreen: false,
|
||||
}
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user