mirror of
https://github.com/mozilla/send.git
synced 2026-04-18 03:00:05 -04:00
Implement bundling for the android app and loading the bundle; pass data from the android input button and the android intents to fileManager
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -6,3 +6,7 @@ dist
|
||||
.nyc_output
|
||||
.tox
|
||||
.pytest_cache
|
||||
android/app/src/main/assets/vendor.js
|
||||
android/app/src/main/assets/runtime.js
|
||||
android/app/src/main/assets/android.js
|
||||
|
||||
|
||||
110
android/android.js
Normal file
110
android/android.js
Normal file
@@ -0,0 +1,110 @@
|
||||
/* global window, document, fetch */
|
||||
|
||||
/*
|
||||
fileManager emits:
|
||||
render
|
||||
DOMTitleChange
|
||||
pushState 'path'
|
||||
|
||||
fileManager listens:
|
||||
DOMContentLoaded
|
||||
navigate
|
||||
render
|
||||
changeLimit
|
||||
delete
|
||||
cancel
|
||||
upload
|
||||
password
|
||||
getMetadata
|
||||
copy
|
||||
|
||||
fileManager on('upload', ...) emits
|
||||
sender.on('progress', updateProgress);
|
||||
emitter.emit('DOMTitleChange', percent(state.transfer.progressRatio));
|
||||
sender.on('encrypting', render);
|
||||
|
||||
emitter.emit('pushState', `/share/${ownedFile.id}`);
|
||||
|
||||
*/
|
||||
const MAXFILESIZE = 1024 * 1024 * 1024 * 2;
|
||||
|
||||
const EventEmitter = require('events');
|
||||
const emitter = new EventEmitter();
|
||||
|
||||
const state = {
|
||||
storage: {
|
||||
files: [],
|
||||
remove: function(fileId) {
|
||||
console.log('REMOVE FILEID', fileId);
|
||||
},
|
||||
writeFile: function(file) {
|
||||
console.log('WRITEFILE', file);
|
||||
},
|
||||
addFile: function(file) {
|
||||
console.log('ADDFILE', file);
|
||||
},
|
||||
totalUploads: 0
|
||||
},
|
||||
transfer: null,
|
||||
uploading: false,
|
||||
settingPassword: false,
|
||||
passwordSetError: null,
|
||||
route: '/'
|
||||
};
|
||||
|
||||
emitter.on('render', function() {
|
||||
const node = document.createElement('div');
|
||||
node.textContent = 'onrender';
|
||||
document.body.appendChild(node);
|
||||
});
|
||||
|
||||
/*
|
||||
<input id="file-upload"
|
||||
class="inputFile"
|
||||
type="file"
|
||||
name="fileUploaded"
|
||||
onfocus=${onfocus}
|
||||
onblur=${onblur}
|
||||
onchange=${upload} />
|
||||
*/
|
||||
|
||||
const fileManager = require('../app/fileManager').default;
|
||||
try {
|
||||
fileManager(state, emitter);
|
||||
} catch (e) {
|
||||
console.error('error' + e);
|
||||
console.error(e);
|
||||
}
|
||||
|
||||
const fileInput = document.createElement('input');
|
||||
fileInput.className = 'inputFile';
|
||||
fileInput.type = 'file';
|
||||
fileInput.name = 'fileUploaded';
|
||||
fileInput.onchange = function upload(event) {
|
||||
event.preventDefault();
|
||||
const target = event.target;
|
||||
const file = target.files[0];
|
||||
if (file.size === 0) {
|
||||
return;
|
||||
}
|
||||
if (file.size > MAXFILESIZE) {
|
||||
console.log('file too big (no bigger than ' + MAXFILESIZE + ')');
|
||||
return;
|
||||
}
|
||||
|
||||
emitter.emit('upload', { file, type: 'click' });
|
||||
};
|
||||
|
||||
document.body.appendChild(fileInput);
|
||||
|
||||
window.addEventListener(
|
||||
'message',
|
||||
event => {
|
||||
fetch(event.data)
|
||||
.then(res => res.blob())
|
||||
.then(file => {
|
||||
emitter.emit('upload', { file, type: 'share' });
|
||||
});
|
||||
},
|
||||
false
|
||||
);
|
||||
@@ -32,3 +32,12 @@ dependencies {
|
||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
||||
implementation 'com.github.delight-im:Android-AdvancedWebView:v3.0.0'
|
||||
}
|
||||
|
||||
task generateAndLinkBundle(type: Exec, description: 'Generate the android.js bundle and link it into the assets directory') {
|
||||
commandLine 'node'
|
||||
args '../generateAndLinkBundle.js'
|
||||
}
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
compileTask -> compileTask.dependsOn generateAndLinkBundle
|
||||
}
|
||||
|
||||
@@ -2,187 +2,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<meta property="og:title" content="Firefox Send"/>
|
||||
<meta name="twitter:title" content="Firefox Send"/>
|
||||
<meta name="description" content="Encrypt and send files with a link that automatically expires to ensure your important documents don’t stay online forever."/>
|
||||
<meta property="og:description" content="Encrypt and send files with a link that automatically expires to ensure your important documents don’t stay online forever."/>
|
||||
<meta name="twitter:description" content="Encrypt and send files with a link that automatically expires to ensure your important documents don’t stay online forever."/>
|
||||
<meta name="twitter:card" content="summary"/>
|
||||
<meta property="og:image" content="https://send.firefox.com/send-fb.19274ff0.jpg"/>
|
||||
<meta name="twitter:image" content="https://send.firefox.com/send-twitter.7d5e4200.jpg"/>
|
||||
<meta property="og:url" content="https://send.firefox.com"/>
|
||||
<base href="https://send.firefox.com/" />
|
||||
|
||||
<title>Firefox Send</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="/style.11428181.css" />
|
||||
|
||||
<!-- generic favicons -->
|
||||
<link rel="icon" href="/favicon-32.4efdbe5a.png" sizes="32x32">
|
||||
<link rel="icon" href="/favicon-96.a2ce7c6e.png" sizes="96x96">
|
||||
<link rel="icon" href="/favicon-128.58447464.png" sizes="128x128">
|
||||
<link rel="icon" href="/favicon-228.069d14fe.png" sizes="228x228">
|
||||
|
||||
<!-- Android -->
|
||||
<link rel="shortcut icon" href="/favicon-196.55cef95d.png" sizes="196x196">
|
||||
|
||||
<!-- iOS -->
|
||||
<link rel="apple-touch-icon" href="/favicon-120.a48a3fc0.png" sizes="120x120">
|
||||
<link rel="apple-touch-icon" href="/favicon-152.10d8b941.png" sizes="152x152">
|
||||
<link rel="apple-touch-icon" href="/favicon-180.373787f8.png" sizes="180x180">
|
||||
|
||||
<!-- Windows 8 IE 10-->
|
||||
<meta name="msapplication-TileColor" content="#FFFFFF">
|
||||
<meta name="msapplication-TileImage" content="/favicon-144.909cb064.png">
|
||||
|
||||
<!-- Windows 8.1 + IE11 and above -->
|
||||
<meta name="msapplication-config" content="/browserconfig.xml"/>
|
||||
|
||||
|
||||
|
||||
<script defer src="/jsconfig.js"></script>
|
||||
<script defer src="/runtime.44a28e7e.js"></script>
|
||||
<script defer src="/vendor.ec5b5b1d.js"></script>
|
||||
<script defer src="/public/locales/en-US/send.6b4f8354.js"></script>
|
||||
<script defer src="/cryptofill.1315ac9e.js"></script>
|
||||
<script defer src="/app.baa60a46.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
|
||||
<header class="header">
|
||||
<div class="logo">
|
||||
<a class="logo__link" href="/">
|
||||
<img
|
||||
src="/send_logo.5fcfdf0e.svg"
|
||||
alt="Send"/>
|
||||
<h1 class="logo__title">Send</h1>
|
||||
</a>
|
||||
<div class="logo__subtitle">
|
||||
<a class="logo__subtitle-link" href="https://testpilot.firefox.com">Firefox Test Pilot</a>
|
||||
<div>web experiment</div>
|
||||
</div>
|
||||
</div>
|
||||
<a href="https://qsurvey.mozilla.com/s3/txp-firefox-send?ver=2.5.4&browser=unknown"
|
||||
rel="noreferrer noopener"
|
||||
class="feedback"
|
||||
target="_blank">Feedback</a>
|
||||
</header>
|
||||
<main class="main">
|
||||
<noscript>
|
||||
<div class="noscript">
|
||||
<h2>Firefox Send requires JavaScript</h2>
|
||||
<p>
|
||||
<a class="link" href="https://github.com/mozilla/send/blob/master/docs/faq.md#why-does-firefox-send-require-javascript">
|
||||
Why does Firefox Send require JavaScript?
|
||||
</a>
|
||||
</p>
|
||||
<p>Please enable JavaScript and try again.</p>
|
||||
</div>
|
||||
</noscript>
|
||||
|
||||
<div id="page-one" class="">
|
||||
<div class="title">Private, Encrypted File Sharing</div>
|
||||
<div class="description">
|
||||
<div>Send files through a safe, private, and encrypted link that automatically expires to ensure your stuff does not remain online forever.</div>
|
||||
<a
|
||||
href="https://testpilot.firefox.com/experiments/send"
|
||||
class="link">
|
||||
Learn more
|
||||
</a>
|
||||
</div>
|
||||
<div class="uploadArea"
|
||||
|
||||
>
|
||||
<img
|
||||
src="/upload.8e2a8bdb.svg"
|
||||
title="Upload"/>
|
||||
<div class="uploadArea__msg">
|
||||
Drop your file here to start uploading
|
||||
</div>
|
||||
<span class="uploadArea__sizeMsg">
|
||||
For the most reliable operation, it’s best to keep your file under 1GB
|
||||
</span>
|
||||
<input id="file-upload"
|
||||
class="inputFile"
|
||||
type="file"
|
||||
name="fileUploaded"
|
||||
|
||||
|
||||
/>
|
||||
<label for="file-upload"
|
||||
class="btn btn--file"
|
||||
title="Select a file to upload">
|
||||
Select a file to upload
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</main>
|
||||
<footer class="footer">
|
||||
<div class="legalSection">
|
||||
<a
|
||||
href="https://www.mozilla.org"
|
||||
class="legalSection__link"
|
||||
role="presentation">
|
||||
<img
|
||||
class="legalSection__mozLogo"
|
||||
src="/mozilla-logo.2538e7d3.svg"
|
||||
alt="mozilla"/>
|
||||
</a>
|
||||
<a
|
||||
href="https://www.mozilla.org/about/legal"
|
||||
class="legalSection__link">
|
||||
Legal
|
||||
</a>
|
||||
<a
|
||||
href="https://testpilot.firefox.com/about"
|
||||
class="legalSection__link">
|
||||
About Test Pilot
|
||||
</a>
|
||||
<a
|
||||
href="/legal"
|
||||
class="legalSection__link">Privacy</a>
|
||||
<a
|
||||
href="/legal"
|
||||
class="legalSection__link">Terms</a>
|
||||
<a
|
||||
href="https://www.mozilla.org/privacy/websites/#cookies"
|
||||
class="legalSection__link">
|
||||
Cookies
|
||||
</a>
|
||||
<a
|
||||
href="https://www.mozilla.org/about/legal/report-infringement/"
|
||||
class="legalSection__link">
|
||||
Report IP Infringement
|
||||
</a>
|
||||
</div>
|
||||
<div class="socialSection">
|
||||
<a
|
||||
href="https://github.com/mozilla/send"
|
||||
class="socialSection__link"
|
||||
role="presentation">
|
||||
<img
|
||||
class="socialSection__icon"
|
||||
src="/github-icon.74dc24f7.svg"
|
||||
alt="github"/>
|
||||
</a>
|
||||
<a
|
||||
href="https://twitter.com/FxTestPilot"
|
||||
class="socialSection__link"
|
||||
role="presentation">
|
||||
<img
|
||||
class="socialSection__icon"
|
||||
src="/twitter-icon.018c7f54.svg"
|
||||
alt="twitter"/>
|
||||
</a>
|
||||
</div>
|
||||
</footer>
|
||||
</body>
|
||||
<script src="runtime.js"></script>
|
||||
<script src="vendor.js"></script>
|
||||
<script src="android.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en-US">
|
||||
<head>
|
||||
|
||||
<title>Firefox Send</title>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div id="output">output</div>
|
||||
<script>
|
||||
window.addEventListener("message", (event) => {
|
||||
fetch(event.data).then(res => res.text()).then(txt => {
|
||||
document.getElementById('output').textContent = "GOT MESSAGE" + txt;
|
||||
});
|
||||
}, false);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -12,14 +12,16 @@ import android.webkit.WebView
|
||||
import android.webkit.WebMessage
|
||||
import android.util.Log
|
||||
import android.util.Base64
|
||||
import android.provider.MediaStore
|
||||
import android.R.attr.data
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
import android.webkit.ConsoleMessage
|
||||
import android.webkit.WebChromeClient
|
||||
|
||||
internal class LoggingWebChromeClient : WebChromeClient() {
|
||||
override fun onConsoleMessage(cm: ConsoleMessage): Boolean {
|
||||
Log.w("CONTENT", String.format("%s @ %d: %s",
|
||||
cm.message(), cm.lineNumber(), cm.sourceId()))
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
class MainActivity : AppCompatActivity(), AdvancedWebView.Listener {
|
||||
private var mWebView: AdvancedWebView? = null
|
||||
@@ -31,6 +33,7 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener {
|
||||
|
||||
mWebView = findViewById<WebView>(R.id.webview) as AdvancedWebView
|
||||
mWebView!!.setListener(this, this)
|
||||
mWebView!!.setWebChromeClient(LoggingWebChromeClient())
|
||||
|
||||
val webSettings = mWebView!!.getSettings()
|
||||
webSettings.setJavaScriptEnabled(true)
|
||||
@@ -51,11 +54,12 @@ class MainActivity : AppCompatActivity(), AdvancedWebView.Listener {
|
||||
// TODO Currently this causes a Permission Denied error
|
||||
// val stream = contentResolver.openInputStream(imageUri)
|
||||
}
|
||||
mWebView!!.loadUrl("file:///android_asset/intent-target.html")
|
||||
// mWebView!!.loadUrl("file:///android_asset/intent-target.html")
|
||||
|
||||
} else {
|
||||
mWebView!!.loadUrl("file:///android_asset/index.html")
|
||||
// } else {
|
||||
// mWebView!!.loadUrl("file:///android_asset/index.html")
|
||||
}
|
||||
mWebView!!.loadUrl("file:///android_asset/index.html")
|
||||
|
||||
}
|
||||
|
||||
|
||||
25
android/generateAndLinkBundle.js
Normal file
25
android/generateAndLinkBundle.js
Normal file
@@ -0,0 +1,25 @@
|
||||
const child_process = require('child_process');
|
||||
const fs = require('fs');
|
||||
|
||||
child_process.execSync('npm run build');
|
||||
|
||||
const json_string = fs.readFileSync('../../dist/manifest.json');
|
||||
const manifest = JSON.parse(json_string);
|
||||
|
||||
const android_filename = manifest['android.js'];
|
||||
fs.writeFileSync(
|
||||
'src/main/assets/android.js',
|
||||
fs.readFileSync(`../../dist/${android_filename}`)
|
||||
);
|
||||
|
||||
const vendor_filename = manifest['vendor.js'];
|
||||
fs.writeFileSync(
|
||||
'src/main/assets/vendor.js',
|
||||
fs.readFileSync(`../../dist/${vendor_filename}`)
|
||||
);
|
||||
|
||||
const runtime_filename = manifest['runtime.js'];
|
||||
fs.writeFileSync(
|
||||
'src/main/assets/runtime.js',
|
||||
fs.readFileSync(`../../dist/${runtime_filename}`)
|
||||
);
|
||||
@@ -127,7 +127,7 @@ export function uploadFile(
|
||||
onprogress([event.loaded, event.total]);
|
||||
}
|
||||
});
|
||||
xhr.open('post', '/api/upload', true);
|
||||
xhr.open('post', 'https://send.firefox.com/api/upload', true);
|
||||
xhr.setRequestHeader('X-File-Metadata', arrayToB64(new Uint8Array(metadata)));
|
||||
xhr.setRequestHeader('Authorization', `send-v1 ${verifierB64}`);
|
||||
xhr.send(blob);
|
||||
@@ -163,7 +163,7 @@ function download(id, keychain, onprogress, canceller) {
|
||||
}
|
||||
});
|
||||
const auth = await keychain.authHeader();
|
||||
xhr.open('get', `/api/download/${id}`);
|
||||
xhr.open('get', `https://send.firefox.com/api/download/${id}`);
|
||||
xhr.setRequestHeader('Authorization', auth);
|
||||
xhr.responseType = 'blob';
|
||||
xhr.send();
|
||||
|
||||
@@ -17,7 +17,8 @@ const entry = {
|
||||
// because they are not explicitly referenced by app
|
||||
vendor: ['babel-polyfill', 'fluent'],
|
||||
app: ['./app/main.js'],
|
||||
style: ['./app/main.css']
|
||||
style: ['./app/main.css'],
|
||||
android: ['./android/android.js']
|
||||
};
|
||||
|
||||
if (IS_DEV) {
|
||||
|
||||
Reference in New Issue
Block a user