mirror of
https://github.com/scratchfoundation/scratch-desktop.git
synced 2024-12-23 06:02:30 -05:00
commit
8dcbbfe5c9
4 changed files with 106 additions and 19 deletions
|
@ -1,4 +1,4 @@
|
|||
import {BrowserWindow, Menu, app, dialog} from 'electron';
|
||||
import {BrowserWindow, Menu, app, dialog, ipcMain} from 'electron';
|
||||
import * as path from 'path';
|
||||
import {format as formatUrl} from 'url';
|
||||
import {getFilterForExtension} from './FileFilters';
|
||||
|
@ -13,20 +13,17 @@ const defaultSize = {width: 1280, height: 800}; // good for MAS screenshots
|
|||
|
||||
const isDevelopment = process.env.NODE_ENV !== 'production';
|
||||
|
||||
const createMainWindow = () => {
|
||||
// global window references prevent them from being garbage-collected
|
||||
const _windows = {};
|
||||
|
||||
const createWindow = ({url, ...browserWindowOptions}) => {
|
||||
const window = new BrowserWindow({
|
||||
width: defaultSize.width,
|
||||
height: defaultSize.height,
|
||||
useContentSize: true,
|
||||
show: false
|
||||
show: false,
|
||||
...browserWindowOptions
|
||||
});
|
||||
const webContents = window.webContents;
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
const osxMenu = Menu.buildFromTemplate(MacOSMenu(app));
|
||||
Menu.setApplicationMenu(osxMenu);
|
||||
}
|
||||
|
||||
if (isDevelopment) {
|
||||
webContents.openDevTools();
|
||||
import('electron-devtools-installer').then(importedModule => {
|
||||
|
@ -46,15 +43,38 @@ const createMainWindow = () => {
|
|||
});
|
||||
|
||||
if (isDevelopment) {
|
||||
window.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}`);
|
||||
window.loadURL(`http://localhost:${process.env.ELECTRON_WEBPACK_WDS_PORT}/${url}`);
|
||||
} else {
|
||||
window.loadURL(formatUrl({
|
||||
pathname: path.join(__dirname, 'index.html'),
|
||||
pathname: path.join(__dirname, url),
|
||||
protocol: 'file',
|
||||
slashes: true
|
||||
}));
|
||||
}
|
||||
|
||||
return window;
|
||||
};
|
||||
|
||||
const createAboutWindow = () => {
|
||||
const window = createWindow({
|
||||
width: 400,
|
||||
height: 400,
|
||||
parent: _windows.main,
|
||||
title: 'About Scratch Desktop',
|
||||
url: 'index.html?route=about'
|
||||
});
|
||||
return window;
|
||||
};
|
||||
|
||||
const createMainWindow = () => {
|
||||
const window = createWindow({
|
||||
width: defaultSize.width,
|
||||
height: defaultSize.height,
|
||||
title: 'Scratch Desktop',
|
||||
url: 'index.html'
|
||||
});
|
||||
const webContents = window.webContents;
|
||||
|
||||
webContents.session.on('will-download', (ev, item) => {
|
||||
const itemPath = item.getFilename();
|
||||
const baseName = path.basename(itemPath);
|
||||
|
@ -104,6 +124,11 @@ const createMainWindow = () => {
|
|||
return window;
|
||||
};
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
const osxMenu = Menu.buildFromTemplate(MacOSMenu(app));
|
||||
Menu.setApplicationMenu(osxMenu);
|
||||
}
|
||||
|
||||
// quit application when all windows are closed
|
||||
app.on('window-all-closed', () => {
|
||||
app.quit();
|
||||
|
@ -113,13 +138,19 @@ app.on('will-quit', () => {
|
|||
telemetry.appWillClose();
|
||||
});
|
||||
|
||||
// global reference to mainWindow (necessary to prevent window from being garbage collected)
|
||||
let _mainWindow;
|
||||
|
||||
// create main BrowserWindow when electron is ready
|
||||
app.on('ready', () => {
|
||||
_mainWindow = createMainWindow();
|
||||
_mainWindow.on('closed', () => {
|
||||
_mainWindow = null;
|
||||
_windows.main = createMainWindow();
|
||||
_windows.main.on('closed', () => {
|
||||
delete _windows.main;
|
||||
});
|
||||
_windows.about = createAboutWindow();
|
||||
_windows.about.on('close', event => {
|
||||
event.preventDefault();
|
||||
_windows.about.hide();
|
||||
});
|
||||
});
|
||||
|
||||
ipcMain.on('open-about-window', () => {
|
||||
_windows.about.show();
|
||||
});
|
||||
|
|
43
src/renderer/about.jsx
Normal file
43
src/renderer/about.jsx
Normal file
|
@ -0,0 +1,43 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import {author, productName, version} from '../../package.json';
|
||||
|
||||
import logo from '../icon/ScratchDesktop.svg';
|
||||
|
||||
// TODO: localization?
|
||||
const AboutElement = () => (
|
||||
<div
|
||||
style={{
|
||||
color: 'white',
|
||||
fontFamily: '"Helvetica Neue", Helvetica, Arial, sans-serif',
|
||||
fontWeight: 'bolder',
|
||||
margin: 0,
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
transform: 'translate(-50%, -50%)'
|
||||
}}
|
||||
>
|
||||
<div><img
|
||||
alt={`${productName} icon`}
|
||||
src={logo}
|
||||
style={{
|
||||
maxWidth: '10rem',
|
||||
maxHeight: '10rem'
|
||||
}}
|
||||
/></div>
|
||||
<h2>{productName}</h2>
|
||||
<div>Version {version}</div>
|
||||
<table style={{fontSize: 'x-small'}}>
|
||||
{
|
||||
['Electron', 'Chrome'].map(component => {
|
||||
const componentVersion = process.versions[component.toLowerCase()];
|
||||
return <tr key={component}><td>{component}</td><td>{componentVersion}</td></tr>;
|
||||
})
|
||||
}
|
||||
</table>
|
||||
</div>
|
||||
);
|
||||
|
||||
const appTarget = document.getElementById('app');
|
||||
ReactDOM.render(<AboutElement />, appTarget);
|
|
@ -45,6 +45,9 @@ const ScratchDesktopHOC = function (WrappedComponent) {
|
|||
componentWillUnmount () {
|
||||
ipcRenderer.removeListener('setTitleFromSave', this.handleSetTitleFromSave);
|
||||
}
|
||||
handleClickLogo () {
|
||||
ipcRenderer.send('open-about-window');
|
||||
}
|
||||
handleProjectTelemetryEvent (event, metadata) {
|
||||
ipcRenderer.send(event, metadata);
|
||||
}
|
||||
|
@ -66,6 +69,7 @@ const ScratchDesktopHOC = function (WrappedComponent) {
|
|||
isScratchDesktop
|
||||
projectId={defaultProjectId}
|
||||
showTelemetryModal={shouldShowTelemetryModal}
|
||||
onClickLogo={this.handleClickLogo}
|
||||
onProjectTelemetryEvent={this.handleProjectTelemetryEvent}
|
||||
onStorageInit={this.handleStorageInit}
|
||||
onTelemetryModalOptIn={this.handleTelemetryModalOptIn}
|
||||
|
|
|
@ -1,3 +1,12 @@
|
|||
// this is an async import so that it doesn't block the first render
|
||||
// index.html contains a loading/splash screen which will display while this import loads
|
||||
import('./app.jsx');
|
||||
|
||||
const route = new URLSearchParams(window.location.search).get('route') || 'app';
|
||||
switch (route) {
|
||||
case 'app':
|
||||
import('./app.jsx');
|
||||
break;
|
||||
case 'about':
|
||||
import('./about.jsx');
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue