implement File Handler API

This commit is contained in:
schlagmichdoch 2023-01-18 15:45:53 +01:00
parent 6748cc0cb4
commit 7936f123c2
5 changed files with 227 additions and 3 deletions

View file

@ -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))

View file

@ -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"
}
}

View file

@ -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) => {

View file

@ -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();
});
}

View file

@ -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() {