Skip to content

Commit

Permalink
Merge pull request #27433 from code-dot-org/staging
Browse files Browse the repository at this point in the history
DTT (Staging > Test) [robo-dtt]
  • Loading branch information
deploy-code-org committed Mar 8, 2019
2 parents 1ed814f + 70da3e0 commit 22d555c
Show file tree
Hide file tree
Showing 29 changed files with 532 additions and 123 deletions.
4 changes: 2 additions & 2 deletions apps/package.json
Expand Up @@ -42,7 +42,7 @@
"@code-dot-org/artist": "0.2.1",
"@code-dot-org/blockly": "3.4.2",
"@code-dot-org/bramble": "0.1.26",
"@code-dot-org/craft": "0.2.1",
"@code-dot-org/craft": "0.2.2",
"@code-dot-org/dance-party": "0.0.42",
"@code-dot-org/johnny-five": "0.11.1-cdo.2",
"@code-dot-org/js-interpreter-tyrant": "0.2.2",
Expand Down Expand Up @@ -217,6 +217,7 @@
},
"dependencies": {
"@code-dot-org/js-interpreter": "^1.3.8",
"@code-dot-org/snack-sdk": "2.2.0-apkurl-v2",
"crypto-js": "^3.1.9-1",
"details-element-polyfill": "https://github.com/javan/details-element-polyfill",
"filesaver.js": "0.2.0",
Expand All @@ -232,7 +233,6 @@
"react-portal": "^3.0.0",
"react-router-dom": "^4.3.1",
"selectize": "^0.12.4",
"snack-sdk": "2.0.0",
"wgxpath": "^1.2.0",
"whatwg-fetch": "^2.0.3"
}
Expand Down
40 changes: 33 additions & 7 deletions apps/src/applab/Exporter.js
Expand Up @@ -3,7 +3,7 @@ import $ from 'jquery';
import _ from 'lodash';
import JSZip from 'jszip';
import {saveAs} from 'filesaver.js';
import {SnackSession} from 'snack-sdk';
import {SnackSession} from '@code-dot-org/snack-sdk';

import * as applabConstants from './constants';
import * as assetPrefix from '../assetManagement/assetPrefix';
Expand All @@ -27,6 +27,7 @@ import exportExpoSplashPng from '../templates/export/expo/splash.png';
import logToCloud from '../logToCloud';
import {getAppOptions} from '@cdo/apps/code-studio/initApp/loadApp';
import project from '@cdo/apps/code-studio/initApp/project';
import {EXPO_SESSION_SECRET} from '../constants';

// This whitelist determines which appOptions properties
// will get exported with the applab app, appearing in the
Expand Down Expand Up @@ -550,10 +551,10 @@ export default {
});
},

