Last active
October 13, 2019 14:07
-
-
Save GitHub30/544ff0c90d2112148f980936552d3b20 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ==UserScript== | |
// @name Upload photos with Zip | |
// @version 1 | |
// @match https://www.amazon.co.jp/clouddrive* | |
// @require https://raw.githubusercontent.com/vuejs/vue/v2.6.10/dist/vue.min.js | |
// @require https://momentjs.com/downloads/moment.min.js | |
// @require https://cdn.jsdelivr.net/npm/image-capture@0.4.0/lib/imagecapture.min.js | |
// @require https://gist.github.com/GitHub30/1b13ed6687a22385a81cf98fefdd5a13/raw/42012a345cc5cb1e4f773300e99765b644a40164/async$.js | |
// @grant unsafeWindow | |
// ==/UserScript== | |
function addScript(src) { | |
var script = document.createElement("script"); | |
script.src = src; | |
document.head.appendChild(script); | |
} | |
addScript('https://stuk.github.io/jszip/dist/jszip.js') | |
unsafeWindow.eval(` | |
function dropFile(file) { | |
const dataTransfer = new DataTransfer(); | |
dataTransfer.items.add(file); | |
window.dispatchEvent(new DragEvent('drop', {dataTransfer})); | |
} | |
`) | |
const vm = new Vue({ | |
el: document.createElement('div'), | |
template: `<div style="margin-bottom: 16px;"> | |
<video title="左クリック、スペースで撮影\n右クリック、Escで終了" autoplay hidden ref="video" @click.left="takePhoto" @click.right="closeCamera" @keydown.space.prevent="takePhoto"/> | |
<button @click="openCamera">カメラ起動</button> | |
<button @click="upload" :disabled="!images.length">Zip圧縮してアップロード</button> | |
<div> | |
<a v-for="(image, i) in images" :href="image.src" target="_blank" :title="image.title" style="position: relative;"> | |
<img :src="image.src" :alt="image.title" width="512px"> | |
<button @click.prevent="removeImage(i)" style="position: absolute;bottom: 0;right: 0;padding: 8px;font-size: 24px;color: #fff;font-weight: bold;-webkit-text-stroke: 1px #000;line-height: 1;">削除</button> | |
</a> | |
</div> | |
</div>`, | |
data: { | |
images: [] | |
}, | |
mounted() { | |
document.addEventListener('keydown', e => { | |
// Ctrl + Shift + C | |
if (e.key === 'C' && e.shiftKey && e.ctrlKey && !e.altKey && !e.metaKey) { | |
if(this.$refs.video.hidden) { | |
this.openCamera(); | |
} else { | |
this.closeCamera(); | |
} | |
e.preventDefault(); | |
} | |
}); | |
}, | |
methods: { | |
async openCamera() { | |
this.$refs.video.hidden = false; | |
this.$refs.video.mozRequestFullScreen(); | |
const constraints = {video: {height: 720, facingMode: "environment", advanced: [{height: 1080}]}}; | |
const stream = await navigator.mediaDevices.getUserMedia(constraints); | |
this.$refs.video.srcObject = stream; | |
this.$refs.video.focus(); | |
this.$refs.video.onmozfullscreenchange = () => { | |
if (!document.mozFullScreenElement) { | |
this.closeCamera(); | |
} | |
}; | |
}, | |
closeCamera() { | |
if(document.mozFullScreenElement) { | |
document.mozCancelFullScreen(); | |
} | |
this.$refs.video.hidden = true; | |
if (this.$refs.video.srcObject) { | |
this.$refs.video.srcObject.getTracks().forEach(track => track.stop()); | |
this.$refs.video.srcObject = null; | |
} | |
}, | |
async takePhoto() { | |
const track = this.$refs.video.srcObject.getVideoTracks()[0]; | |
const captureDevice = new ImageCapture(track); | |
const blob = await captureDevice.takePhoto(); | |
this.images.push({title: moment().toISOString(true) + '.png', src: URL.createObjectURL(blob), blob}); | |
}, | |
async upload() { | |
unsafeWindow.zip = new unsafeWindow.JSZip(); | |
for(const image of this.images) { | |
// https://github.com/Stuk/jszip/issues/369 | |
unsafeWindow.zip.file(image.title, image.blob); | |
} | |
const zipBlob = await unsafeWindow.eval('zip.generateAsync({type: "blob"})'); | |
unsafeWindow.dropFile(new File([zipBlob], moment().toISOString(true) + ".zip", zipBlob)); | |
}, | |
removeImage(i) { | |
this.images.splice(i, 1); | |
} | |
} | |
}); | |
async$('.body-content').then(body => body.insertBefore(vm.$el, body.firstElementChild)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment