thedesk/app/js/post/img.js

418 lines
11 KiB
JavaScript
Raw Normal View History

2018-01-28 23:22:43 +11:00
//ドラッグ・アンド・ドロップからアップロードまで。uiのimg.jsとは異なります。
2019-11-09 00:52:54 +11:00
var obj = $('body')
var system
2018-01-28 23:22:43 +11:00
//ドラッグスタート
2019-11-09 00:52:54 +11:00
obj.on('dragstart', function(e) {
system = 'locked'
})
2018-01-28 23:22:43 +11:00
//何もなくファイルが通過
2019-11-09 00:52:54 +11:00
obj.on('dragend', function(e) {
system = ''
})
2018-01-28 23:22:43 +11:00
//ドラッグファイルが画面上に
2019-11-09 00:52:54 +11:00
obj.on('dragenter', function(e) {
if (system != 'locked') {
$('#drag').css('display', 'flex')
2018-01-28 23:22:43 +11:00
}
2019-11-09 00:52:54 +11:00
})
$('body').on('dragover', function(e) {
e.stopPropagation()
e.preventDefault()
})
2018-01-28 23:22:43 +11:00
//ドロップした
2019-11-09 00:52:54 +11:00
$('body').on('drop', function(e) {
if (system != 'locked') {
$('#drag').css('display', 'none')
e.preventDefault()
var files = e.originalEvent.dataTransfer.files
pimg(files)
2018-01-28 23:22:43 +11:00
}
2019-11-09 00:52:54 +11:00
})
2018-01-28 23:22:43 +11:00
//何もなくファイルが通過
2019-11-09 00:52:54 +11:00
$('#drag').on('dragleave', function(e) {
$('#drag').css('display', 'none')
})
2018-01-28 23:22:43 +11:00
//複数アップ
function pimg(files) {
2019-11-09 00:52:54 +11:00
console.table(files)
2018-01-28 23:22:43 +11:00
for (i = 0; i < files.length; i++) {
2019-11-09 00:52:54 +11:00
var dot = files[i].path.match(/\.(.+)$/)[1]
if (dot == 'bmp' || dot == 'BMP') {
postMessage(['bmpImage', [files[i].path, i]], '*')
todo(lang.lang_progress)
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
handleFileUpload(files[i], obj, i)
2018-02-19 04:41:25 +11:00
}
2018-01-28 23:22:43 +11:00
}
}
//ドラッグ・アンド・ドロップを終了
function closedrop() {
2019-11-09 00:52:54 +11:00
$('#drag').css('display', 'none')
2018-01-28 23:22:43 +11:00
}
2018-03-18 02:00:53 +11:00
//ファイル選択
function fileselect() {
2019-11-09 00:52:54 +11:00
postMessage(['sendSinmpleIpc', 'file-select'], '*')
2018-03-18 02:00:53 +11:00
}
2018-01-28 23:22:43 +11:00
2018-02-19 04:41:25 +11:00
//ファイル読み込み
2018-04-10 02:22:08 +10:00
function handleFileUpload(files, obj, no) {
2019-11-09 00:52:54 +11:00
var fr = new FileReader()
2019-10-12 02:18:43 +11:00
fr.onload = function(evt) {
2019-11-09 00:52:54 +11:00
var b64 = evt.target.result
2019-12-14 03:54:40 +11:00
var resize = localStorage.getItem('uploadCrop') * 1
if (resize > 0) {
var element = new Image()
var width
element.onload = function() {
var width = element.naturalWidth
var height = element.naturalHeight
if (width > resize || height > resize) {
postMessage(['resizeImage', [b64, resize]], '*')
return false
} else {
$('#b64-box').val(b64)
var ret = media(b64, files['type'], no)
}
}
element.src = b64
return false
}
2019-11-09 00:52:54 +11:00
$('#b64-box').val(b64)
var ret = media(b64, files['type'], no)
}
fr.readAsDataURL(files)
$('#mec').append(files['name'] + '/')
2018-01-28 23:22:43 +11:00
}
//ファイルアップロード
2020-04-07 18:41:57 +10:00
async function media(b64, type, no, stamped) {
2019-12-14 03:54:40 +11:00
var acct_id = $('#post-acct-sel').val()
var domain = localStorage.getItem('domain_' + acct_id)
var user = localStorage.getItem('user_' + acct_id)
if ($('#stamp').hasClass('stamp-avail') && !stamped) {
postMessage(['stampImage', [b64, user + '@' + domain]], '*')
return false
}
2019-11-09 00:52:54 +11:00
var l = 4
var c = 'abcdefghijklmnopqrstuvwxyz0123456789'
var cl = c.length
var r = ''
2019-05-19 17:39:30 +10:00
for (var i = 0; i < l; i++) {
2019-11-09 00:52:54 +11:00
r += c[Math.floor(Math.random() * cl)]
2018-04-10 02:22:08 +10:00
}
2019-11-09 00:52:54 +11:00
if ($('#media').val()) {
$('#media').val($('#media').val() + ',' + 'tmp_' + r)
2018-04-10 02:22:08 +10:00
} else {
2019-11-09 00:52:54 +11:00
$('#media').val('tmp_' + r)
2018-04-10 02:22:08 +10:00
}
2019-11-09 00:52:54 +11:00
$('.toot-btn-group').prop('disabled', true)
$('#post-acct-sel').prop('disabled', true)
localStorage.setItem('image', 'busy')
todo('Image Upload...')
var media = toBlob(b64, type)
var fd = new FormData()
fd.append('file', media)
var at = localStorage.getItem('acct_' + acct_id + '_at')
var httpreq = new XMLHttpRequest()
if (localStorage.getItem('mode_' + domain) == 'misskey') {
var start = 'https://' + domain + '/api/drive/files/create'
httpreq.open('POST', start, true)
httpreq.upload.addEventListener('progress', progshow, false)
httpreq.responseType = 'json'
if ($('#nsfw').hasClass('nsfw-avail')) {
var nsfw = true
2018-07-30 21:03:49 +10:00
} else {
2019-11-09 00:52:54 +11:00
var nsfw = false
2018-07-30 21:03:49 +10:00
}
2019-11-09 00:52:54 +11:00
var previewer = 'url'
fd.append('i', at)
httpreq.send(fd)
2019-05-19 17:39:30 +10:00
} else {
2019-11-09 00:52:54 +11:00
var previewer = 'preview_url'
2020-04-07 18:41:57 +10:00
//v2/media
try {
var id = await v2MediaUpload(domain, at, fd)
var mediav = $('#media').val()
var regExp = new RegExp('tmp_' + r, 'g')
mediav = mediav.replace(regExp, id)
$('#media').val(mediav)
var html = `<img src="../../img/picture.svg" class="preview-img pointer unknown" data-media="${id}" oncontextmenu="deleteImage('${id}')" onclick="altImage('${acct_id}','${id}')" title="${lang.lang_postimg_delete}">`
$('#preview').append(html)
todc()
if (localStorage.getItem('nsfw_' + acct_id)) {
$('#nsfw').addClass('yellow-text')
$('#nsfw').html('visibility')
$('#nsfw').addClass('nsfw-avail')
}
$('.toot-btn-group').prop('disabled', false)
$('select').formSelect()
$('#mec').text(lang.lang_there)
M.toast({ html: '<span>' + lang.lang_postimg_sync + '</span><button class="btn-flat toast-action" onclick="syncDetail()">Click</button>', displayLength: 3000 })
$('#imgup').text('')
$('#imgsel').show()
localStorage.removeItem('image')
} catch {
var start = 'https://' + domain + '/api/v1/media'
httpreq.open('POST', start, true)
httpreq.upload.addEventListener('progress', progshow, false)
httpreq.responseType = 'json'
httpreq.setRequestHeader('Authorization', 'Bearer ' + at)
httpreq.send(fd)
}
2018-07-30 21:03:49 +10:00
}
2019-10-12 02:18:43 +11:00
httpreq.onreadystatechange = function() {
2019-03-08 05:19:26 +11:00
if (httpreq.readyState === 4) {
2019-11-09 00:52:54 +11:00
var json = httpreq.response
2019-11-04 03:10:06 +11:00
if (this.status !== 200) {
2019-11-09 00:52:54 +11:00
setLog(start, this.status, json)
2020-01-23 02:29:49 +11:00
$('.toot-btn-group').prop('disabled', false)
$('select').formSelect()
$('#mec').text(lang.lang_there)
M.toast({ html: this.status + ':' +json, displayLength: 2000 })
$('#imgup').text('')
$('#imgsel').show()
2019-11-04 03:10:06 +11:00
}
2019-07-12 02:01:24 +10:00
if (!json.id) {
2019-11-09 00:52:54 +11:00
todc()
$('#imgup').text('')
$('.toot-btn-group').prop('disabled', false)
$('#post-acct-sel').prop('disabled', false)
$('select').formSelect()
$('#imgsel').show()
M.toast({ html: lang.lang_postimg_failupload, displayLength: 5000 })
return false
2019-07-12 02:01:24 +10:00
}
2020-04-08 15:54:25 +10:00
$('#imgup').text('')
$('.toot-btn-group').prop('disabled', false)
$('select').formSelect()
$('#imgsel').show()
2019-11-09 00:52:54 +11:00
var img = localStorage.getItem('img')
if (json.type.indexOf('image') != -1) {
2019-12-14 03:54:40 +11:00
var html = `<img src="${json[previewer]}" class="preview-img pointer" data-media="${json['id']}" oncontextmenu="deleteImage('${json['id']}')" onclick="altImage('${acct_id}','${json['id']}')" title="${lang.lang_postimg_delete}">`
2019-11-09 00:52:54 +11:00
$('#preview').append(html)
2018-04-17 03:10:35 +10:00
} else {
2019-11-09 00:52:54 +11:00
$('#preview').append(lang.lang_postimg_previewdis)
2018-04-17 03:10:35 +10:00
}
if (!img) {
2019-11-09 00:52:54 +11:00
var img = 'no-act'
2018-04-17 03:10:35 +10:00
}
2019-11-09 00:52:54 +11:00
if (img != 'inline') {
var mediav = $('#media').val()
var regExp = new RegExp('tmp_' + r, 'g')
mediav = mediav.replace(regExp, json['id'])
$('#media').val(mediav)
2018-04-17 03:10:35 +10:00
}
2019-12-12 02:06:40 +11:00
if (img == 'url' && json['text_url']) {
2019-11-09 00:52:54 +11:00
$('#textarea').val($('#textarea').val() + ' ' + json['text_url'])
2018-04-17 03:10:35 +10:00
}
2018-02-19 04:41:25 +11:00
}
2019-11-09 00:52:54 +11:00
}
2018-01-28 23:22:43 +11:00
}
//Base64からBlobへ
function toBlob(base64, type) {
2019-11-09 00:52:54 +11:00
var bin = atob(base64.replace(/^.*,/, ''))
var buffer = new Uint8Array(bin.length)
2018-01-28 23:22:43 +11:00
for (var i = 0; i < bin.length; i++) {
2019-11-09 00:52:54 +11:00
buffer[i] = bin.charCodeAt(i)
2018-01-28 23:22:43 +11:00
}
// Blobを作成
try {
var blob = new Blob([new Uint8Array(buffer)], {
type: type
2019-11-09 00:52:54 +11:00
})
2018-01-28 23:22:43 +11:00
} catch (e) {
2019-11-09 00:52:54 +11:00
return false
2018-01-28 23:22:43 +11:00
}
2019-11-09 00:52:54 +11:00
return blob
2018-04-17 03:10:35 +10:00
}
//画像を貼り付けたら…
2019-11-09 00:52:54 +11:00
var element = document.querySelector('#textarea')
element.addEventListener('paste', function(e) {
2019-05-19 17:39:30 +10:00
if (!e.clipboardData || !e.clipboardData.items) {
2019-11-09 00:52:54 +11:00
return true
2019-05-19 17:39:30 +10:00
}
// DataTransferItemList に画像が含まれいない場合は終了する
2019-11-09 00:52:54 +11:00
var imageItems = [...e.clipboardData.items].filter(i => i.type.startsWith('image'))
2019-05-19 17:39:30 +10:00
if (imageItems.length == 0) {
2019-11-09 00:52:54 +11:00
console.warn('it is not image')
return true
2019-05-19 17:39:30 +10:00
}
2018-04-17 03:10:35 +10:00
2019-05-19 17:39:30 +10:00
// ファイルとして得る
// DataTransferItem の kind は file なので getAsString ではなく getAsFile を呼ぶ
2019-11-09 00:52:54 +11:00
var imageFile = imageItems[0].getAsFile()
var imageType = imageItems[0].type
2018-04-17 03:10:35 +10:00
2019-05-19 17:39:30 +10:00
// FileReaderで読み込む
2019-11-09 00:52:54 +11:00
var fr = new FileReader()
2019-10-12 02:18:43 +11:00
fr.onload = function(e) {
2019-05-19 17:39:30 +10:00
// onload内ではe.target.resultにbase64が入っているのであとは煮るなり焼くなり
2019-11-09 00:52:54 +11:00
var base64 = e.target.result
var mediav = $('#media').val()
2019-05-19 17:39:30 +10:00
if (mediav) {
2019-11-09 00:52:54 +11:00
var i = mediav.split(',').length
2018-04-17 03:10:35 +10:00
}
2019-05-19 17:39:30 +10:00
// DataTransferItem の type に mime tipes があるのでそれを使う
2019-11-09 00:52:54 +11:00
media(base64, imageType, i)
}
fr.readAsDataURL(imageFile)
2018-04-17 03:10:35 +10:00
2019-05-19 17:39:30 +10:00
// 画像以外がペーストされたときのために、元に戻しておく
2019-11-09 00:52:54 +11:00
})
2019-05-19 17:39:30 +10:00
function deleteImage(key) {
2019-06-22 02:06:32 +10:00
Swal.fire({
title: lang.lang_postimg_delete,
2019-11-09 00:52:54 +11:00
type: 'warning',
2019-06-22 02:06:32 +10:00
showCancelButton: true,
2019-11-09 00:52:54 +11:00
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
2019-06-22 02:06:32 +10:00
confirmButtonText: lang.lang_yesno,
cancelButtonText: lang.lang_no
2019-10-12 02:18:43 +11:00
}).then(result => {
2019-06-22 02:06:32 +10:00
if (result.value) {
2019-11-09 00:52:54 +11:00
var media = $('#media').val()
var arr = media.split(',')
2019-06-22 02:06:32 +10:00
for (var i = 0; i < media.length; i++) {
if (arr[i] == key) {
2019-11-09 00:52:54 +11:00
arr.splice(i, 1)
break
2019-06-22 02:06:32 +10:00
}
}
2019-11-09 00:52:54 +11:00
$('#media').val(arr.join(','))
$('#preview [data-media=' + key + ']').remove()
2019-03-21 07:49:59 +11:00
}
2019-11-09 00:52:54 +11:00
})
2019-10-12 02:18:43 +11:00
}
function altImage(acct_id, id) {
2019-11-09 00:52:54 +11:00
var domain = localStorage.getItem('domain_' + acct_id)
var at = localStorage.getItem('acct_' + acct_id + '_at')
var start = 'https://' + domain + '/api/v1/media/' + id
2020-04-07 18:41:57 +10:00
if($('[data-media=' + id + ']').hasClass('unknown')) {
fetch(start, {
method: 'GET',
headers: {
'content-type': 'application/json',
Authorization: 'Bearer ' + at
}
})
.then(function(response) {
if (!response.ok) {
response.text().then(function(text) {
setLog(response.url, response.status, text)
2019-10-12 02:18:43 +11:00
})
2020-04-07 18:41:57 +10:00
}
return response.json()
})
.catch(function(error) {
todo(error)
setLog(start, 'JSON', error)
console.error(error)
})
.then(function(json) {
console.log(json)
$('[data-media=' + id + ']').removeClass('unknown')
if(json.preview_url) {
$('[data-media=' + id + ']').attr('src', json.preview_url)
}
})
} else {
Swal.fire({
title: lang.lang_postimg_desc,
text: lang.lang_postimg_leadContext,
input: 'text',
inputAttributes: {
autocapitalize: 'off'
},
showCancelButton: true,
confirmButtonText: 'Post',
showLoaderOnConfirm: true,
preConfirm: data => {
return fetch(start, {
method: 'PUT',
headers: {
'content-type': 'application/json',
Authorization: 'Bearer ' + at
},
body: JSON.stringify({
description: data
})
2019-10-12 02:18:43 +11:00
})
2020-04-07 18:41:57 +10:00
.then(function(response) {
if (!response.ok) {
response.text().then(function(text) {
setLog(response.url, response.status, text)
})
}
return response.json()
})
.catch(function(error) {
todo(error)
setLog(start, 'JSON', error)
console.error(error)
})
.then(function(json) {
console.log(json)
$('[data-media=' + id + ']').attr('title', data)
})
},
allowOutsideClick: () => !Swal.isLoading()
}).then(result => {
if (result.value) {
Swal.fire({
title: 'Complete'
2019-11-09 00:52:54 +11:00
})
2020-04-07 18:41:57 +10:00
}
})
}
2019-10-12 02:18:43 +11:00
}
2019-12-14 03:54:40 +11:00
function stamp() {
if ($('#stamp').hasClass('stamp-avail')) {
$('#stamp').html('Off')
$('#stamp').removeClass('stamp-avail')
} else {
$('#stamp').html('On')
$('#stamp').addClass('stamp-avail')
}
2020-04-07 18:41:57 +10:00
}
//v2/media対応
async function v2MediaUpload(domain, at, fd) {
var start = 'https://' + domain + '/api/v2/media'
let promise = await fetch(start, {
method: 'POST',
headers: {
Authorization:
'Bearer ' + at
},
body: fd
})
var json = await promise.json()
if(json.id) {
return json.id
} else {
return false
}
}
function alertProcessUnfinished() {
Swal.fire({
title: lang.lang_post_unfinishedMedia,
type: 'error',
showCancelButton: true,
confirmButtonText: lang.lang_post_retry,
cancelButtonText: lang.lang_no
}).then(result => {
if (result.value) {
post()
}
})
}
function syncDetail() {
Swal.fire({
title: lang.lang_post_syncDetail,
text: lang.lang_post_syncDetailText,
type: 'info'
})
2019-12-14 03:54:40 +11:00
}