Compare commits

...
23 Commits
Author SHA1 Message Date
Thomas Weber dd83af71fd Changes to match TW/desktop 2021-01-09 15:13:15 -06:00
Thomas Weber e795bdc0cb Update to handle async prompt 2021-01-07 15:44:29 -06:00
Thomas Weber dc68458634 Merge branch 'develop' into desktop 2021-01-07 15:44:11 -06:00
Thomas Weber 5c25b07e1e Remove llinks to privacy policy, embedding, and URL parameters
These do not make sense in desktop.
2021-01-07 15:43:35 -06:00
Thomas Weber dcd5ac11b1 Add cloud unavailable message specific to offline editor 2021-01-07 13:55:00 -06:00
Thomas Weber 17630e0812 Fetch library items from library-files/ 2021-01-07 13:54:36 -06:00
Thomas Weber 7db75dbf6d Remove progress bar logic
Closes https://github.com/TurboWarp/desktop/issues/8
2021-01-06 20:19:03 -06:00
Thomas Weber edadc3ac7f "autosave" -> "restore point" 2021-01-06 13:39:43 -06:00
Thomas Weber d2e7c4fdaf Revert webpack config changes 2021-01-06 13:39:05 -06:00
Thomas Weber d573691288 Merge branch 'develop' into desktop 2021-01-06 13:38:32 -06:00
Thomas Weber 5df9370307 Don't reference a file that doesn't exist 2021-01-05 20:02:32 -06:00
Thomas Weber 172df1b808 Don't ignore src 2021-01-05 17:54:28 -06:00
Thomas Weber cfc01bc136 Add link to license 2021-01-05 17:33:45 -06:00
Thomas Weber 3084d2489e Await prompt() because it's going to be replaced with an async method in electron 2021-01-05 16:43:13 -06:00
Thomas Weber aa1e099570 Merge branch 'develop' into desktop 2021-01-05 15:39:44 -06:00
Thomas Weber 63f4707fc6 Set env vars 2021-01-05 15:22:50 -06:00
Thomas Weber 5a238b3459 Remove legacy download option 2021-01-05 15:22:42 -06:00
Thomas Weber 6900b2b64e Update translations 2021-01-05 11:38:08 -06:00
Thomas Weber 544b2bae83 Don't even load en-steps 2021-01-05 11:15:42 -06:00
Thomas Weber d192466784 Disable addon loading 2021-01-04 18:37:34 -06:00
Thomas Weber fa3f030d1c Disable onbeforeunload 2021-01-04 18:37:29 -06:00
Thomas Weber 629d832304 Fix package and webpack config 2021-01-04 18:37:18 -06:00
Thomas Weber 0f3ab023b0 Disable the editor warning 2021-01-04 17:57:02 -06:00
15 changed files with 38 additions and 102 deletions

No files matched your search

