diff --git a/android/android.js b/android/android.js index b0ca7557..68a677f9 100644 --- a/android/android.js +++ b/android/android.js @@ -1,6 +1,6 @@ /* global window, document, fetch */ -const MAXFILESIZE = 1024 * 1024 * 1024 * 2; +window.MAXFILESIZE = 1024 * 1024 * 1024 * 2; const EventEmitter = require('events'); const emitter = new EventEmitter(); @@ -32,41 +32,58 @@ function dom(tagName, attributes, children = []) { function uploadComplete(file) { document.body.innerHTML = ''; - const input = dom('input', { id: 'url', value: file.url }); - const copy = dom( - 'button', - { - id: 'copy-button', - className: 'button', - onclick: () => { - input.select(); - document.execCommand('copy'); - input.blur(); - copy.textContent = 'Copied!'; - setTimeout(function() { - copy.textContent = 'Copy to clipboard'; - }, 2000); - } - }, - 'Copy to clipboard' - ); + const input = dom('input', { id: 'url', value: file.url, readonly: 'true' }); + const copyText = dom('span', {}, 'Copy link'); + const copyImage = dom('img', { id: 'copy-image', src: 'copy-link.png' }); const node = dom( 'div', - { id: 'striped' }, - dom('div', { id: 'white' }, [ + { id: 'white' }, + dom('div', { className: 'card' }, [ + dom('div', {}, 'The card contents will be here.'), + dom('div', {}, [ + 'Expires after: ', + dom('span', { className: 'expiresAfter' }, 'exp') + ]), input, - copy, dom( - 'button', - { id: 'send-another', className: 'button', onclick: render }, - 'Send another file' - ) + 'div', + { + id: 'copy-link', + onclick: e => { + e.preventDefault(); + input.select(); + document.execCommand('copy'); + input.selectionEnd = input.selectionStart; + copyText.textContent = 'Copied!'; + setTimeout(function() { + copyText.textContent = 'Copy link'; + }, 2000); + } + }, + [copyImage, copyText] + ), + dom('img', { + id: 'send-another', + src: 'cloud-upload.png', + onclick: () => { + render(); + document.getElementById('label').click(); + } + }) ]) ); document.body.appendChild(node); } const state = { + translate: (...toTranslate) => { + return toTranslate.map(o => JSON.stringify(o)).toString(); + }, + raven: { + captureException: e => { + console.error('ERROR ' + e + ' ' + e.stack); + } + }, storage: { files: [], remove: function(fileId) { @@ -92,21 +109,30 @@ function upload(event) { if (file.size === 0) { return; } - if (file.size > MAXFILESIZE) { - console.log('file too big (no bigger than ' + MAXFILESIZE + ')'); - return; - } - emitter.emit('upload', { file: file, type: 'click' }); + emitter.emit('addFiles', { files: [file] }); + emitter.emit('upload', {}); } function render() { document.body.innerHTML = ''; - const striped = dom( + const node = dom( 'div', - { id: 'striped' }, - dom('div', { id: 'white' }, [ - dom('label', { id: 'label', htmlFor: 'input' }, 'Choose file'), + { id: 'white' }, + dom('div', { id: 'centering' }, [ + dom('img', { src: 'encrypted-envelope.png' }), + dom('h4', {}, 'Private, Encrypted File Sharing'), + dom( + 'div', + {}, + 'Send files through a safe, private, and encrypted link that automatically expires to ensure your stuff does not remain online forever.' + ), + dom('div', { id: 'spacer' }), + dom( + 'label', + { id: 'label', htmlFor: 'input' }, + dom('img', { src: 'cloud-upload.png' }, []) + ), dom('input', { id: 'input', type: 'file', @@ -115,19 +141,42 @@ function render() { }) ]) ); - document.body.appendChild(striped); + document.body.appendChild(node); } emitter.on('render', function() { + if (!state.transfer || !state.transfer.progress) { + return; + } document.body.innerHTML = ''; - const percent = - (state.transfer.progress[0] / state.transfer.progress[1]) * 100; + const percent = Math.floor(state.transfer.progressRatio * 100); const node = dom( 'div', - { style: 'background-color: white; width: 100%' }, - dom('span', { - style: `display: inline-block; width: ${percent}%; background-color: blue` - }) + { id: 'white', style: 'width: 90%' }, + dom('div', { className: 'card' }, [ + dom('div', {}, `${percent}%`), + dom( + 'span', + { + style: `display: inline-block; height: 4px; border-radius: 2px; width: ${percent}%; background-color: #1b96ef; color: white` + }, + '.' + ), + dom( + 'div', + { + style: 'text-align: right', + onclick: e => { + e.preventDefault(); + if (state.uploading) { + emitter.emit('cancel'); + render(); + } + } + }, + 'CANCEL' + ) + ]) ); document.body.appendChild(node); }); @@ -150,8 +199,10 @@ window.addEventListener( fetch(event.data) .then(res => res.blob()) .then(blob => { - emitter.emit('upload', { file: blob, type: 'share' }); - }); + emitter.emit('addFiles', { files: [blob] }); + emitter.emit('upload', {}); + }) + .catch(e => console.error('ERROR ' + e + ' ' + e.stack)); }, false ); diff --git a/android/app/app.iml b/android/app/app.iml index 5f5dbac2..4554de11 100644 --- a/android/app/app.iml +++ b/android/app/app.iml @@ -43,7 +43,7 @@ @@ -150,15 +150,12 @@ - - - @@ -172,10 +169,13 @@ + + + diff --git a/android/app/build.gradle b/android/app/build.gradle index 05d1d89c..fe209ee1 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -8,7 +8,7 @@ android { compileSdkVersion 27 defaultConfig { applicationId "com.mozilla.send.sendandroid" - minSdkVersion 24 + minSdkVersion 26 targetSdkVersion 27 versionCode 1 versionName "1.0" diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 940d90eb..786540c6 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -12,6 +12,7 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> + diff --git a/android/app/src/main/assets/cloud-upload.png b/android/app/src/main/assets/cloud-upload.png new file mode 100644 index 00000000..1667ca78 Binary files /dev/null and b/android/app/src/main/assets/cloud-upload.png differ diff --git a/android/app/src/main/assets/copy-link.png b/android/app/src/main/assets/copy-link.png new file mode 100644 index 00000000..31ad553d Binary files /dev/null and b/android/app/src/main/assets/copy-link.png differ diff --git a/android/app/src/main/assets/encrypted-envelope.png b/android/app/src/main/assets/encrypted-envelope.png new file mode 100644 index 00000000..94073533 Binary files /dev/null and b/android/app/src/main/assets/encrypted-envelope.png differ diff --git a/android/app/src/main/assets/index.css b/android/app/src/main/assets/index.css index 3dd18d2d..68bcb164 100644 --- a/android/app/src/main/assets/index.css +++ b/android/app/src/main/assets/index.css @@ -1,20 +1,11 @@ -body { - background: url('background_1.jpg'); - display: flex; - flex-direction: row; - flex: auto; - justify-content: center; - align-items: center; - padding: 0 20px; - box-sizing: border-box; - position: fixed; - top: 0; - left: 0; - right: 0; - bottom: 0; +html { + height: 100vh; } -#striped { +body { + box-sizing: border-box; + margin: 0; + min-height: 100vh; background-image: repeating-linear-gradient( 45deg, white, @@ -26,32 +17,37 @@ body { #0083ff 30px, #0083ff 50px ); - height: 350px; - width: 480px; } #white { + display: flex; + flex-direction: column; + min-height: 100vh; + background-color: white; + margin: 0 10px; + padding: 10px; + text-align: center; +} + +#centering { + flex: 1; display: flex; justify-content: center; align-items: center; flex-direction: column; height: 100%; - background-color: white; - margin: 0 10px; - padding: 1px 10px 0 10px; + width: 100%; } #label { - background: #0297f8; - border: 1px solid #0297f8; - color: white; - font-size: 24px; - font-weight: 500; + position: fixed; + right: 2em; + bottom: 1em; +} + +#label img { height: 60px; - width: 200px; - display: flex; - justify-content: center; - align-items: center; + width: 60px; } #input { @@ -59,26 +55,38 @@ body { } #url { - flex: 1; - width: 100%; - height: 32px; - font-size: 24px; - margin-top: 1em; + display: none; } -.button { - flex: 1; - display: block; - background: #0297f8; - border: 1px solid #0297f8; - color: white; - font-size: 24px; - font-weight: 500; - width: 95%; - height: 32px; - margin-top: 1em; +#copy-link { + text-align: right; +} + +#copy-image { + position: relative; + top: 6px; + height: 30px; + width: 30px; +} + +.spacer { + height: 12em; } #send-another { margin-bottom: 1em; + height: 60px; + width: 60px; + position: fixed; + right: 2em; + bottom: 1em; +} + +.card { + margin: 6px; + padding: 6px; + border: 1px solid white; + border-radius: 5px; + box-shadow: 5px 5px 5px 5px #d5d5d5; + text-align: left; } diff --git a/android/build.gradle b/android/build.gradle index 7c715ccf..d0971749 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,14 +1,14 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = '1.2.50' + ext.kotlin_version = '1.2.60' repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.3' - classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'com.android.tools.build:gradle:3.1.4' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.2.60" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files