Fix gallery view and lazy load thumbnails

This commit is contained in:
N-Pex 2025-06-19 10:58:11 +02:00
parent f0382afd83
commit acdef62880
6 changed files with 69 additions and 27 deletions

View file

@ -73,7 +73,7 @@ $hiliteColor: #4642f1;
color: rgba($text, 80%) !important;
}
.send-attachments__selecting__current-item {
.send-attachments__selecting__current-item, .gallery-current-item {
width: 100%;
flex: 1 1 100%;
background-color: $backgroundSection;
@ -102,7 +102,7 @@ $hiliteColor: #4642f1;
}
}
.file-drop-thumbnail-container {
.file-drop-thumbnail-container, .gallery-thumbnail-container {
width: 100%;
padding: 13px 20px 15px 20px;
flex: 0 0 74px;

View file

@ -1,5 +1,5 @@
<template>
<div class="fill-screen file-drop-root">
<div class="fill-screen send-attachments">
<div class="chat-header">
<v-container fluid class="d-flex justify-space-between align-center">
@ -9,13 +9,13 @@
</v-container>
</div>
<div class="file-drop-current-item">
<div class="gallery-current-item">
<ThumbnailView :item="items[currentItemIndex]" />
<div class="download-button clickable" @click.stop="downloadOne">
<v-icon color="black">arrow_downward</v-icon>
</div>
</div>
<div class="file-drop-thumbnail-container">
<div class="gallery-thumbnail-container">
<div :class="{ 'file-drop-thumbnail': true, 'clickable': true, 'current': id == currentItemIndex }"
@click="currentItemIndex = id" v-for="(currentImageInput, id) in items" :key="id">
<v-img v-if="currentImageInput" :src="currentImageInput.thumbnail ? currentImageInput.thumbnail : currentImageInput.src" />
@ -107,15 +107,17 @@ export default {
<style lang="scss">
@use "@/assets/css/chat.scss" as *;
@use "@/assets/css/sendattachments.scss" as *;
.chat-header {
position: relative !important;
width: 100%;
flex: 0 0 auto;
}
.file-drop-current-item {
position: relative;
}
// .file-drop-current-item {
// position: relative;
// }
.download-button {
position: absolute;
@ -137,7 +139,7 @@ export default {
right: 0;
bottom: 0;
background: black;
z-index: 20;
z-index: 20 !important;
justify-content: space-between !important;
}
</style>

View file

@ -1,5 +1,5 @@
<template>
<message-incoming v-bind="{ ...$props, ...$attrs }">
<message-incoming v-bind="{ ...$props, ...$attrs }" v-intersect="onIntersect">
<div class="bubble image-bubble" ref="imageRef">
<ImageWithProgress
:aspect-ratio="16 / 9"
@ -30,6 +30,7 @@ export default {
cover: true,
contain: false,
dialog: false,
isVisible: false,
};
},
methods: {
@ -44,6 +45,15 @@ export default {
}
});
},
loadThumbnail() {
if (this.isVisible) {
this.eventAttachment?.loadThumbnail();
}
},
onIntersect(isIntersecting, entries, observer) {
this.isVisible = isIntersecting;
this.loadThumbnail();
}
},
mounted() {
//console.log("Mounted with event:", JSON.stringify(this.event.getContent()));
@ -62,7 +72,7 @@ export default {
}
this.eventAttachment = this.$matrix.attachmentManager.getEventAttachment(this.event);
this.eventAttachment?.loadThumbnail();
this.loadThumbnail();
},
beforeUnmount() {
this.eventAttachment?.release();

View file

@ -1,5 +1,5 @@
<template>
<message-outgoing v-bind="{ ...$props, ...$attrs }">
<message-outgoing v-bind="{ ...$props, ...$attrs }" v-intersect="onIntersect">
<div class="bubble image-bubble" ref="imageRef">
<ImageWithProgress
:aspect-ratio="16 / 9"
@ -30,6 +30,7 @@ export default {
cover: true,
contain: false,
dialog: false,
isVisible: false,
};
},
methods: {
@ -44,6 +45,15 @@ export default {
}
});
},
loadThumbnail() {
if (this.isVisible) {
this.eventAttachment?.loadThumbnail();
}
},
onIntersect(isIntersecting, entries, observer) {
this.isVisible = isIntersecting;
this.loadThumbnail();
}
},
mounted() {
console.error("Mounted outgoing image, load thumbnail!");
@ -62,7 +72,7 @@ export default {
this.initMessageOutImageHammerJs(this.$refs.imageRef);
}
this.eventAttachment = this.$matrix.attachmentManager.getEventAttachment(this.event);
this.eventAttachment?.loadThumbnail();
this.loadThumbnail();
},
beforeUnmount() {
this.eventAttachment?.release();

View file

@ -3,6 +3,7 @@
ref="root"
v-bind="{ ...$props, ...$attrs }"
v-if="showMultiview"
v-intersect="onIntersect"
>
<div class="bubble">
<div class="original-message" v-if="inReplyToText">
@ -74,6 +75,7 @@ const emits = defineEmits<MessageEmits & {(event: "layout-change", value: {eleme
const items: Ref<EventAttachment[]> = ref([]);
const showItem: Ref<EventAttachment | undefined> = ref(undefined);
const isVisible: Ref<boolean> = ref(false);
const props = defineProps<MessageProps>();
@ -96,6 +98,17 @@ const {
linkify,
} = useMessage($matrix, t, props, emits, processThread);
const onRelationsCreated = () => {
if (event.value) {
thread.value = props.timelineSet.relations.getChildEventsForEvent(
event.value.getId() ?? "",
util.threadMessageType(),
"m.room.message"
);
event.value.off(MatrixEventEvent.RelationsCreated, onRelationsCreated);
}
};
watch(event, () => {
if (event.value) {
if (thread.value === undefined) {
@ -123,17 +136,6 @@ const showMultiview = computed((): boolean => {
messageText.value?.length > 0
});
const onRelationsCreated = () => {
if (event.value) {
thread.value = props.timelineSet.relations.getChildEventsForEvent(
event.value.getId() ?? "",
util.threadMessageType(),
"m.room.message"
);
event.value.off(MatrixEventEvent.RelationsCreated, onRelationsCreated);
}
};
const onItemClick = (event: any) => {
showItem.value = event.item;
};
@ -145,7 +147,7 @@ const _processThread = () => {
items.value = eventItems.map((e: MatrixEvent) => {
let ea = $matrix.attachmentManager.getEventAttachment(e);
if (showMultiview.value) {
if (showMultiview.value && isVisible.value) {
ea.loadThumbnail();
}
return ea;
@ -184,6 +186,14 @@ const layoutedItems = computed(() => {
}
return rows;
});
const onIntersect = (isIntersecting: boolean, entries: any, observer: any) => {
isVisible.value = isIntersecting;
if (showMultiview.value && isIntersecting) {
items.value.forEach((a) => a.loadThumbnail());
}
};
</script>
<style lang="scss">
@use "@/assets/css/chat.scss" as *;

View file

@ -3,6 +3,7 @@
ref="root"
v-bind="{ ...$props, ...$attrs }"
v-if="showMultiview"
v-intersect="onIntersect"
>
<div class="bubble">
<div class="original-message" v-if="inReplyToText">
@ -74,7 +75,8 @@ const emits = defineEmits<MessageEmits & {(event: "layout-change", value: {eleme
const items: Ref<EventAttachment[]> = ref([]);
const showItem: Ref<EventAttachment | undefined> = ref(undefined);
const isVisible: Ref<boolean> = ref(false);
const props = defineProps<MessageProps>();
const { room } = props;
@ -143,7 +145,7 @@ const _processThread = () => {
items.value = eventItems.map((e: MatrixEvent) => {
let ea = $matrix.attachmentManager.getEventAttachment(e);
if (showMultiview.value) {
if (showMultiview.value && isVisible.value) {
ea.loadThumbnail();
}
return ea;
@ -182,6 +184,14 @@ const layoutedItems = computed(() => {
}
return rows;
});
const onIntersect = (isIntersecting: boolean, entries: any, observer: any) => {
isVisible.value = isIntersecting;
if (showMultiview.value && isIntersecting) {
items.value.forEach((a) => a.loadThumbnail());
}
};
</script>
<style lang="scss">
@use "@/assets/css/chat.scss" as *;