var ChatMediaHandler = {}; /** * Image Upload **/ // 写真アップロード $("#imageInputButton").on("click", function () { $("#imageInputTag").click(); }); $("#imageInputTag").on("change", function () { $("#image-form").submit(); // reset the value of form $("#imageInputTag").val(""); }); $("#image-form").on("submit", function (e) { e.preventDefault(); const imageInputTag = $("#imageInputTag"); const file = imageInputTag.prop("files")[0]; if (file) { $(".overlay").addClass("active undismissable"); $(".loader").addClass("active"); Common.showLoadingIndicator(); let fd = new FormData($(this)[0]); //画像の大きさが500pixelより大きかったら、thumbnailを生成 ChatMediaHandler.createThumbnailAndUpload( file, function (resizeFile, thumbnailCreated) { if (resizeFile && thumbnailCreated) { //ただ、画像の大きさが500pixel以下の場合はthumbnailは生成されない fd.append("thumb", resizeFile); } // イメージをアップロード ChatMediaHandler.uploadImage(fd); } ); } }); /** * Video Upload **/ // 動画アップロード $("#videoUploadButton").on("click", function () { $("#videoInputTag").click(); }); $("#videoInputTag").on("change", function () { $("#video-form").submit(); // reset the value of form $("#videoInputTag").val(""); }); $("#video-form").on("submit", function (e) { e.preventDefault(); const videoInputTag = $("#videoInputTag"); const file = videoInputTag.prop("files")[0]; if (file) { $(".overlay").addClass("active undismissable"); $(".loader").addClass("active"); Common.showLoadingIndicator(); var fd = new FormData($(this)[0]); if (!file.type.includes("image")) { // video 保存 // ChatMediaHandler.createVideoThumbnailAndUpload(file, function(resizeFile, thumbnailCreated) { // if(resizeFile && thumbnailCreated) { // //ただ、画像の大きさが500pixel以下の場合はthumbnailは生成されない // fd.append('thumb', resizeFile) // } // ChatMediaHandler.uploadImage(fd); // }) ChatMediaHandler.uploadImage(fd); return; } } }); // this method call from android only for now ChatMediaHandler.videoEncodeFail = function () { alert(getLocalizedString("error_send_video")); Common.dismissLoadingIndicator(); }; // this method call from android only for now ChatMediaHandler.videoEncodeEnd = function (encodedUri) { var fileName = encodedUri.split("/")[encodedUri.split("/").length - 1]; var fileURL = "file:" + encodedUri; var xhr = new XMLHttpRequest(); xhr.open("GET", fileURL); xhr.responseType = "blob"; xhr.addEventListener("load", function () { var formData = new FormData(); formData.append("image", xhr.response, fileName); formData.append("sid", currentUserInfo.sid); formData.append("roomId", roomInfo.roomID); jQuery .ajax({ async: true, url: serverInfo.cmsURL + "/chatapi/file/upload", type: "post", data: formData, contentType: false, processData: false, error: function () { alert(getLocalizedString("error_send_video")); Common.dismissLoadingIndicator(); }, }) .done(function (res) { if (deviceInfo.isAndroid()) { android.removeEncodedVideo(encodedUri); } var imgPath = serverInfo.cmsURL + "/chatapi/file/getImage?fileName=" + res.fileName + "&roomId=" + roomInfo.roomID; var imageName = new String(res.fileName); // uploadFileの判断 var extension = imageName .substr(imageName.lastIndexOf(".") + 1) .toLowerCase(); if (res.thumbnailPath && res.thumbnailPath.length > 0) { imgPath = serverInfo.cmsURL + "/chatapi/file/getImage?fileName=" + res.thumbImageFileName + "&roomId=" + roomInfo.roomID; } let downloadPath = serverInfo.cmsURL + "/chatapi/file/download?fileName=" + imageName + "&roomId=" + roomInfo.roomID; var videoSrc = serverInfo.cmsURL + "/chatapi/file/getImage?fileName=" + res.fileName + "&roomId=" + roomInfo.roomID; const totalDiv = $("<div/>", { id: "attachedImages" }); const videoTag = $("<video/>", { controls: "true", width: "auto", style: "max-width:100%", poster: "./img/bg_movie.jpg", }); const source = $("<source/>", { src: videoSrc }); const downloadIcon = $("<a/>", { href: downloadPath, class: "fa fa-download", download: res.fileName, }); videoTag.append(source); totalDiv.append(videoTag); totalDiv.append(downloadIcon); let text = totalDiv.prop("outerHTML"); let encodedText; try { encodedText = encodeURIComponent(text); } catch (e) { encodedText = text; } const sendData = encodedText; CHAT_SOCKET.emitCreateVideo(sendData); $(".overlay").removeClass("active undismissable"); $(".loader").removeClass("active"); Common.dismissLoadingIndicator(); }); }); xhr.send(); }; // Video のサムネイルファイル生成する ChatMediaHandler.createVideoThumbnailAndUpload = function ( sourceImage, callback ) { var fileReader = new FileReader(); fileReader.onload = function () { var blob = new Blob([fileReader.result], { type: sourceImage.type }); var url = URL.createObjectURL(blob); var video = document.createElement("video"); var timeupdate = function () { if (snapImage()) { video.removeEventListener("timeupdate", timeupdate); video.pause(); } }; video.addEventListener("loadeddata", function () { if (snapImage()) { video.removeEventListener("timeupdate", timeupdate); } }); var snapImage = function () { var canvas = document.createElement("canvas"); canvas.width = video.videoWidth; canvas.height = video.videoHeight; canvas .getContext("2d") .drawImage(video, 0, 0, canvas.width, canvas.height); fetch(canvas.toDataURL("image/jpeg")) .then(function (res) { return res.arrayBuffer(); }) .then(function (buf) { // 回転された画像をFormDataに保存 const newFile = new File([buf], sourceImage.name, { type: "image/jpeg", }); callback(newFile, true); // ajax End }) .catch((error) => { // fetch Error catch Block if (error) { console.error(error); } }); return true; }; video.addEventListener("timeupdate", timeupdate); video.preload = "metadata"; video.src = url; // Load video in Safari / IE11 video.muted = true; video.playsInline = true; video.pause(); }; fileReader.readAsArrayBuffer(sourceImage); }; // Ajaxでイメージをアップロードする ChatMediaHandler.uploadImage = function (formData) { formData.append("roomId", roomInfo.roomID); formData.append("sid", currentUserInfo.sid); jQuery .ajax({ async: true, url: serverInfo.cmsURL + "/chatapi/file/upload", type: "post", data: formData, contentType: false, processData: false, error: function () { alert("読み込み失敗"); Common.dismissLoadingIndicator(); }, }) .done(function (res) { var imgPath = serverInfo.cmsURL + "/chatapi/file/getImage?fileName=" + res.fileName + "&roomId=" + roomInfo.roomID; var imageName = res.fileName; // uploadFileの判断 var extension = imageName .substr(imageName.lastIndexOf(".") + 1) .toLowerCase(); // 画像の処理 if ( res.fileType == "jpeg" || res.fileType == "jpg" || res.fileType == "png" ) { if (res.thumbnailPath && res.thumbnailPath.length > 0) { imgPath = serverInfo.cmsURL + "/chatapi/file/getImage?fileName=" + res.thumbImageFileName + "&roomId=" + roomInfo.roomID; imageName = res.thumbImageFileName; } let downloadPath = serverInfo.cmsURL + "/chatapi/file/download?fileName=" + imageName + "&roomId=" + roomInfo.roomID; // アップロードが終了した後ローディング画面から離れてメッセージをメッセージを転送する const lightbox = $("<a/>", { "data-lightbox": "attachedImages", "data-title": imageName, }); const image = $("<img/>", { src: imgPath, width: "auto", style: "max-width:100%", "data-toggle": "modal", onclick: "imageModal(this);", }); const downloadIcon = $("<a/>", { href: downloadPath, class: "fa fa-download", download: res.fileName, }); lightbox.append(image); lightbox.append(downloadIcon); let text = lightbox.prop("outerHTML"); let encodedText; try { encodedText = encodeURIComponent(text); } catch (e) { encodedText = text; } const sendData = encodedText; CHAT_SOCKET.emitCreateImage(sendData); } else { // 動画の処理 if (res.thumbnailPath && res.thumbnailPath.length > 0) { imgPath = serverInfo.cmsURL + "/chatapi/file/getImage?fileName=" + res.thumbImageFileName + "&roomId=" + roomInfo.roomID; } let downloadPath = serverInfo.cmsURL + "/chatapi/file/download?fileName=" + imageName + "&roomId=" + roomInfo.roomID; var videoSrc = serverInfo.cmsURL + "/chatapi/file/getImage?fileName=" + res.fileName + "&roomId=" + roomInfo.roomID; const totalDiv = $("<div/>", { id: "attachedImages" }); const videoTag = $("<video/>", { controls: "true", width: "auto", style: "max-width:100%", poster: "./img/bg_movie.jpg", }); const source = $("<source/>", { src: videoSrc }); const downloadIcon = $("<a/>", { href: downloadPath, class: "fa fa-download", download: res.fileName, }); videoTag.append(source); totalDiv.append(videoTag); totalDiv.append(downloadIcon); let text = totalDiv.prop("outerHTML"); let encodedText; try { encodedText = encodeURIComponent(text); } catch (e) { encodedText = text; } const sendData = encodedText; CHAT_SOCKET.emitCreateVideo(sendData); } $(".overlay").removeClass("active undismissable"); $(".loader").removeClass("active"); Common.dismissLoadingIndicator(); }); }; // Thumbnailのファイルを生成する。 ChatMediaHandler.createThumbnailAndUpload = function (sourceImage, callback) { const fileReader = new FileReader(); const img = new Image(); fileReader.onloadend = function () { img.src = fileReader.result; }; img.onload = function () { const elem = document.createElement("canvas"); var rate; var width = img.width; var height = img.height; if (img.width <= 500 && img.height <= 500) { callback(undefined, false); return; } if (img.width > img.height) { rate = 500 / img.width; } else { rate = 500 / img.height; } elem.width = width * rate; elem.height = height * rate; const ctx = elem.getContext("2d"); ctx.drawImage( img, 0, 0, img.width, img.height, 0, 0, elem.width, elem.height ); // ctx.drawImage(img, 0, 0, width, height); fetch(elem.toDataURL("image/jpeg")) .then(function (res) { return res.arrayBuffer(); }) .then(function (buf) { const newFile = new File([buf], sourceImage.name, { type: "image/jpeg", }); callback(newFile, true); }) .catch((error) => { // fetch Error catch Block if (error) { console.error(error); } }); }; fileReader.readAsDataURL(sourceImage); };