Skip to content

Instantly share code, notes, and snippets.

@GitHub30
Last active October 13, 2019 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GitHub30/544ff0c90d2112148f980936552d3b20 to your computer and use it in GitHub Desktop.
Save GitHub30/544ff0c90d2112148f980936552d3b20 to your computer and use it in GitHub Desktop.
// ==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