Merge pull request #939 from mozilla/more-android-ui

Add ui for setting max downloads, max time, and password.
This commit is contained in:
Danny Coates 2018-09-25 12:15:49 -07:00 committed by GitHub
commit 3f098f340e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 135 additions and 5 deletions

View File

@ -14,6 +14,8 @@ window.LIMITS = {
}; };
window.DEFAULTS = { window.DEFAULTS = {
DOWNLOAD_COUNTS: [1, 2, 3, 4, 5, 20, 50, 100, 200],
EXPIRE_TIMES_SECONDS: [300, 3600, 86400, 604800],
EXPIRE_SECONDS: 3600 EXPIRE_SECONDS: 3600
}; };
@ -24,7 +26,11 @@ app.use(require('./stores/state').default);
app.use(require('../app/fileManager').default); app.use(require('../app/fileManager').default);
app.use(require('./stores/intents').default); app.use(require('./stores/intents').default);
app.route('/', require('./pages/home').default); app.route('/', require('./pages/home').default);
app.route('/options', require('./pages/options').default);
app.route('/upload', require('./pages/upload').default); app.route('/upload', require('./pages/upload').default);
app.route('/share/:id', require('./pages/share').default); app.route('/share/:id', require('./pages/share').default);
app.route('/preferences', require('./pages/preferences').default); app.route('/preferences', require('./pages/preferences').default);
app.route('/error', require('./pages/error').default);
//app.route('/debugging', require('./pages/debugging').default);
// add /api/filelist
app.mount('body'); app.mount('body');

View File

@ -22,13 +22,14 @@
</configuration> </configuration>
</facet> </facet>
<facet type="kotlin-language" name="Kotlin"> <facet type="kotlin-language" name="Kotlin">
<configuration version="3" platform="JVM 1.6" useProjectSettings="false"> <configuration version="3" platform="JVM 1.8" useProjectSettings="false">
<compilerSettings /> <compilerSettings />
<compilerArguments> <compilerArguments>
<option name="destination" value="$MODULE_DIR$/build/tmp/kotlin-classes/debug" /> <option name="destination" value="$MODULE_DIR$/build/tmp/kotlin-classes/debug" />
<option name="noStdlib" value="true" /> <option name="noStdlib" value="true" />
<option name="noReflect" value="true" /> <option name="noReflect" value="true" />
<option name="moduleName" value="app_debug" /> <option name="moduleName" value="app_debug" />
<option name="jvmTarget" value="1.8" />
<option name="addCompilerBuiltIns" value="true" /> <option name="addCompilerBuiltIns" value="true" />
<option name="loadBuiltInsFromDependencies" value="true" /> <option name="loadBuiltInsFromDependencies" value="true" />
<option name="languageVersion" value="1.2" /> <option name="languageVersion" value="1.2" />
@ -111,6 +112,7 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" /> <sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/.DS_Store" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/build-info" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/build-info" />
@ -125,6 +127,7 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-main-apk-res" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-main-apk-res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaPrecompile" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaPrecompile" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifest-checker" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifest-checker" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/prebuild" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/prebuild" />

View File

@ -106,3 +106,19 @@ body {
#preferences { #preferences {
text-align: left; text-align: left;
} }
#hamburger {
position: fixed;
right: 2em;
top: 1em;
}
#top-banner {
position: fixed;
top: 1em;
left: 2em;
}
#options {
text-align: left;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

10
android/pages/error.js Normal file
View File

@ -0,0 +1,10 @@
const html = require('choo/html');
export default function error(_state, _emit) {
return html`<body>
<div id="white">
<h1>Error</h1>
<p>Sorry, an error occurred.</p>
</div>
</body>`;
}

View File

