mirror of
https://github.com/balzack/databag.git
synced 2025-04-24 10:35:23 +00:00
sending video attachments
This commit is contained in:
parent
21b4d1a4b6
commit
0c2de2e00d
@ -28,6 +28,7 @@
|
||||
"react": "18.3.1",
|
||||
"react-dom": "18.2.0",
|
||||
"react-easy-crop": "^5.0.8",
|
||||
"react-image-file-resizer": "^0.4.8",
|
||||
"react-resize-detector": "^11.0.1",
|
||||
"react-router-dom": "^6.26.0",
|
||||
"redaxios": "^0.5.1",
|
||||
|
@ -245,9 +245,11 @@ export function useContent() {
|
||||
addTopic: async (sealed: boolean, subject: string, contacts: string[]) => {
|
||||
const content = app.state.session.getContent()
|
||||
if (sealed) {
|
||||
return await content.addChannel(true, 'sealed', { subject }, contacts)
|
||||
const topic = await content.addChannel(true, 'sealed', { subject }, contacts)
|
||||
return topic.id;
|
||||
} else {
|
||||
return await content.addChannel(false, 'superbasic', { subject }, contacts)
|
||||
const topic = await content.addChannel(false, 'superbasic', { subject }, contacts)
|
||||
return topic.id;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ import { Divider, Text, Textarea, ActionIcon, Loader } from '@mantine/core'
|
||||
import { Message } from '../message/Message';
|
||||
import { modals } from '@mantine/modals'
|
||||
import { ImageFile } from './imageFile/ImageFile';
|
||||
import { VideoFile } from './videoFile/VideoFile';
|
||||
|
||||
const PAD_HEIGHT = (1024 - 64);
|
||||
const LOAD_DEBOUNCE = 1000;
|
||||
@ -26,6 +27,19 @@ export function Conversation() {
|
||||
const [sending, setSending] = useState(false);
|
||||
const { state, actions } = useConversation();
|
||||
const attachImage = useRef({ click: ()=>{} } as HTMLInputElement);
|
||||
const attachVideo = useRef({ click: ()=>{} } as HTMLInputElement);
|
||||
|
||||
const addImage = (image: File | undefined) => {
|
||||
if (image) {
|
||||
actions.addImage(image);
|
||||
}
|
||||
}
|
||||
|
||||
const addVideo = (video: File | undefined) => {
|
||||
if (video) {
|
||||
actions.addVideo(video);
|
||||
}
|
||||
}
|
||||
|
||||
const sendMessage = async () => {
|
||||
if (!sending) {
|
||||
@ -95,11 +109,16 @@ export function Conversation() {
|
||||
const media = state.assets.map((asset, index: number) => {
|
||||
if (asset.type === 'image') {
|
||||
return <ImageFile key={index} source={asset.file} />
|
||||
} else if (asset.type === 'video') {
|
||||
return <VideoFile key={index} source={asset.file} thumbPosition={(position: number) => actions.setThumbPosition(index, position)} disabled={sending} />
|
||||
} else {
|
||||
return <div key={index}></div>
|
||||
}
|
||||
});
|
||||
|
||||
console.log(state.assets);
|
||||
|
||||
|
||||
return (
|
||||
<div className={classes.conversation}>
|
||||
<div className={classes.header}>
|
||||
@ -159,33 +178,34 @@ export function Conversation() {
|
||||
</div>
|
||||
<div className={classes.divider} />
|
||||
<div className={classes.add}>
|
||||
<input type='file' name="asset" accept="image/*" ref={attachImage} onChange={e => actions.addImage(e.target.files[0])} style={{display: 'none'}}/>
|
||||
<input type='file' name="asset" accept="image/*" ref={attachImage} onChange={e => addImage(e.target?.files?.[0])} style={{display: 'none'}}/>
|
||||
<input type='file' name="asset" accept="video/*" ref={attachVideo} onChange={e => addVideo(e.target?.files?.[0])} style={{display: 'none'}}/>
|
||||
<div className={classes.files}>
|
||||
{ media }
|
||||
</div>
|
||||
<Textarea className={classes.message} placeholder={state.strings.newMessage} value={state.message} onChange={(event) => actions.setMessage(event.currentTarget.value)} disabled={!state.detail || state.detail.locked} />
|
||||
<Textarea className={classes.message} placeholder={state.strings.newMessage} value={state.message} onChange={(event) => actions.setMessage(event.currentTarget.value)} disabled={!state.detail || state.detail.locked || sending} />
|
||||
<div className={classes.controls}>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked} onClick={() => attachImage.current.click()}>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked || sending} onClick={() => attachImage.current.click()}>
|
||||
<IconCamera />
|
||||
</ActionIcon>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked}>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked || sending} onClick={() => attachVideo.current.click()}>
|
||||
<IconVideo />
|
||||
</ActionIcon>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked}>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked || sending}>
|
||||
<IconDisc />
|
||||
</ActionIcon>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked}>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked || sending}>
|
||||
<IconFile />
|
||||
</ActionIcon>
|
||||
<Divider size="sm" orientation="vertical" />
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked}>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked || sending}>
|
||||
<IconTextSize />
|
||||
</ActionIcon>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked}>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.detail || state.detail.locked || sending}>
|
||||
<IconTextColor />
|
||||
</ActionIcon>
|
||||
<div className={classes.send}>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={!state.message || !state.detail || state.detail.locked} onClick={sendMessage} loading={sending}>
|
||||
<ActionIcon className={classes.attach} variant="light" disabled={(!state.message && state.assets.length === 0) || !state.detail || state.detail.locked || sending} onClick={sendMessage} loading={sending}>
|
||||
<IconSend />
|
||||
</ActionIcon>
|
||||
</div>
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
.thumb {
|
||||
width: auto;
|
||||
height: 64px;
|
||||
height: 92px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,81 @@
|
||||
import { useState, useContext, useEffect, useRef } from 'react'
|
||||
import { AppContext } from '../context/AppContext'
|
||||
import { DisplayContext } from '../context/DisplayContext'
|
||||
import { Focus, FocusDetail, Topic, Profile, Card, AssetSource, HostingMode, TransformType } from 'databag-client-sdk'
|
||||
import { Focus, FocusDetail, Topic, Profile, Card, AssetType, AssetSource, HostingMode, TransformType } from 'databag-client-sdk'
|
||||
import { ContextType } from '../context/ContextType'
|
||||
import Resizer from "react-image-file-resizer";
|
||||
import failed from '../images/failed.png'
|
||||
|
||||
const img = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAIAQMAAAD+wSzIAAAABlBMVEX///+/v7+jQ3Y5AAAADklEQVQI12P4AIX8EAgALgAD/aNpbtEAAAAASUVORK5CYII'
|
||||
|
||||
const IMAGE_SCALE_SIZE = (128 * 1024);
|
||||
const GIF_TYPE = 'image/gif';
|
||||
const WEBP_TYPE = 'image/webp';
|
||||
const LOAD_DEBOUNCE = 1000;
|
||||
|
||||
function getImageThumb(file: File) {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
if ((file.type === GIF_TYPE || file.type === WEBP_TYPE) && file.size < IMAGE_SCALE_SIZE) {
|
||||
const reader = new FileReader();
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = function () {
|
||||
resolve(reader.result as string);
|
||||
};
|
||||
reader.onerror = function (error) {
|
||||
reject();
|
||||
};
|
||||
}
|
||||
else {
|
||||
Resizer.imageFileResizer(file, 192, 192, 'JPEG', 50, 0,
|
||||
uri => {
|
||||
resolve(uri as string);
|
||||
}, 'base64', 128, 128 );
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getVideoThumb(file: File, position: number) {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const url = URL.createObjectURL(file);
|
||||
var video = document.createElement("video");
|
||||
var timeupdate = function (ev: any) {
|
||||
video.removeEventListener("timeupdate", timeupdate);
|
||||
video.pause();
|
||||
setTimeout(() => {
|
||||
var canvas = document.createElement("canvas");
|
||||
if (!canvas) {
|
||||
reject();
|
||||
} else {
|
||||
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));
|
||||
}
|
||||
const context = canvas.getContext("2d");
|
||||
if (!context) {
|
||||
reject();
|
||||
} else {
|
||||
context.drawImage(video, 0, 0, canvas.width, canvas.height);
|
||||
var image = canvas.toDataURL("image/jpeg", 0.75);
|
||||
resolve(image);
|
||||
}
|
||||
}
|
||||
canvas.remove();
|
||||
video.remove();
|
||||
URL.revokeObjectURL(url);
|
||||
}, 1000);
|
||||
};
|
||||
video.addEventListener("timeupdate", timeupdate);
|
||||
video.preload = "metadata";
|
||||
video.src = url;
|
||||
video.muted = true;
|
||||
video.playsInline = true;
|
||||
video.currentTime = position;
|
||||
video.play();
|
||||
});
|
||||
}
|
||||
|
||||
export function useConversation() {
|
||||
const app = useContext(AppContext) as ContextType
|
||||
const display = useContext(DisplayContext) as ContextType
|
||||
@ -38,6 +106,13 @@ export function useConversation() {
|
||||
setState((s) => ({ ...s, ...value }))
|
||||
}
|
||||
|
||||
const updateAsset = (index, value) => {
|
||||
setState((s) => {
|
||||
s.assets[index] = { ...s.assets[index], ...value };
|
||||
return { ...s };
|
||||
});
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const { layout, strings } = display.state
|
||||
updateState({ layout, strings })
|
||||
@ -113,6 +188,9 @@ export function useConversation() {
|
||||
setMessage: (message: string) => {
|
||||
updateState({ message });
|
||||
},
|
||||
setThumbPosition: (index: number, position: number) => {
|
||||
updateAsset(index, { position });
|
||||
},
|
||||
more: async () => {
|
||||
const focus = app.state.focus;
|
||||
if (focus) {
|
||||
@ -129,33 +207,101 @@ export function useConversation() {
|
||||
const focus = app.state.focus;
|
||||
const sealed = state.detail?.sealed ? true : false;
|
||||
if (focus) {
|
||||
const subject = (assets: {assetId: string, appId: string}[]) => ({ text: state.message });
|
||||
const sources = [] as AssetSource[];
|
||||
const uploadAssets = state.assets.map(asset => {
|
||||
if (asset.type === 'image') {
|
||||
if (sealed) {
|
||||
sources.push({ type: AssetType.Image, source: asset.file, transforms: [
|
||||
{ type: TransformType.Thumb, appId: `it${sources.length}`, thumb: () => getImageThumb(asset.file) },
|
||||
{ type: TransformType.Copy, appId: `ic${sources.length}` }
|
||||
]});
|
||||
return { encrypted: { type: 'image', thumb: `it${sources.length-1}`, parts: `ic${sources.length-1}` } };
|
||||
} else {
|
||||
sources.push({ type: AssetType.Image, source: asset.file, transforms: [
|
||||
{ type: TransformType.Thumb, appId: `it${sources.length}` },
|
||||
{ type: TransformType.Copy, appId: `ic${sources.length}` }
|
||||
]});
|
||||
return { image: { thumb: `it${sources.length-1}`, full: `ic${sources.length-1}` } };
|
||||
}
|
||||
} else if (asset.type === 'video') {
|
||||
if (sealed) {
|
||||
sources.push({ type: AssetType.Video, source: asset.file, transforms: [
|
||||
{ type: TransformType.Thumb, appId: `vt${sources.length}`, thumb: () => getVideoThumb(asset.file, asset.position) },
|
||||
{ type: TransformType.Copy, appId: `vc${sources.length}` }
|
||||
]});
|
||||
return { encrypted: { type: 'video', thumb: `vt${sources.length-1}`, parts: `vc${sources.length-1}` } };
|
||||
} else {
|
||||
sources.push({ type: AssetType.Video, source: asset.file, transforms: [
|
||||
{ type: TransformType.Thumb, appId: `vt${sources.length}`, position: asset.position},
|
||||
{ type: TransformType.HighQuality, appId: `vh${sources.length}` },
|
||||
{ type: TransformType.LowQuality, appId: `vl${sources.length}` }
|
||||
]});
|
||||
return { video: { thumb: `vt${sources.length-1}`, hd: `vh${sources.length-1}`, lq: `vl${sources.length-1}` } };
|
||||
}
|
||||
} else if (asset.type === 'audio') {
|
||||
if (sealed) {
|
||||
sources.push({ type: AssetType.Audio, source: asset.file, transforms: [
|
||||
{ type: TransformType.Copy, appId: `ac${sources.length}` }
|
||||
]});
|
||||
return { encrypted: { type: 'audio', parts: `ac${sources.length-1}` } };
|
||||
} else {
|
||||
sources.push({ type: AssetType.Video, source: asset.file, transforms: [
|
||||
{ type: TransformType.Copy, appId: `ac${sources.length}` }
|
||||
]});
|
||||
return { audio: { full: `ac${sources.length-1}` } };
|
||||
}
|
||||
} else {
|
||||
if (sealed) {
|
||||
sources.push({ type: AssetType.Binary, source: asset.file, transforms: [
|
||||
{ type: TransformType.Copy, appId: `bc${sources.length}` }
|
||||
]});
|
||||
return { encrypted: { type: 'binary', parts: `bc${sources.length-1}` } };
|
||||
} else {
|
||||
sources.push({ type: AssetType.Binary, source: asset.file, transforms: [
|
||||
{ type: TransformType.Copy, appId: `bc${sources.length}` }
|
||||
]});
|
||||
return { binary: { data: `bc${sources.length-1}` } };
|
||||
}
|
||||
}
|
||||
});
|
||||
const subject = (uploaded: {assetId: string, appId: string}[]) => {
|
||||
const assets = uploadAssets.map(asset => {
|
||||
if(asset.encrypted) {
|
||||
const type = asset.encrypted.type;
|
||||
const thumb = uploaded.find(upload => upload.appId === asset.encrypted.thumb)?.assetId;
|
||||
const parts = uploaded.find(upload => upload.appId === asset.encrypted.parts)?.assetId;
|
||||
return { encrypted: { type, thumb, parts }};
|
||||
} else if (asset.image) {
|
||||
const thumb = uploaded.find(upload => upload.appId === asset.image.thumb)?.assetId;
|
||||
const full = uploaded.find(upload => upload.appId === asset.image.full)?.assetId;
|
||||
return { image: { thumb, full } };
|
||||
} else if(asset.video) {
|
||||
const thumb = uploaded.find(upload => upload.appId === asset.video.thumb)?.assetId;
|
||||
const hd = uploaded.find(upload => upload.appId === asset.video.hd)?.assetId;
|
||||
const lq = uploaded.find(upload => upload.appId === asset.video.lq)?.assetId;
|
||||
return { video: { thumb, hd, lq } };
|
||||
} else if (asset.audio) {
|
||||
const full = uploaded.find(upload => upload.appId === asset.audio.full)?.assetId;
|
||||
return { audio: { full } };
|
||||
} else {
|
||||
const data = uploaded.find(upload => upload.appId === asset.binary.data)?.assetId;
|
||||
return { binary: { data } };
|
||||
}
|
||||
});
|
||||
return { text: state.message, assets };
|
||||
}
|
||||
const progress = (precent: number) => {};
|
||||
await focus.addTopic(sealed, sealed ? 'sealedtopic' : 'superbasictopic', subject, [], progress);
|
||||
updateState({ message: '' });
|
||||
await focus.addTopic(sealed, sealed ? 'sealedtopic' : 'superbasictopic', subject, sources, progress);
|
||||
updateState({ message: '', assets: [] });
|
||||
}
|
||||
},
|
||||
addImage: (file: File) => {
|
||||
const type = 'image';
|
||||
updateState({ assets: [ ...state.assets, { type, file } ]});
|
||||
},
|
||||
add: async (file: File) => {
|
||||
const focus = app.state.focus;
|
||||
if (focus) {
|
||||
const asset = {
|
||||
name: 'topic',
|
||||
mimeType: 'image',
|
||||
extension: 'jpg',
|
||||
source: file,
|
||||
transforms: [ {type: TransformType.Thumb, thumb: ()=>(img), appId: '1'}, {type: TransformType.Copy, appId: '2'}],
|
||||
}
|
||||
const topicId = await focus.addTopic(true, 'sealedtopic', (assets: {assetId: string, appId: string}[])=>{
|
||||
console.log(assets);
|
||||
return { text: 'almost done', assets: [{ encrypted: { type: 'image', thumb: '0', parts: '1' } }] };
|
||||
}, [asset], (percent: number)=>{
|
||||
console.log(percent);
|
||||
});
|
||||
}
|
||||
addVideo: (file: File) => {
|
||||
const type = 'video';
|
||||
updateState({ assets: [ ...state.assets, { type, file } ]});
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
.asset {
|
||||
position: relative;
|
||||
margin-top: 16px;
|
||||
height: 92px;
|
||||
border-radius: 2px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.left {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.right {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.thumb {
|
||||
width: auto;
|
||||
height: 64px;
|
||||
}
|
||||
}
|
||||
|
53
app/client/web/src/conversation/videoFile/VideoFile.tsx
Normal file
53
app/client/web/src/conversation/videoFile/VideoFile.tsx
Normal file
@ -0,0 +1,53 @@
|
||||
import React, { useRef, useState } from 'react';
|
||||
import { ActionIcon, Image } from '@mantine/core'
|
||||
import { useVideoFile } from './useVideoFile.hook';
|
||||
import classes from './VideoFile.module.css'
|
||||
import { IconChevronLeft, IconChevronRight } from '@tabler/icons-react'
|
||||
|
||||
export function VideoFile({ source, thumbPosition, disabled }: {source: File, thumbPosition: (position: number)=>void, disabled: boolean}) {
|
||||
const { state, actions } = useVideoFile(source);
|
||||
const [loaded, setLoaded] = useState(false);
|
||||
const position = useRef(0);
|
||||
const player = useRef();
|
||||
|
||||
const seek = (offset: number) => {
|
||||
if (player.current) {
|
||||
const len = player.current.duration;
|
||||
if (len > 16) {
|
||||
position.current += offset * Math.floor(len / 16);
|
||||
}
|
||||
else {
|
||||
position.current += offset;
|
||||
}
|
||||
if (position.current < 0 || position.current >= len) {
|
||||
position.current = 0;
|
||||
}
|
||||
thumbPosition(position.current);
|
||||
player.current.currentTime = position.current;
|
||||
player.current.play();
|
||||
}
|
||||
}
|
||||
|
||||
const onPause = () => {
|
||||
player.current.pause();
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={classes.asset}>
|
||||
{ state.videoUrl && (
|
||||
<video ref={player} muted onLoadedMetadata={() => setLoaded(true)} onPlay={onPause} src={state.videoUrl} width={'auto'} height={'100%'} playsinline="true" />
|
||||
)}
|
||||
{ loaded && !disabled && (
|
||||
<ActionIcon className={classes.right} variant="light" onClick={() => seek(1)}>
|
||||
<IconChevronRight />
|
||||
</ActionIcon>
|
||||
)}
|
||||
{ loaded && !disabled && (
|
||||
<ActionIcon className={classes.left} variant="light" onClick={() => seek(-1)}>
|
||||
<IconChevronLeft />
|
||||
</ActionIcon>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
|
||||
export function useVideoFile(source: File) {
|
||||
const [state, setState] = useState({
|
||||
videoUrl: null,
|
||||
})
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const updateState = (value: any) => {
|
||||
setState((s) => ({ ...s, ...value }))
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const videoUrl = URL.createObjectURL(source);
|
||||
updateState({ videoUrl });
|
||||
return () => { URL.revokeObjectURL(videoUrl) };
|
||||
}, [source]);
|
||||
|
||||
const actions = {
|
||||
}
|
||||
|
||||
return { state, actions }
|
||||
}
|
@ -60,6 +60,12 @@
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.incomplete {
|
||||
margin-left: 72px;
|
||||
margin-right: 32px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.content {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -9,7 +9,6 @@ import { VideoAsset } from './videoAsset/VideoAsset';
|
||||
import { BinaryAsset } from './binaryAsset/BinaryAsset';
|
||||
import type { MediaAsset } from '../conversation/Conversation';
|
||||
import { useMessage } from './useMessage.hook';
|
||||
import failed from '../images/failed.png'
|
||||
import { IconForbid, IconTrash, IconEdit, IconAlertSquareRounded, IconChevronLeft, IconChevronRight, IconFileAlert } from '@tabler/icons-react';
|
||||
import { useResizeDetector } from 'react-resize-detector';
|
||||
|
||||
@ -126,7 +125,9 @@ export function Message({ topic, card, profile, host }: { topic: Topic, card: Ca
|
||||
</div>
|
||||
)}
|
||||
{ !locked && media.length > 0 && transform === 'incomplete' && (
|
||||
<Skeleton height={64} circle mb="xl" />
|
||||
<div className={classes.incomplete}>
|
||||
<Skeleton height={64} circle mb="xl" />
|
||||
</div>
|
||||
)}
|
||||
{ !locked && media.length > 0 && transform !== 'complete' && transform !== 'incomplete' && (
|
||||
<div className={classes.failed}>
|
||||
|
@ -26,7 +26,7 @@ export function useMessage() {
|
||||
const now = Math.floor((new Date()).getTime() / 1000)
|
||||
const date = new Date(created * 1000);
|
||||
const offset = now - created;
|
||||
if(offset < 86400) {
|
||||
if(offset < 43200) {
|
||||
if (state.timeFormat === '12h') {
|
||||
return date.toLocaleTimeString("en-US", {hour: 'numeric', minute:'2-digit'});
|
||||
}
|
||||
|
13234
app/client/web/yarn.lock
13234
app/client/web/yarn.lock
File diff suppressed because it is too large
Load Diff
@ -450,8 +450,9 @@ export class FocusModule implements Focus {
|
||||
transforms.push('icopy;photo');
|
||||
transformMap.set('icopy;photo', transform.appId);
|
||||
} else if (transform.type === TransformType.Thumb && asset.type === AssetType.Video) {
|
||||
transforms.push('vthumb;video');
|
||||
transformMap.set('vthumb;video', transform.appId);
|
||||
const transformKey = `vthumb;video;${ transform.position ? transform.position : 0}`;
|
||||
transforms.push(transformKey);
|
||||
transformMap.set(transformKey, transform.appId);
|
||||
} else if (transform.type === TransformType.Copy && asset.type === AssetType.Video) {
|
||||
transforms.push('vcopy;video');
|
||||
transformMap.set('vcopy;video', transform.appId);
|
||||
@ -487,7 +488,7 @@ export class FocusModule implements Focus {
|
||||
}
|
||||
if (transformMap.has(transformAsset.transform)) {
|
||||
const appId = transformMap.get(transformAsset.transform) || '' //or to make build happy
|
||||
appAsset.push({appId, assetId: transformAsset.assetId });
|
||||
appAsset.push({appId, assetId: assetItem.assetId });
|
||||
assetItems.push(assetItem);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user