async exportApp(appName, code, levelHtml, suppliedExpoOpts) {
async exportApp(appName, code, levelHtml, suppliedExpoOpts, config) {
const expoOpts = suppliedExpoOpts || {};
if (expoOpts.mode === 'expoPublish') {
return await this.publishToExpo(appName, code, levelHtml);
return await this.publishToExpo(appName, code, levelHtml, config);
}
return this.exportAppToZip(
appName,
Expand Down Expand Up @@ -597,7 +598,25 @@ export default {
return exportExpoPackagedFilesEjs({entries});
},

async publishToExpo(appName, code, levelHtml) {
async generateExpoApk(snackId, config) {
const session = new SnackSession({
sessionId: `${getEnvironmentPrefix()}-${project.getCurrentId()}`,
name: `project-${project.getCurrentId()}`,
sdkVersion: '31.0.0',
snackId,
user: {
sessionSecret: config.expoSession || EXPO_SESSION_SECRET
}
});

const appJson = session.generateAppJson();

const artifactUrl = await session.getApkUrlAsync(appJson);

return artifactUrl;
},

async publishToExpo(appName, code, levelHtml, config) {
const {css, outerHTML} = transformLevelHtml(levelHtml);
const fontAwesomeCSS = exportFontAwesomeCssEjs({
fontPath: fontAwesomeWOFFPath
Expand Down Expand Up @@ -642,7 +661,10 @@ export default {
sessionId: `${getEnvironmentPrefix()}-${project.getCurrentId()}`,
files,
name: project.getCurrentName(),
sdkVersion: '31.0.0'
sdkVersion: '31.0.0',
user: {
sessionSecret: config.expoSession || EXPO_SESSION_SECRET
}
});

// Important that index.html comes first:
Expand Down Expand Up @@ -707,9 +729,13 @@ export default {

await session.sendCodeAsync(files);
const saveResult = await session.saveAsync();
const expoURL = `exp://expo.io/@snack/${saveResult.id}`;
const expoUri = `exp://expo.io/${saveResult.id}`;
const expoSnackId = saveResult.id;

return expoURL;
return {
expoUri,
expoSnackId
};
}
};

Expand Down
9 changes: 8 additions & 1 deletion apps/src/applab/applab.js
Expand Up @@ -825,12 +825,19 @@ Applab.exportApp = function(expoOpts) {
Applab.runButtonClick();
var html = document.getElementById('divApplab').outerHTML;
studioApp().resetButtonClick();

const {mode, expoSnackId} = expoOpts || {};
if (mode === 'expoGenerateApk') {
return Exporter.generateExpoApk(expoSnackId, studioApp().config);
}

return Exporter.exportApp(
// TODO: find another way to get this info that doesn't rely on globals.
(window.dashboard && window.dashboard.project.getCurrentName()) || 'my-app',
studioApp().editor.getValue(),
html,
expoOpts
expoOpts,
studioApp().config
);
};

Expand Down
82 changes: 78 additions & 4 deletions apps/src/code-studio/components/AdvancedShareOptions.jsx
Expand Up @@ -62,6 +62,10 @@ const style = {
expoButtonLast: {
marginRight: 0
},
expoButtonApk: {
marginBottom: 10,
maxWidth: 280
},
expoContainer: {
display: 'flex',
flexDirection: 'column'
Expand Down Expand Up @@ -141,7 +145,8 @@ class AdvancedShareOptions extends React.Component {
try {
await this.props.exportApp({mode: 'expoZip'});
this.setState({
exportingExpo: null
exportingExpo: null,
exportExpoError: null
});
} catch (e) {
this.setState({
Expand All @@ -154,20 +159,48 @@ class AdvancedShareOptions extends React.Component {
publishExpoExport = async () => {
this.setState({exportingExpo: 'publish'});
try {
const expoUri = await this.props.exportApp({mode: 'expoPublish'});
const {expoUri, expoSnackId} = await this.props.exportApp({
mode: 'expoPublish'
});
this.setState({
exportingExpo: null,
expoUri
exportExpoError: null,
expoUri,
expoSnackId
});
} catch (e) {
this.setState({
exportingExpo: null,
expoUri: null,
expoSnackId: null,
exportExpoError:
'Failed to publish project to Expo. Please try again later.'
});
}
};

generateExpoApk = async () => {
const {expoSnackId} = this.state;
this.setState({generatingExpoApk: true});
try {
const expoApkUri = await this.props.exportApp({
mode: 'expoGenerateApk',
expoSnackId
});
this.setState({
generatingExpoApk: false,
generatingExpoApkError: null,
expoApkUri
});
} catch (e) {
this.setState({
generatingExpoApk: false,
generatingExpoApkError:
'Failed to create Android app. Please try again later.'
});
}
};

renderEmbedTab() {
let url = `${this.props.shareUrl}/embed`;
if (this.state.embedWithoutCode) {
Expand Down Expand Up @@ -241,7 +274,12 @@ class AdvancedShareOptions extends React.Component {
};

renderExportExpoTab() {
const {expoUri, exportedExpoZip} = this.state;
const {
expoUri,
exportedExpoZip,
expoApkUri,
generatingExpoApk
} = this.state;
const exportSpinner =
this.state.exportingExpo === 'zip' ? (
<i className="fa fa-spinner fa-spin" />
Expand All @@ -250,10 +288,21 @@ class AdvancedShareOptions extends React.Component {
this.state.exportingExpo === 'publish' ? (
<i className="fa fa-spinner fa-spin" />
) : null;
const generateApkSpinner = generatingExpoApk ? (
<i className="fa fa-spinner fa-spin" />
) : null;
// TODO: Make this use a nice UI component from somewhere.
const alert = this.state.exportExpoError ? (
<div className="alert fade in">{this.state.exportExpoError}</div>
) : null;
const apkAlert = this.state.generatingExpoApkError ? (
<div className="alert fade in">{this.state.generatingExpoApkError}</div>
) : null;
const apkStatusString = expoApkUri
? 'App created successfully'
: generatingExpoApk
? 'Creating app...'
: '(This will take 5-10 minutes)';

return (
<div>
Expand Down Expand Up @@ -307,6 +356,31 @@ class AdvancedShareOptions extends React.Component {
value={expoUri}
style={style.expoInput}
/>
<button
onClick={this.generateExpoApk}
style={[style.expoButton, style.expoButtonApk]}
>
{generateApkSpinner}
Create Android App
</button>
<p style={style.p}>{apkStatusString}</p>
{!!expoApkUri && (
<div>
<p style={[style.p, style.bold]}>
Send this URL to an Android phone:
</p>
</div>
)}
{!!expoApkUri && (
<input
type="text"
onClick={this.onInputSelect}
readOnly="true"
value={expoApkUri}
style={style.expoInput}
/>
)}
{apkAlert}
</div>
</div>
</div>
Expand Down
Expand Up @@ -32,7 +32,7 @@ export default class Releases extends LabeledFormComponent {
photo release.
</a>
</ControlLabel>
{this.singleCheckboxFor('photoRelease')}
{this.singleCheckboxFor('photoRelease', {required: false})}
<ControlLabel>
Please read this{' '}
<a
Expand Down
3 changes: 3 additions & 0 deletions apps/src/constants.js
Expand Up @@ -176,3 +176,6 @@ export const ALPHABET =
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
export const CIPHER =
'Iq61F8kiaUHPGcsY7DgX4yAu3LwtWhnCmeR5pVrJoKfQZMx0BSdlOjEv2TbN9z';

export const EXPO_SESSION_SECRET =
'{"id":"fakefake-67ec-4314-a438-60589b9c0fa2","version":1,"expires_at":2000000000000}';
42 changes: 34 additions & 8 deletions apps/src/gamelab/Exporter.js
Expand Up @@ -3,7 +3,7 @@
import $ from 'jquery';
import JSZip from 'jszip';
import {saveAs} from 'filesaver.js';
import {SnackSession} from 'snack-sdk';
import {SnackSession} from '@code-dot-org/snack-sdk';

import * as assetPrefix from '../assetManagement/assetPrefix';
import download from '../assetManagement/download';
Expand All @@ -23,6 +23,7 @@ import exportExpoSplashPng from '../templates/export/expo/splash.png';
import logToCloud from '../logToCloud';
import project from '@cdo/apps/code-studio/initApp/project';
import {GAME_WIDTH, GAME_HEIGHT} from './constants';
import {EXPO_SESSION_SECRET} from '../constants';

const CONTROLS_HEIGHT = 165;

Expand Down Expand Up @@ -242,10 +243,10 @@ export default {
return rewrittenAnimationList;
},

async exportApp(appName, code, animationOpts, suppliedExpoOpts) {
async exportApp(appName, code, animationOpts, suppliedExpoOpts, config) {
const expoOpts = suppliedExpoOpts || {};
if (expoOpts.mode === 'expoPublish') {
return await this.publishToExpo(appName, code, animationOpts);
return await this.publishToExpo(appName, code, animationOpts, config);
}
return this.exportAppToZip(
appName,
Expand Down Expand Up @@ -289,7 +290,25 @@ export default {
return exportExpoPackagedFilesEjs({entries});
},

async publishToExpo(appName, code, animationOpts) {
async generateExpoApk(snackId, config) {
const session = new SnackSession({
sessionId: `${getEnvironmentPrefix()}-${project.getCurrentId()}`,
name: `project-${project.getCurrentId()}`,
sdkVersion: '31.0.0',
snackId,
user: {
sessionSecret: config.expoSession || EXPO_SESSION_SECRET
}
});

const appJson = session.generateAppJson();

const artifactUrl = await session.getApkUrlAsync(appJson);

return artifactUrl;
},

async publishToExpo(appName, code, animationOpts, config) {
const {origin} = window.location;
const gamelabApiPath =
getEnvironmentPrefix() === 'cdo-development'
Expand Down Expand Up @@ -338,8 +357,11 @@ export default {
const session = new SnackSession({
sessionId: `${getEnvironmentPrefix()}-${project.getCurrentId()}`,
files,
name: project.getCurrentName(),
sdkVersion: '31.0.0'
name: `project-${project.getCurrentId()}`,
sdkVersion: '31.0.0',
user: {
sessionSecret: config.expoSession || EXPO_SESSION_SECRET
}
});

// Important that index.html comes first:
Expand Down Expand Up @@ -397,9 +419,13 @@ export default {

await session.sendCodeAsync(files);
const saveResult = await session.saveAsync();
const expoURL = `exp://expo.io/@snack/${saveResult.id}`;
const expoUri = `exp://expo.io/${saveResult.id}`;
const expoSnackId = saveResult.id;

return expoURL;
return {
expoUri,
expoSnackId
};
},

generateAppAssetsAndJSON(params) {
Expand Down
7 changes: 6 additions & 1 deletion apps/src/gamelab/GameLab.js
Expand Up @@ -420,6 +420,10 @@ GameLab.prototype.init = function(config) {
* @param {Object} expoOpts
*/
GameLab.prototype.exportApp = async function(expoOpts) {
const {mode, expoSnackId} = expoOpts || {};
if (mode === 'expoGenerateApk') {
return Exporter.generateExpoApk(expoSnackId, this.studioApp_.config);
}
await this.whenAnimationsAreReady();
return this.exportAppWithAnimations(
getStore().getState().animationList,
Expand All @@ -446,7 +450,8 @@ GameLab.prototype.exportAppWithAnimations = function(animationList, expoOpts) {
allAnimationsSingleFrame,
pauseAnimationsByDefault
},
expoOpts
expoOpts,
this.studioApp_.config
);
};

Expand Down

0 comments on commit 22d555c

Please sign in to comment.