-3
View File
@@ -5,9 +5,6 @@
/node_modules /node_modules
npm-* npm-*
# Double copies of all the static assets and tutorial gifs
/src
# Testing # Testing
/.nyc_output /.nyc_output
/coverage /coverage
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "scratch-gui", "name": "scratch-gui",
"version": "0.1.0", "version": "0.1.0",
"description": "GraphicaL User Interface for creating and running Scratch 3.0 projects", "description": "GraphicaL User Interface for creating and running Scratch 3.0 projects",
"main": "./dist/scratch-gui.js", "main": "./dist/js/scratch-gui.js",
"scripts": { "scripts": {
"build": "npm run clean && webpack --colors --bail", "build": "npm run clean && webpack --colors --bail",
"clean": "rimraf ./build && mkdirp build && rimraf ./dist && mkdirp dist", "clean": "rimraf ./build && mkdirp build && rimraf ./dist && mkdirp dist",
+1 -1
View File
@@ -1,7 +1,7 @@
let loaded = false; let loaded = false;
const load = () => { const load = () => {
import(/* webpackChunkName: "addons" */ './index'); // import(/* webpackChunkName: "addons" */ './index');
}; };
const loadAddons = () => { const loadAddons = () => {
+3 -39
View File
@@ -9,8 +9,6 @@ import topBlock from './top-block.svg';
import middleBlock from './middle-block.svg'; import middleBlock from './middle-block.svg';
import bottomBlock from './bottom-block.svg'; import bottomBlock from './bottom-block.svg';
import * as progressMonitor from './tw-progress-monitor';
// tw: // tw:
// we make some rather large changes here: // we make some rather large changes here:
// - remove random message, replaced with message dependent on what is actually being loaded // - remove random message, replaced with message dependent on what is actually being loaded
@@ -19,6 +17,9 @@ import * as progressMonitor from './tw-progress-monitor';
// The way of doing this is extremely unusual and weird compared to how things are typically done for performance. // The way of doing this is extremely unusual and weird compared to how things are typically done for performance.
// This is because react updates are too performance crippling to handle the progress bar rapidly updating. // This is because react updates are too performance crippling to handle the progress bar rapidly updating.
// tw:
// progress bar logic removed entirely as it is unneeded in desktop build
const mainMessages = { const mainMessages = {
'gui.loader.headline': ( 'gui.loader.headline': (
<FormattedMessage <FormattedMessage
@@ -63,41 +64,13 @@ class LoaderComponent extends React.Component {
constructor (props) { constructor (props) {
super(props); super(props);
this._state = 0; this._state = 0;
this.progress = 0;
this.complete = 0;
this.total = 0;
bindAll(this, [ bindAll(this, [
'barInnerRef',
'handleProgressChange',
'messageRef' 'messageRef'
]); ]);
} }
componentDidMount () { componentDidMount () {
progressMonitor.setProgressHandler(this.handleProgressChange);
this.updateMessage(); this.updateMessage();
} }
componentDidUpdate () {
this.update();
}
componentWillUnmount () {
progressMonitor.setProgressHandler(() => {});
}
handleProgressChange (state, progress, complete, total) {
if (state !== this._state) {
this._state = state;
this.updateMessage();
}
this.progress = progress;
this.complete = complete;
this.total = total;
this.update();
}
update () {
this.barInner.style.width = `${this.progress * 100}%`;
if (this._state === 2) {
this.updateMessage();
}
}
updateMessage () { updateMessage () {
if (this._state === 0) { if (this._state === 0) {
this.message.textContent = this.props.intl.formatMessage(messages.generic); this.message.textContent = this.props.intl.formatMessage(messages.generic);
@@ -112,9 +85,6 @@ class LoaderComponent extends React.Component {
this.message.textContent = this.props.intl.formatMessage(messages.assetsUnknown); this.message.textContent = this.props.intl.formatMessage(messages.assetsUnknown);
} }
} }
barInnerRef (element) {
this.barInner = element;
}
messageRef (element) { messageRef (element) {
this.message = element; this.message = element;
} }
@@ -149,12 +119,6 @@ class LoaderComponent extends React.Component {
ref={this.messageRef} ref={this.messageRef}
/> />
</div> </div>
<div className={styles.twProgressOuter}>
<div
className={styles.twProgressInner}
ref={this.barInnerRef}
/>
</div>
</div> </div>
</div> </div>
); );
+1 -1
View File
@@ -225,7 +225,7 @@
} }
.mystuff > a { .mystuff > a {
background-image: url("/images/mystuff.png"); /* background-image: url("/images/mystuff.png"); */
} }
.about-icon { .about-icon {
+12 -43
View File
@@ -384,7 +384,7 @@ class MenuBar extends React.Component {
> >
<div className={styles.mainMenu}> <div className={styles.mainMenu}>
<div className={styles.fileGroup}> <div className={styles.fileGroup}>
{this.props.onClickLogo ? ( {false && this.props.onClickLogo ? (
<div className={classNames(styles.menuBarItem)}> <div className={classNames(styles.menuBarItem)}>
<img <img
alt="Scratch" alt="Scratch"
@@ -552,30 +552,6 @@ class MenuBar extends React.Component {
</MenuItem> </MenuItem>
</React.Fragment> </React.Fragment>
)} )}
<MenuItem onClick={this.getSaveToComputerHandler(downloadProject)}>
{extended.available ? (
<FormattedMessage
defaultMessage="{saveToYourComputer} (legacy)"
description="Wrapper around 'Save to your computer' when a more modern API is available" // eslint-disable-line max-len
id="tw.menuBar.legacyDownloadToComputer"
values={{
saveToYourComputer: (
<FormattedMessage
defaultMessage="Save to your computer"
description="Menu bar item for downloading a project to your computer" // eslint-disable-line max-len
id="gui.menuBar.downloadToComputer"
/>
)
}}
/>
) : (
<FormattedMessage
defaultMessage="Save to your computer"
description="Menu bar item for downloading a project to your computer" // eslint-disable-line max-len
id="gui.menuBar.downloadToComputer"
/>
)}
</MenuItem>
</React.Fragment> </React.Fragment>
)}</SB3Downloader> )}</SB3Downloader>
</MenuSection> </MenuSection>
@@ -830,6 +806,13 @@ class MenuBar extends React.Component {
onRequestClose={this.props.onRequestCloseHelp} onRequestClose={this.props.onRequestCloseHelp}
> >
<MenuSection> <MenuSection>
<MenuItem onClick={this.props.onClickLogo}>
<FormattedMessage
defaultMessage="About, credits, license"
description="Link to about in desktop"
id="tw.desktop.about"
/>
</MenuItem>
<MenuItemLink href="https://github.com/TurboWarp"> <MenuItemLink href="https://github.com/TurboWarp">
<FormattedMessage <FormattedMessage
defaultMessage="Source Code" defaultMessage="Source Code"
@@ -837,18 +820,11 @@ class MenuBar extends React.Component {
id="tw.code" id="tw.code"
/> />
</MenuItemLink> </MenuItemLink>
<MenuItemLink href="/privacy.html"> <MenuItemLink href="https://desktop.turbowarp.org">
<FormattedMessage <FormattedMessage
defaultMessage="Privacy" defaultMessage="Website"
description="Link to privacy policy" description="Link to website in desktop"
id="tw.privacy" id="tw.desktop.website"
/>
</MenuItemLink>
<MenuItemLink href="https://github.com/TurboWarp/scratch-gui/wiki/Embedding">
<FormattedMessage
defaultMessage="Embedding"
description="Menu bar item for embedding link"
id="tw.menuBar.embed"
/> />
</MenuItemLink> </MenuItemLink>
<MenuItemLink href="https://github.com/TurboWarp/scratch-gui/wiki/TurboWarp-blocks"> <MenuItemLink href="https://github.com/TurboWarp/scratch-gui/wiki/TurboWarp-blocks">
@@ -858,13 +834,6 @@ class MenuBar extends React.Component {
id="tw.menuBar.blocks" id="tw.menuBar.blocks"
/> />
</MenuItemLink> </MenuItemLink>
<MenuItemLink href="https://github.com/TurboWarp/scratch-gui/wiki/URL-Parameters">
<FormattedMessage
defaultMessage="URL Parameters"
description="Menu bar item for URL parameters link"
id="tw.menuBar.parameters"
/>
</MenuItemLink>
<MenuItemLink href="https://github.com/TurboWarp/translations/blob/master/CONTRIBUTING.md#readme"> <MenuItemLink href="https://github.com/TurboWarp/translations/blob/master/CONTRIBUTING.md#readme">
<FormattedMessage <FormattedMessage
defaultMessage="Help Translate TurboWarp" defaultMessage="Help Translate TurboWarp"
+1 -1
View File
@@ -106,7 +106,7 @@ class LibraryItem extends React.PureComponent {
render () { render () {
const iconMd5 = this.curIconMd5(); const iconMd5 = this.curIconMd5();
const iconURL = iconMd5 ? const iconURL = iconMd5 ?
`https://cdn.assets.scratch.mit.edu/internalapi/asset/${iconMd5}/get/` : `library-files/${iconMd5}` :
this.props.iconRawURL; this.props.iconRawURL;
return ( return (
<LibraryItemComponent <LibraryItemComponent
+2 -2
View File
@@ -167,12 +167,12 @@ class Monitor extends React.Component {
this.element = monitorElt; this.element = monitorElt;
} }
handleImport () { handleImport () {
importCSV().then(rows => { importCSV().then(async rows => {
const numberOfColumns = rows[0].length; const numberOfColumns = rows[0].length;
let columnNumber = 1; let columnNumber = 1;
if (numberOfColumns > 1) { if (numberOfColumns > 1) {
const msg = this.props.intl.formatMessage(messages.columnPrompt, {numberOfColumns}); const msg = this.props.intl.formatMessage(messages.columnPrompt, {numberOfColumns});
columnNumber = parseInt(prompt(msg), 10); // eslint-disable-line no-alert columnNumber = parseInt(await prompt(msg), 10); // eslint-disable-line no-alert
} }
const newListValue = rows.map(row => row[columnNumber - 1]) const newListValue = rows.map(row => row[columnNumber - 1])
.filter(item => typeof item === 'string'); // CSV importer can leave undefineds .filter(item => typeof item === 'string'); // CSV importer can leave undefineds
+2 -2
View File
@@ -20,9 +20,9 @@ class ChangeUsername extends React.Component {
'changeUsername' 'changeUsername'
]); ]);
} }
changeUsername () { async changeUsername () {
// eslint-disable-next-line no-alert // eslint-disable-next-line no-alert
const newUsername = prompt(this.props.intl.formatMessage(messages.usernamePrompt), this.props.username); const newUsername = await prompt(this.props.intl.formatMessage(messages.usernamePrompt), this.props.username);
if (newUsername === null) { if (newUsername === null) {
return; return;
} }
+7 -1
View File
@@ -4,12 +4,18 @@ import React from 'react';
import {defineMessages, injectIntl, intlShape} from 'react-intl'; import {defineMessages, injectIntl, intlShape} from 'react-intl';
import {connect} from 'react-redux'; import {connect} from 'react-redux';
import {setCloud} from '../reducers/tw'; import {setCloud} from '../reducers/tw';
import {isScratchDesktop} from '../lib/isScratchDesktop';
const messages = defineMessages({ const messages = defineMessages({
cloudUnavailableAlert: { cloudUnavailableAlert: {
defaultMessage: 'Cannot use cloud variables, most likely because you opened the editor.', defaultMessage: 'Cannot use cloud variables, most likely because you opened the editor.',
description: 'Message displayed when clicking on the option to toggle cloud variables when cloud variables are not available', description: 'Message displayed when clicking on the option to toggle cloud variables when cloud variables are not available',
id: 'tw.menuBar.cloudUnavailableAlert' id: 'tw.menuBar.cloudUnavailableAlert'
},
offlineEditorAlert: {
defaultMessage: 'Cannot use cloud variables in offline editor.',
description: 'Message displayed when clicking on the option to toggle cloud variables in offline editor',
id: 'tw.menuBar.cloudUnavailableOfflineEditorAlert'
} }
}); });
@@ -23,7 +29,7 @@ class CloudVariablesToggler extends React.Component {
toggleCloudVariables () { toggleCloudVariables () {
if (!this.props.canUseCloudVariables) { if (!this.props.canUseCloudVariables) {
// eslint-disable-next-line no-alert // eslint-disable-next-line no-alert
alert(this.props.intl.formatMessage(messages.cloudUnavailableAlert)); alert(this.props.intl.formatMessage(isScratchDesktop() ? messages.offlineEditorAlert : messages.cloudUnavailableAlert));
return; return;
} }
this.props.onCloudChange(!this.props.enabled); this.props.onCloudChange(!this.props.enabled);
+2 -2
View File
@@ -20,10 +20,10 @@ class FramerateChanger extends React.Component {
'changeFramerate' 'changeFramerate'
]); ]);
} }
changeFramerate (e) { async changeFramerate (e) {
if (e && (e.ctrlKey || e.shiftKey)) { if (e && (e.ctrlKey || e.shiftKey)) {
// eslint-disable-next-line no-alert // eslint-disable-next-line no-alert
const newFPS = prompt(this.props.intl.formatMessage(messages.newFramerate), this.props.framerate); const newFPS = await prompt(this.props.intl.formatMessage(messages.newFramerate), this.props.framerate);
if (newFPS === null) { if (newFPS === null) {
return; return;
} }
+1 -1
View File
@@ -3,7 +3,7 @@
* Utility functions for handling tutorial images in multiple languages * Utility functions for handling tutorial images in multiple languages
*/ */
import {enImages as defaultImages} from './en-steps.js'; const defaultImages = {};
let savedImages = {}; let savedImages = {};
let savedLocale = ''; let savedLocale = '';
+1 -1
View File
@@ -57,7 +57,7 @@ const ProjectSaverHOC = function (WrappedComponent) {
if (typeof window === 'object') { if (typeof window === 'object') {
// Note: it might be better to use a listener instead of assigning onbeforeunload; // Note: it might be better to use a listener instead of assigning onbeforeunload;
// but then it'd be hard to turn this listening off in our tests // but then it'd be hard to turn this listening off in our tests
window.onbeforeunload = e => this.leavePageConfirm(e); // window.onbeforeunload = e => this.leavePageConfirm(e);
} }
// Allow the GUI consumer to pass in a function to receive a trigger // Allow the GUI consumer to pass in a function to receive a trigger
+1 -1
View File
@@ -41,7 +41,7 @@ const TWEditorWarningHOC = function (WrappedComponent) {
if (!this.props.isPlayerOnly) { if (!this.props.isPlayerOnly) {
shownWarning = true; shownWarning = true;
this.props.onShowWarning(); // this.props.onShowWarning();
this.props.vm.setCompilerOptions({ this.props.vm.setCompilerOptions({
warpTimer: true warpTimer: true
}); });
+3 -3
View File
@@ -41,8 +41,8 @@ const base = {
}, },
output: { output: {
library: 'GUI', library: 'GUI',
filename: process.env.NODE_ENV === 'production' ? 'js/[name].[contenthash].js' : 'js/[name].js', filename: process.env.NODE_ENV === 'production' ? 'js/[name].js' : 'js/[name].js',
chunkFilename: process.env.NODE_ENV === 'production' ? 'js/[name].[contenthash].js' : 'js/[name].js', chunkFilename: process.env.NODE_ENV === 'production' ? 'js/[name].js' : 'js/[name].js',
publicPath: root publicPath: root
}, },
externals: { externals: {
@@ -220,7 +220,7 @@ module.exports = [
output: { output: {
libraryTarget: 'umd', libraryTarget: 'umd',
path: path.resolve('dist'), path: path.resolve('dist'),
publicPath: `${STATIC_PATH}/` // publicPath: `${STATIC_PATH}/`
}, },
externals: { externals: {
React: 'react', React: 'react',