browser app cleanup for sending encrypted blocks

This commit is contained in:
Roland Osborne 2023-04-27 12:16:14 -07:00
parent 000d306bd1
commit 681bea25f8
2 changed files with 75 additions and 66 deletions

View File

@ -1,5 +1,6 @@
import { useState, useRef } from 'react'; import { useState, useRef } from 'react';
import axios from 'axios'; import axios from 'axios';
import Resizer from "react-image-file-resizer";
const ENCRYPTED_BLOCK_SIZE = (128 * 1024); //110k const ENCRYPTED_BLOCK_SIZE = (128 * 1024); //110k
@ -149,6 +150,61 @@ export function useUploadContext() {
return { state, actions } return { state, actions }
} }
function getImageThumb(url) {
return new Promise(resolve => {
Resizer.imageFileResizer(url, 192, 192, 'JPEG', 50, 0,
uri => {
resolve(uri);
}, 'base64', 128, 128 );
});
}
function getVideoThumb(url, pos) {
return new Promise((resolve, reject) => {
var video = document.createElement("video");
var timeupdate = function (ev) {
video.removeEventListener("timeupdate", timeupdate);
video.pause();
setTimeout(() => {
var canvas = document.createElement("canvas");
if (video.videoWidth > video.videoHeight) {
canvas.width = 192;
canvas.height = Math.floor((192 * video.videoHeight / video.videoWidth));
}
else {
canvas.height = 192;
canvas.width = Math.floor((192 * video.videoWidth / video.videoHeight));
}
canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height);
var image = canvas.toDataURL("image/jpeg", 0.75);
resolve(image);
canvas.remove();
video.remove();
}, 1000);
};
video.addEventListener("timeupdate", timeupdate);
video.preload = "metadata";
video.src = url;
video.muted = true;
video.playsInline = true;
video.currentTime = pos;
video.play();
});
}
async function getThumb(url, type, position) {
if (type === 'image') {
return await getImageThumb(url);
}
else if (type === 'video') {
return await getVideoThumb(url, position);
}
else {
return null;
}
}
async function upload(entry, update, complete) { async function upload(entry, update, complete) {
if (!entry.files?.length) { if (!entry.files?.length) {
entry.success(entry.assets); entry.success(entry.assets);
@ -159,9 +215,9 @@ async function upload(entry, update, complete) {
entry.active = {}; entry.active = {};
try { try {
if (file.encrypted) { if (file.encrypted) {
const { size, getThumb, getEncryptedBlock, position } = file; const { size, getEncryptedBlock, position, image, video, audio } = file;
const type = file.image ? 'image' : file.video ? 'video' : file.audio ? 'audio' : ''; const { url, type } = image ? { url: image, type: 'image' } : video ? { url: video, type: 'video' } : audio ? { url: audio, type: 'audio' } : {}
const thumb = getThumb(position); const thumb = await getThumb(url, type, position);
const parts = []; const parts = [];
for (let pos = 0; pos < size; pos += ENCRYPTED_BLOCK_SIZE) { for (let pos = 0; pos < size; pos += ENCRYPTED_BLOCK_SIZE) {
const { blockEncrypted, blockIv } = await getEncryptedBlock(pos, ENCRYPTED_BLOCK_SIZE); const { blockEncrypted, blockIv } = await getEncryptedBlock(pos, ENCRYPTED_BLOCK_SIZE);

View File

@ -64,7 +64,9 @@ export function useAddTopic(contentKey) {
updateState({ enableImage, enableAudio, enableVideo }); updateState({ enableImage, enableAudio, enableVideo });
}, [conversation.state.channel?.data?.channelDetail]); }, [conversation.state.channel?.data?.channelDetail]);
const setUrl = async (url, getThumb) => { const setUrl = async (file) => {
const url = URL.createObjectURL(file);
objects.current.push(url);
if (contentKey) { if (contentKey) {
const buffer = await url.arrayBuffer(); const buffer = await url.arrayBuffer();
const getEncryptedBlock = (pos, len) => { const getEncryptedBlock = (pos, len) => {
@ -74,38 +76,30 @@ export function useAddTopic(contentKey) {
const block = btoa(String.fromCharCode.apply(null, buffer.slice(pos, len))); const block = btoa(String.fromCharCode.apply(null, buffer.slice(pos, len)));
return getEncryptedBlock(block, contentKey); return getEncryptedBlock(block, contentKey);
} }
return { url, position: 0, label: '', encrypted: true, size: buffer.byteLength, getEncryptedBlock, getThumb }; return { url, encrypted: true, size: buffer.byteLength, getEncryptedBlock };
} }
else { else {
return { url, position: 0, label: '', encrypted: false }; return { url, encrypted: false };
} }
} }
const actions = { const actions = {
addImage: async (image) => { addImage: async (image) => {
const url = URL.createObjectURL(image); const asset = await setUrl(image);
objects.current.push(url); asset.image = image;
const getThumb = async () => { addAsset(asset);
return await getImageThumb(url);
}
const asset = setUrl(url, getThumb);
addAsset({ image, ...asset });
}, },
addVideo: async (video) => { addVideo: async (video) => {
const url = URL.createObjectURL(video); const asset = await setUrl(video);
objects.current.push(url); asset.video = video;
const getThumb = async (position) => { asset.position = 0;
return await getVideoThumb(url, position); addAsset(asset);
}
const asset = setUrl(url, getThumb);
addAsset({ video, ...asset });
}, },
addAudio: async (audio) => { addAudio: async (audio) => {
const url = URL.createObjectURL(audio); const asset = await setUrl(audio);
objects.current.push(url); asset.audio = audio;
const getThumb = async () => { return null }; asset.label = '';
const asset = setUrl(url, getThumb); addAsset(asset);
addAsset({ audio, ...asset });
}, },
setLabel: (index, label) => { setLabel: (index, label) => {
updateAsset(index, { label }); updateAsset(index, { label });
@ -167,44 +161,3 @@ export function useAddTopic(contentKey) {
return { state, actions }; return { state, actions };
} }
async function getImageThumb(url) {
return new Promise(resolve => {
Resizer.imageFileResizer(url, 192, 192, 'JPEG', 50, 0,
uri => {
resolve(uri);
}, 'base64', 128, 128 );
});
}
async function getVideoThumb(url, pos) {
return new Promise((resolve, reject) => {
var video = document.createElement("video");
var timeupdate = function (ev) {
video.removeEventListener("timeupdate", timeupdate);
video.pause();
setTimeout(() => {
var canvas = document.createElement("canvas");
if (video.videoWidth > video.videoHeight) {
canvas.width = 192;
canvas.height = Math.floor((192 * video.videoHeight / video.videoWidth));
}
else {
canvas.height = 192;
canvas.width = Math.floor((192 * video.videoWidth / video.videoHeight));
}
canvas.getContext("2d").drawImage(video, 0, 0, canvas.width, canvas.height);
var image = canvas.toDataURL("image/jpeg", 0.75);
resolve(image);
canvas.remove();
video.remove();
}, 1000);
};
video.addEventListener("timeupdate", timeupdate);
video.preload = "metadata";
video.src = url;
video.muted = true;
video.playsInline = true;
video.currentTime = pos;
video.play();
});
}