rendering full screen image attachement

This commit is contained in:
Roland Osborne 2024-12-17 18:08:54 -08:00
parent 9d7f933ae8
commit 440d65e12b
7 changed files with 5479 additions and 8052 deletions

View File

@ -40,3 +40,4 @@
button {
font-size: calc(10px + 2vmin);
}

View File

@ -9,7 +9,7 @@ import { VideoAsset } from './videoAsset/VideoAsset';
import { BinaryAsset } from './binaryAsset/BinaryAsset';
import type { MediaAsset } from '../conversation/Conversation';
import { useMessage } from './useMessage.hook';
import { IconForbid, IconTrash, IconEdit, IconAlertSquareRounded, IconChevronLeft, IconChevronRight, IconFileAlert } from '@tabler/icons-react';
import { IconForbid, IconTrash, IconShare, IconEdit, IconAlertSquareRounded, IconChevronLeft, IconChevronRight, IconFileAlert } from '@tabler/icons-react';
import { useResizeDetector } from 'react-resize-detector';
export function Message({ topic, card, profile, host }: { topic: Topic, card: Card | null, profile: Profile | null, host: boolean }) {
@ -74,6 +74,7 @@ export function Message({ topic, card, profile, host }: { topic: Topic, card: Ca
</div>
<div className={classes.options}>
<div className={classes.surface}>
<IconShare className={classes.option} />
{ !locked && profile && (
<IconEdit className={classes.option} />
)}

View File

@ -1,4 +1,5 @@
.asset {
cursor: pointer;
.thumb {
width: auto;
@ -6,3 +7,15 @@
}
}
.modal {
section {
background-color: transparent;
}
.body {
.image {
}
}
}

View File

@ -1,17 +1,49 @@
import React from 'react';
import React, { useState } from 'react';
import { MediaAsset } from '../../conversation/Conversation';
import { useImageAsset } from './useImageAsset.hook';
import { Image } from '@mantine/core'
import { ActionIcon, Modal, Image } from '@mantine/core'
import classes from './ImageAsset.module.css'
import { IconX } from '@tabler/icons-react'
export function ImageAsset({ topicId, asset }: { topicId: string, asset: MediaAsset }) {
const { state, actions } = useImageAsset(topicId, asset);
const [show, setShow] = useState(false);
const showImage = () => {
setShow(true);
actions.loadImage();
}
return (
<div className={classes.asset}>
<div>
{ state.thumbUrl && (
<Image radius="sm" className={classes.thumb} src={state.thumbUrl} />
<div className={classes.asset} onClick={showImage}>
<Image radius="sm" className={classes.thumb} src={state.thumbUrl} />
</div>
)}
<Modal className={classes.modal} opened={show} onClose={() => setShow(false)} padding={0} size="xl" overlayProps={{ backgroundOpacity: 0.65, blur: 3 }} centered withCloseButton={false}>
{ !state.dataUrl && (
<div className={classes.body}>
<Image radius="lg" className={classes.image} fit="contain" src={state.thumbUrl} />
<div className={classes.frame}>
<ActionIcon variant="subtle" size="lg" onClick={() => setShow(false)}>
<IconX size="lg" />
</ActionIcon>
</div>
</div>
)}
{ state.dataUrl && (
<div className={classes.body}>
<Image radius="lg" className={classes.image} fit="contain" src={state.dataUrl} />
<div className={classes.frame}>
<ActionIcon variant="subtle" size="lg" onClick={() => setShow(false)}>
<IconX size="lg" />
</ActionIcon>
</div>
</div>
)}
</Modal>
</div>
);
}

View File

@ -8,6 +8,7 @@ export function useImageAsset(topicId: string, asset: MediaAsset) {
const app = useContext(AppContext) as ContextType
const [state, setState] = useState({
thumbUrl: null,
dataUrl: null,
})
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -33,13 +34,20 @@ export function useImageAsset(topicId: string, asset: MediaAsset) {
}, [asset]);
const actions = {
getAssetUrl: async (topicId: string, assetId: string) => {
loadImage: async () => {
console.log("CHECK0");
const { focus } = app.state;
if (!focus) {
throw new Error('no channel in focus');
const assetId = asset.image ? asset.image.full : asset.encrypted ? asset.encrypted.parts : null;
if (focus && assetId != null) {
try {
console.log("CHECK1");
const dataUrl = await focus.getTopicAssetUrl(topicId, assetId);
updateState({ dataUrl });
} catch (err) {
console.log(err);
}
}
return await focus.getTopicAssetUrl(topicId, assetId, (percent: number)=>true);
},
}
}
return { state, actions }

File diff suppressed because it is too large Load Diff

View File

@ -970,37 +970,73 @@ export class FocusModule implements Focus {
index += 1;
if (thumb) {
return { encrypted: { type, thumb: `${index-2}`, data: `${index-1}`, label, extension } }
return { encrypted: { type, thumb: `${index-2}`, parts: `${index-1}`, label, extension } }
} else {
return { encrypted: { type, data: `${index-1}`, label, extension } }
return { encrypted: { type, parts: `${index-1}`, label, extension } }
}
} else {
const { thumb, label, full, lq, hd, extension, data } = (binary || image || audio || video) as any;
if (thumb) {
const asset = {
if (image) {
const { thumb, full } = image;
const thumbAsset = {
assetId: `${index}`,
hosting: HostingMode.Basic,
basic: thumb,
}
assetItems.add(asset);
assetItems.add(thumbAsset);
index += 1;
}
const asset = {
assetId: `${index}`,
hosting: HostingMode.Basic,
basic: full || hd || lq,
}
assetItems.add(asset);
index += 1;
const type = image ? 'image' : audio ? 'audio' : video ? 'video' : 'binary';
const assetEntry = {} as any;
if (thumb) {
assetEntry[type] = { thumb: `${index-2}`, data: `${index-1}`, label, extension }
const fullAsset = {
assetId: `${index}`,
hosting: HostingMode.Basic,
basic: full,
}
assetItems.add(fullAsset);
index += 1;
return { image: { thumb: `${index-2}`, full: `${index-1}` }};
} else if (video) {
const { thumb, hd, lq } = video;
const thumbAsset = {
assetId: `${index}`,
hosting: HostingMode.Basic,
basic: thumb,
}
assetItems.add(thumbAsset);
index += 1;
const hdAsset = {
assetId: `${index}`,
hosting: HostingMode.Basic,
basic: hd,
}
assetItems.add(fullAsset);
index += 1;
const lqAsset = {
assetId: `${index}`,
hosting: HostingMode.Basic,
basic: lq,
}
assetItems.add(fullAsset);
index += 1;
return { video: { thumb: `${index-3}`, hd: `${index-2}`, lq: `${index-1}` }};
} else if (audio) {
const { label, full } = audio;
const fullAsset = {
assetId: `${index}`,
hosting: HostingMode.Basic,
basic: full,
}
assetItems.add(fullAsset);
index += 1;
return { audio: { label, full: `${index-1}` }};
} else {
assetEntry[type] = { data: `${index-1}`, label, extension }
const { label, extension, data } = binary;
const dataAsset = {
assetId: `${index}`,
hosting: HostingMode.Basic,
basic: data,
}
assetItems.add(dataAsset);
index += 1;
return { audio: { label, extension, data: `${index-1}` }};
}
return assetEntry;
}
})
return { data: { text, textColor, textSize, assets: dataAssets }, assets: Array.from(assetItems.values()) };