implement File Handler API
This commit is contained in:
parent
6748cc0cb4
commit
7936f123c2
5 changed files with 227 additions and 3 deletions
|
@ -13,6 +13,7 @@ Developed based on [Snapdrop](https://github.com/RobinLinus/snapdrop)
|
|||
* You will always discover devices on your local network. Paired devices are shown additionally.
|
||||
* Paired devices outside your local network that are behind a NAT are connected automatically via [Open Relay: Free WebRTC TURN Server](https://www.metered.ca/tools/openrelay/)
|
||||
|
||||
[//]: # (Todo: add File Handler API Doku)
|
||||
|
||||
### Other changes
|
||||
* node-only implementation (thanks [@Bellisario](https://github.com/Bellisario))
|
||||
|
|
|
@ -37,5 +37,203 @@
|
|||
"text": "text",
|
||||
"url": "url"
|
||||
}
|
||||
},
|
||||
"file_handlers": [
|
||||
{
|
||||
"action": "/?file_handler",
|
||||
"name": "All Files",
|
||||
"accept": {
|
||||
"application/cpl+xml": [".cpl"],
|
||||
"application/gpx+xml": [".gpx"],
|
||||
"application/gzip": [".gz"],
|
||||
"application/java-archive": [".jar", ".war", ".ear"],
|
||||
"application/java-vm": [".class"],
|
||||
"application/javascript": [".js", ".mjs"],
|
||||
"application/json": [".json", ".map"],
|
||||
"application/manifest+json": [".webmanifest"],
|
||||
"application/msword": [".doc", ".dot", ".wiz"],
|
||||
"application/octet-stream": [".bin", ".dms", ".lrf", ".mar", ".so", ".dist", ".distz", ".pkg", ".bpk", ".dump", ".elc", ".deploy", ".exe", ".dll", ".deb", ".dmg", ".iso", ".img", ".msi", ".msp", ".msm", ".buffer"],
|
||||
"application/oda": [".oda"],
|
||||
"application/oxps": [".oxps"],
|
||||
"application/pdf": [".pdf"],
|
||||
"application/pgp-signature": [".asc", ".sig"],
|
||||
"application/pics-rules": [".prf"],
|
||||
"application/pkcs7-mime": [".p7c"],
|
||||
"application/pkix-cert": [".cer"],
|
||||
"application/postscript": [".ai", ".eps", ".ps"],
|
||||
"application/rtf": [".rtf"],
|
||||
"application/vnd.android.package-archive": [".apk"],
|
||||
"application/vnd.apple.mpegurl": [".m3u", ".m3u8"],
|
||||
"application/vnd.apple.pkpass": [".pkpass"],
|
||||
"application/vnd.google-earth.kml+xml": [".kml"],
|
||||
"application/vnd.google-earth.kmz": [".kmz"],
|
||||
"application/vnd.ms-cab-compressed": [".cab"],
|
||||
"application/vnd.ms-excel": [".xls", ".xlm", ".xla", ".xlc", ".xlt", ".xlw"],
|
||||
"application/vnd.ms-outlook": [".msg"],
|
||||
"application/vnd.ms-powerpoint": [".ppt", ".pot", ".ppa", ".pps", ".pwz"],
|
||||
"application/vnd.ms-project": [".mpp", ".mpt"],
|
||||
"application/vnd.ms-xpsdocument": [".xps"],
|
||||
"application/vnd.oasis.opendocument.database": [".odb"],
|
||||
"application/vnd.oasis.opendocument.spreadsheet": [".ods"],
|
||||
"application/vnd.oasis.opendocument.text": [".odt"],
|
||||
"application/vnd.openstreetmap.data+xml": [".osm"],
|
||||
"application/vnd.openxmlformats-officedocument.presentationml.presentation": [".pptx"],
|
||||
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [".xlsx"],
|
||||
"application/vnd.openxmlformats-officedocument.wordprocessingml.document": [".docx"],
|
||||
"application/vnd.tcpdump.pcap": [".pcap", ".cap", ".dmp"],
|
||||
"application/vnd.wordperfect": [".wpd"],
|
||||
"application/wasm": [".wasm"],
|
||||
"application/x-7z-compressed": [".7z"],
|
||||
"application/x-apple-diskimage": [".dmg"],
|
||||
"application/x-bcpio": [".bcpio"],
|
||||
"application/x-bittorrent": [".torrent"],
|
||||
"application/x-cbr": [".cbr", ".cba", ".cbt", ".cbz", ".cb7"],
|
||||
"application/x-cdlink": [".vcd"],
|
||||
"application/x-chrome-extension": [".crx"],
|
||||
"application/x-cpio": [".cpio"],
|
||||
"application/x-csh": [".csh"],
|
||||
"application/x-debian-package": [".deb", ".udeb"],
|
||||
"application/x-dvi": [".dvi"],
|
||||
"application/x-freearc": [".arc"],
|
||||
"application/x-gtar": [".gtar"],
|
||||
"application/x-hdf": [".hdf"],
|
||||
"application/x-hdf5": [".h5"],
|
||||
"application/x-httpd-php": [".php"],
|
||||
"application/x-iso9660-image": [".iso"],
|
||||
"application/x-iwork-keynote-sffkey": [".key"],
|
||||
"application/x-iwork-numbers-sffnumbers": [".numbers"],
|
||||
"application/x-iwork-pages-sffpages": [".pages"],
|
||||
"application/x-latex": [".latex"],
|
||||
"application/x-makeself": [".run"],
|
||||
"application/x-mif": [".mif"],
|
||||
"application/x-ms-shortcut": [".lnk"],
|
||||
"application/x-msaccess": [".mdb"],
|
||||
"application/x-msdownload": [".exe", ".dll", ".com", ".bat", ".msi"],
|
||||
"application/x-mspublisher": [".pub"],
|
||||
"application/x-netcdf": [".cdf", ".nc"],
|
||||
"application/x-perl": [".pl", ".pm"],
|
||||
"application/x-pilot": [".prc", ".pdb"],
|
||||
"application/x-pkcs12": [".p12", ".pfx"],
|
||||
"application/x-pn-realaudio": [".ram"],
|
||||
"application/x-python-code": [".pyc", ".pyo"],
|
||||
"application/x-rar-compressed": [".rar"],
|
||||
"application/x-redhat-package-manager": [".rpm"],
|
||||
"application/x-sh": [".sh"],
|
||||
"application/x-shar": [".shar"],
|
||||
"application/x-shockwave-flash": [".swf"],
|
||||
"application/x-sql": [".sql"],
|
||||
"application/x-subrip": [".srt"],
|
||||
"application/x-sv4cpio": [".sv4cpio"],
|
||||
"application/x-sv4crc": [".sv4crc"],
|
||||
"application/x-tads": [".gam"],
|
||||
"application/x-tar": [".tar"],
|
||||
"application/x-tcl": [".tcl"],
|
||||
"application/x-tex": [".tex"],
|
||||
"application/x-troff": [".roff", ".t", ".tr"],
|
||||
"application/x-troff-man": [".man"],
|
||||
"application/x-troff-me": [".me"],
|
||||
"application/x-troff-ms": [".ms"],
|
||||
"application/x-ustar": [".ustar"],
|
||||
"application/x-wais-source": [".src"],
|
||||
"application/x-xpinstall": [".xpi"],
|
||||
"application/xhtml+xml": [".xhtml", ".xht"],
|
||||
"application/xml": [".xsl", ".rdf", ".wsdl", ".xpdl"],
|
||||
"application/zip": [".zip"],
|
||||
"audio/3gpp": [".3gp", ".3gpp"],
|
||||
"audio/3gpp2": [".3g2", ".3gpp2"],
|
||||
"audio/aac": [".aac", ".adts", ".loas", ".ass"],
|
||||
"audio/basic": [".au", ".snd"],
|
||||
"audio/midi": [".mid", ".midi", ".kar", ".rmi"],
|
||||
"audio/mpeg": [".mpga", ".mp2", ".mp2a", ".mp3", ".m2a", ".m3a"],
|
||||
"audio/ogg": [".oga", ".ogg", ".spx", ".opus"],
|
||||
"audio/opus": [".opus"],
|
||||
"audio/x-aiff": [".aif", ".aifc", ".aiff"],
|
||||
"audio/x-flac": [".flac"],
|
||||
"audio/x-m4a": [".m4a"],
|
||||
"audio/x-mpegurl": [".m3u"],
|
||||
"audio/x-ms-wma": [".wma"],
|
||||
"audio/x-pn-realaudio": [".ra"],
|
||||
"audio/x-wav": [".wav"],
|
||||
"font/otf": [".otf"],
|
||||
"font/ttf": [".ttf"],
|
||||
"font/woff": [".woff"],
|
||||
"font/woff2": [".woff2"],
|
||||
"image/emf": [".emf"],
|
||||
"image/gif": [".gif"],
|
||||
"image/heic": [".heic"],
|
||||
"image/heif": [".heif"],
|
||||
"image/ief": [".ief"],
|
||||
"image/jpeg": [".jpeg", ".jpg"],
|
||||
"image/jpg": [".jpg"],
|
||||
"image/pict": [".pict", ".pct", ".pic"],
|
||||
"image/png": [".png"],
|
||||
"image/svg+xml": [".svg", ".svgz"],
|
||||
"image/tiff": [".tif", ".tiff"],
|
||||
"image/vnd.adobe.photoshop": [".psd"],
|
||||
"image/vnd.djvu": [".djvu", ".djv"],
|
||||
"image/vnd.dwg": [".dwg"],
|
||||
"image/vnd.dxf": [".dxf"],
|
||||
"image/vnd.microsoft.icon": [".ico"],
|
||||
"image/vnd.ms-dds": [".dds"],
|
||||
"image/x-3ds": [".3ds"],
|
||||
"image/x-cmu-raster": [".ras"],
|
||||
"image/x-icon": [".ico"],
|
||||
"image/x-ms-bmp": [".bmp"],
|
||||
"image/x-portable-anymap": [".pnm"],
|
||||
"image/x-portable-bitmap": [".pbm"],
|
||||
"image/x-portable-graymap": [".pgm"],
|
||||
"image/x-portable-pixmap": [".ppm"],
|
||||
"image/x-rgb": [".rgb"],
|
||||
"image/x-tga": [".tga"],
|
||||
"image/x-xbitmap": [".xbm"],
|
||||
"image/x-xpixmap": [".xpm"],
|
||||
"image/x-xwindowdump": [".xwd"],
|
||||
"message/rfc822": [".eml", ".mht", ".mhtml", ".nws"],
|
||||
"model/obj": [".obj"],
|
||||
"model/stl": [".stl"],
|
||||
"model/vnd.collada+xml": [".dae"],
|
||||
"text/calendar": [".ics", ".ifb"],
|
||||
"text/css": [".css"],
|
||||
"text/csv": [".csv"],
|
||||
"text/html": [".html", ".htm", ".shtml"],
|
||||
"text/markdown": [".markdown", ".md"],
|
||||
"text/plain": [".txt", ".text", ".conf", ".def", ".list", ".log", ".in", ".ini"],
|
||||
"text/richtext": [".rtx"],
|
||||
"text/rtf": [".rtf"],
|
||||
"text/tab-separated-values": [".tsv"],
|
||||
"text/x-c": [".c", ".cc", ".cxx", ".cpp", ".h", ".hh", ".dic"],
|
||||
"text/x-java-source": [".java"],
|
||||
"text/x-lua": [".lua"],
|
||||
"text/x-python": [".py"],
|
||||
"text/x-setext": [".etx"],
|
||||
"text/x-sgml": [".sgm", ".sgml"],
|
||||
"text/x-vcard": [".vcf"],
|
||||
"text/xml": [".xml"],
|
||||
"text/xul": [".xul"],
|
||||
"text/yaml": [".yaml", ".yml"],
|
||||
"video/3gpp": [".3gp", ".3gpp"],
|
||||
"video/mp2t": [".ts"],
|
||||
"video/mp4": [".mp4", ".mp4v", ".mpg4"],
|
||||
"video/mpeg": [".mpeg", ".m1v", ".mpa", ".mpe", ".mpg"],
|
||||
"video/quicktime": [".mov", ".qt"],
|
||||
"video/webm": [".webm"],
|
||||
"video/x-flv": [".flv"],
|
||||
"video/x-m4v": [".m4v"],
|
||||
"video/x-ms-asf": [".asf", ".asx"],
|
||||
"video/x-ms-vob": [".vob"],
|
||||
"video/x-ms-wmv": [".wmv"],
|
||||
"video/x-msvideo": [".avi"],
|
||||
"video/x-sgi-movie": [".*"]
|
||||
},
|
||||
"icons": [
|
||||
{
|
||||
"src": "/images/android-chrome-192x192.png",
|
||||
"sizes": "192x192"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"launch_handler": {
|
||||
"client_mode": "focus-existing"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -263,6 +263,7 @@ class Peer {
|
|||
this._fileHeaderRequested = header;
|
||||
let bytesCompleted = 0;
|
||||
|
||||
zipper.createNewZipWriter();
|
||||
for (let i=0; i<files.length; i++) {
|
||||
const entry = await zipper.addFile(files[i], {
|
||||
onprogress: (progress, total) => {
|
||||
|
|
|
@ -535,6 +535,7 @@ class ReceiveFileDialog extends ReceiveDialog {
|
|||
description = `${files[0].name} and ${files.length-1} other ${files.length>2 ? "files" : "file"}`;
|
||||
size = this._formatFileSize(completeSize);
|
||||
|
||||
zipper.createNewZipWriter();
|
||||
for (let i=0; i<files.length; i++) {
|
||||
await zipper.addFile(files[i]);
|
||||
}
|
||||
|
@ -1151,6 +1152,28 @@ class WebShareTargetUI {
|
|||
}
|
||||
}
|
||||
|
||||
class WebFileHandlersUI {
|
||||
constructor() {
|
||||
if ("launchQueue" in window) {
|
||||
launchQueue.setConsumer(async launchParams => {
|
||||
console.log("Launched with: ", launchParams);
|
||||
if (!launchParams.files.length)
|
||||
return;
|
||||
let files = [];
|
||||
|
||||
for (let i=0; i<launchParams.files.length; i++) {
|
||||
if (i !== 0 && await launchParams.files[i].isSameEntry(launchParams.files[i-1])) continue;
|
||||
const fileHandle = launchParams.files[i];
|
||||
const file = await fileHandle.getFile();
|
||||
files.push(file);
|
||||
}
|
||||
Events.fire('activate-paste-mode', {files: files, text: ""})
|
||||
launchParams = null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class NoSleepUI {
|
||||
constructor() {
|
||||
NoSleepUI._nosleep = new NoSleep();
|
||||
|
@ -1363,6 +1386,7 @@ class PairDrop {
|
|||
const notifications = new Notifications();
|
||||
const networkStatusUI = new NetworkStatusUI();
|
||||
const webShareTargetUI = new WebShareTargetUI();
|
||||
const webFileHandlersUI = new WebFileHandlersUI();
|
||||
const noSleepUI = new NoSleepUI();
|
||||
});
|
||||
}
|
||||
|
|
|
@ -41,10 +41,10 @@ const zipper = (() => {
|
|||
|
||||
let zipWriter;
|
||||
return {
|
||||
createNewZipWriter() {
|
||||
zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"), { bufferedWrite: true, level: 0 });
|
||||
},
|
||||
addFile(file, options) {
|
||||
if (!zipWriter) {
|
||||
zipWriter = new zip.ZipWriter(new zip.BlobWriter("application/zip"), { bufferedWrite: true, level: 0 });
|
||||
}
|
||||
return zipWriter.add(file.name, new zip.BlobReader(file), options);
|
||||
},
|
||||
async getBlobURL() {
|
||||
|
|
Loading…
Reference in a new issue