@ -5,6 +5,7 @@ export default function mainPage(state, emit) {
event.preventDefault(); event.preventDefault();
emit('pushState', '/preferences'); emit('pushState', '/preferences');
} }
function uploadFile(event) { function uploadFile(event) {
event.preventDefault(); event.preventDefault();
const target = event.target; const target = event.target;
@ -13,15 +14,16 @@ export default function mainPage(state, emit) {
return; return;
} }
emit('pushState', '/upload'); emit('pushState', '/options');
emit('addFiles', { files: [file] }); emit('addFiles', { files: [file] });
emit('upload', {});
} }
return html`<body> return html`<body>
<div id="white"> <div id="white">
<div id="centering"> <div id="centering">
<a href="#" onclick=${clickPreferences}> <img id="top-banner" src=${state.getAsset('top-banner.png')} />
preferenes <a id="hamburger" href="#" onclick=${clickPreferences}>
<img src=${state.getAsset('preferences.png')} />
</a> </a>
<img src=${state.getAsset('encrypted-envelope.png')} /> <img src=${state.getAsset('encrypted-envelope.png')} />
<h4>Private, Encrypted File Sharing</h4> <h4>Private, Encrypted File Sharing</h4>

92
android/pages/options.js Normal file
View File

@ -0,0 +1,92 @@
/* globals DEFAULTS */
const html = require('choo/html');
export default function options(state, emit) {
function clickCancel(event) {
event.preventDefault();
emit('pushState', '/');
}
async function submitForm(event) {
event.preventDefault();
if (this.addPassword.checked) {
if (this.password.value !== this.confirmPassword.value) {
state.passwordDoesNotMatchError = true;
emit('render');
return;
} else {
state.passwordDoesNotMatchError = false;
}
}
state.timeLimit = parseInt(event.target.maxTime);
emit('upload', {
type: 'click',
dlimit: parseInt(event.target.numDownloads.value),
password: event.target.password.value
});
emit('pushState', '/upload');
}
function addPasswordChange(event) {
const pw = document.getElementById('password-section');
if (event.target.checked) {
pw.style.display = 'block';
} else {
pw.style.display = 'none';
}
}
const passwordDoesNotMatchDisplayStyle = state.passwordDoesNotMatchError
? 'display: block'
: 'display: none';
const passwordChecked = state.passwordDoesNotMatchError ? true : false;
return html`<body>
<div id="white">
<div id="options">
<a onclick=${clickCancel} class="cancel" href="#">
cancel
</a>
<h5>Selected files</h5>
<ul>
<li>file</li>
</ul>
<div id="options-controls">
<form onsubmit=${submitForm}>
<div id="expires-after-section">
<h5>Expires after</h5>
<select name="numDownloads">
${DEFAULTS.DOWNLOAD_COUNTS.map(i => {
return html`<option value="${i}">${i} download${
i > 1 ? 's' : ''
}</option>`;
})}
</select>
or
<select name="maxTime">
<option value="300">5 minutes</option>
<option value="3600">1 hour</option>
<option value="86400" selected="true">24 hours</option>
<option value="604800">7 days</option>
</select>
</div>
<div id="set-password-section">
<input onchange=${addPasswordChange} name="addPassword" autocomplete="off" type="checkbox" checked=${passwordChecked}>
<label for="addPassword">Protect with password</label>
<div id="password-section" style=${passwordDoesNotMatchDisplayStyle}>
<div style=${passwordDoesNotMatchDisplayStyle}>
Passwords must match.
</div>
<h5>Password:</h5>
<input name="password" type="password" />
<h5>Confirm password:</h5>
<input name="confirmPassword" type="password" />
</div>
</div>
<button>Send</button>
</form>
</div>
</div>
</div>
</body>`;
}

View File

@ -44,6 +44,7 @@ module.exports = function(app, devServer) {
app.get(`/download/:id${ID_REGEX}`, android); app.get(`/download/:id${ID_REGEX}`, android);
app.get('/completed', android); app.get('/completed', android);
app.get('/preferences', android); app.get('/preferences', android);
app.get('/options', android);
app.get('/api/fxa/oauth', android); app.get('/api/fxa/oauth', android);
} }
routes(app); routes(app);