Support for retry when sending media

This commit is contained in:
N-Pex 2025-08-21 16:07:13 +02:00
parent 881270f149
commit ce6398685f
7 changed files with 69 additions and 34 deletions

View file

@ -29,48 +29,58 @@ import { EventAttachment } from "../../models/eventAttachment";
import { useThumbnail } from "../messages/composition/useThumbnail";
import { Attachment } from "../../models/attachment";
import ImageWithProgress from "../ImageWithProgress.vue";
function isEventAttachment(source: EventAttachment | Attachment | undefined): source is EventAttachment {
return (source as EventAttachment).event !== undefined;
}
function isAttachment(source: EventAttachment | Attachment | undefined): source is Attachment {
return (source as Attachment).file !== undefined;
}
const $$sanitize: any = inject("globalSanitize");
const thumbnailRef = useTemplateRef("thumbnailRef");
interface ThumbnailProps {
item?: EventAttachment;
file?: Attachment;
item?: EventAttachment | Attachment;
previewOnly?: boolean;
}
type ThumbnailEmits = {
(event: "itemclick", value: { item: EventAttachment }): void;
(event: "itemclick", value: { item: EventAttachment | Attachment }): void;
};
const props = defineProps<ThumbnailProps>();
const { item, file, previewOnly = false } = props;
const { item, previewOnly = false } = props;
const emits = defineEmits<ThumbnailEmits>();
let { isVideo, isImage, fileTypeIcon, fileTypeIconClass, fileName, fileSize } = useThumbnail(file?.file ?? item?.event);
let { isVideo, isImage, fileTypeIcon, fileTypeIconClass, fileName, fileSize } = useThumbnail(isEventAttachment(props.item) ? props.item.event : isAttachment(props.item) ? props.item.file : undefined);
const fileURL: Ref<string | undefined> = ref(undefined);
const source: Ref<string | undefined> = ref(undefined);
const poster: Ref<string | undefined> = ref(undefined);
const updateSource = () => {
if (props.item) {
if (isVideo.value || props.item.src) {
source.value = props.item.src;
if (isEventAttachment(props.item)) {
const eventAttachment = props.item;
if (isVideo.value || eventAttachment.src) {
source.value = eventAttachment.src;
} else if (previewOnly) {
props.item.loadThumbnail().then((url) => {
eventAttachment.loadThumbnail().then((url) => {
source.value = url.data;
})
} else if (isImage.value) {
props.item.loadSrc().then((url) => {
eventAttachment.loadSrc().then((url) => {
source.value = url.data;
})
}
} else if (props.file) {
} else if (isAttachment(props.item)) {
const attachment = props.item;
if (fileURL.value) {
URL.revokeObjectURL(fileURL.value);
}
fileURL.value = URL.createObjectURL(props.file.file);
fileURL.value = URL.createObjectURL(attachment.file);
source.value = fileURL.value;
} else {
source.value = undefined;
@ -78,11 +88,12 @@ const updateSource = () => {
};
const updatePoster = () => {
if (props.item && isVideo.value) {
if (props.item.thumbnail) {
poster.value = props.item.thumbnail;
if (isEventAttachment(props.item) && isVideo.value) {
const eventAttachment = props.item;
if (eventAttachment.thumbnail) {
poster.value = eventAttachment.thumbnail;
} else {
props.item
eventAttachment
.loadThumbnail()
.then((url) => {
poster.value = url.data;
@ -99,7 +110,7 @@ updatePoster();
watch(props, (props: ThumbnailProps) => {
const updates = useThumbnail(props.file?.file ?? props.item?.event);
const updates = useThumbnail(isEventAttachment(props.item) ? props.item.event : isAttachment(props.item) ? props.item.file : undefined);
isVideo.value = updates.isVideo.value;
isImage.value = updates.isImage.value;
fileTypeIcon = updates.fileTypeIcon;
@ -111,23 +122,24 @@ watch(props, (props: ThumbnailProps) => {
});
const loadingProgress = computed(() => {
if (item) {
return previewOnly ? item.thumbnailProgress : item.srcProgress;
if (isEventAttachment(item)) {
const eventAttachment = item;
return previewOnly ? eventAttachment.thumbnailProgress : eventAttachment.srcProgress;
}
return -1;
});
onMounted(() => {
if (thumbnailRef.value && (item as EventAttachment)) {
if (thumbnailRef.value && item) {
const hammerInstance = singleOrDoubleTapRecognizer(thumbnailRef.value);
hammerInstance.on("singletap doubletap", (ev: any) => {
if (ev.type === "singletap") {
emits("itemclick", { item: item as EventAttachment });
emits("itemclick", { item: item });
}
});
}
if (!previewOnly && item && (item as EventAttachment)) {
(item as EventAttachment).loadSrc();
if (!previewOnly && item && isEventAttachment(item)) {
item.loadSrc();
}
});