chat-media-handler.js 12.5 KB
Newer Older
1
var ChatMediaHandler = {};
Kim Peace committed
2 3

/**
4
 *    Image Upload
Kim Peace committed
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
 **/
// 写真アップロード
$("#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");
24
    Common.showLoadingIndicator();
Kim Peace committed
25
    let fd = new FormData($(this)[0]);
Kim Peace committed
26
    //画像の大きさが500pixelより大きかったら、thumbnailを生成
27
    ChatMediaHandler.createThumbnailAndUpload(
Kim Peace committed
28 29 30 31 32 33 34 35
      file,
      function (resizeFile, thumbnailCreated) {
        if (resizeFile && thumbnailCreated) {
          //ただ、画像の大きさが500pixel以下の場合はthumbnailは生成されない
          fd.append("thumb", resizeFile);
        }

        // イメージをアップロード
36
        ChatMediaHandler.uploadImage(fd);
Kim Peace committed
37 38 39 40 41 42
      }
    );
  }
});

/**
43
 *    Video Upload
Kim Peace committed
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
 **/
// 動画アップロード
$("#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");
63
    Common.showLoadingIndicator();
Kim Peace committed
64 65 66
    var fd = new FormData($(this)[0]);

    if (!file.type.includes("image")) {
67 68 69 70 71 72 73 74
      // video 保存
      // ChatMediaHandler.createVideoThumbnailAndUpload(file, function(resizeFile, thumbnailCreated) {
      //     if(resizeFile && thumbnailCreated) {
      //         //ただ、画像の大きさが500pixel以下の場合はthumbnailは生成されない
      //         fd.append('thumb', resizeFile)
      //     }
      //     ChatMediaHandler.uploadImage(fd);
      // })
75
      ChatMediaHandler.uploadImage(fd);
Kim Peace committed
76 77 78 79
      return;
    }
  }
});
Kim Peace committed
80 81

// this method call from android only for now
82
ChatMediaHandler.videoEncodeFail = function () {
Kim Peace committed
83
  alert(getLocalizedString("error_send_video"));
84
  Common.dismissLoadingIndicator();
Kim Peace committed
85 86 87
};

// this method call from android only for now
88
ChatMediaHandler.videoEncodeEnd = function (encodedUri) {
Kim Peace committed
89 90 91 92 93 94 95 96
  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);
97 98
    formData.append("sid", currentUserInfo.sid);
    formData.append("roomId", roomInfo.roomID);
Kim Peace committed
99 100 101
    jQuery
      .ajax({
        async: true,
102
        url: serverInfo.cmsURL + "/chatapi/file/upload",
Kim Peace committed
103 104 105 106 107 108
        type: "post",
        data: formData,
        contentType: false,
        processData: false,
        error: function () {
          alert(getLocalizedString("error_send_video"));
109
          Common.dismissLoadingIndicator();
Kim Peace committed
110 111 112
        },
      })
      .done(function (res) {
113
        if (deviceInfo.isAndroid()) {
Kim Peace committed
114 115 116
          android.removeEncodedVideo(encodedUri);
        }
        var imgPath =
117
          serverInfo.cmsURL +
Kim Peace committed
118 119 120
          "/chatapi/file/getImage?fileName=" +
          res.fileName +
          "&roomId=" +
121
          roomInfo.roomID;
122
        var imageName = new String(res.fileName);
Kim Peace committed
123 124

        // uploadFileの判断
onuma committed
125 126 127
        var extension = imageName
          .substr(imageName.lastIndexOf(".") + 1)
          .toLowerCase();
Kim Peace committed
128 129 130

        if (res.thumbnailPath && res.thumbnailPath.length > 0) {
          imgPath =
131
            serverInfo.cmsURL +
Kim Peace committed
132 133 134
            "/chatapi/file/getImage?fileName=" +
            res.thumbImageFileName +
            "&roomId=" +
135
            roomInfo.roomID;
Kim Peace committed
136 137
        }
        let downloadPath =
138
          serverInfo.cmsURL +
Kim Peace committed
139 140 141
          "/chatapi/file/download?fileName=" +
          imageName +
          "&roomId=" +
142
          roomInfo.roomID;
Kim Peace committed
143
        var videoSrc =
144
          serverInfo.cmsURL +
Kim Peace committed
145 146 147
          "/chatapi/file/getImage?fileName=" +
          res.fileName +
          "&roomId=" +
148
          roomInfo.roomID;
Kim Peace committed
149 150 151 152 153
        const totalDiv = $("<div/>", { id: "attachedImages" });
        const videoTag = $("<video/>", {
          controls: "true",
          width: "auto",
          style: "max-width:100%",
154
          poster: "./img/bg_movie.jpg",
Kim Peace committed
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
        });
        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;
        }
172 173
        const sendData = encodedText;
        CHAT_SOCKET.emitCreateVideo(sendData);
Kim Peace committed
174 175 176

        $(".overlay").removeClass("active undismissable");
        $(".loader").removeClass("active");
177
        Common.dismissLoadingIndicator();
Kim Peace committed
178 179 180 181
      });
  });
  xhr.send();
};
182 183

// Video のサムネイルファイル生成する
Kim Peace committed
184 185 186 187
ChatMediaHandler.createVideoThumbnailAndUpload = function (
  sourceImage,
  callback
) {
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
  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) {
Kim Peace committed
228
            console.error(error);
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
          }
        });
      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でイメージをアップロードする
245
ChatMediaHandler.uploadImage = function (formData) {
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
  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;
        }
323 324
        const sendData = encodedText;
        CHAT_SOCKET.emitCreateImage(sendData);
325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
      } 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%",
354
          poster: "./img/bg_movie.jpg",
355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
        });
        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;
        }
374 375
        const sendData = encodedText;
        CHAT_SOCKET.emitCreateVideo(sendData);
376 377 378 379 380 381 382 383 384
      }

      $(".overlay").removeClass("active undismissable");
      $(".loader").removeClass("active");
      Common.dismissLoadingIndicator();
    });
};

// Thumbnailのファイルを生成する。
385
ChatMediaHandler.createThumbnailAndUpload = function (sourceImage, callback) {
386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438
  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) {
Kim Peace committed
439
          console.error(error);
440 441 442 443 444
        }
      });
  };

  fileReader.readAsDataURL(sourceImage);
Kim Peace committed
445
};