Place CR icon correctly on (scaled) image

Also, show "red dot" only if details not viewed already.
This commit is contained in:
N-Pex 2025-11-03 09:16:48 +01:00
parent 28865658d2
commit c66602deb7
7 changed files with 74 additions and 37 deletions

View file

@ -1,5 +1,6 @@
<template>
<v-img class="image-with-progress" v-bind="{...$props, ...$attrs}">
<resize-observer @notify="handleResize" />
<v-img ref="image" class="image-with-progress" v-bind="{...$props, ...$attrs}" v-on:load="loaded">
<LoadProgress class="image-with-progress__progress" v-if="loadingProgress != undefined && loadingProgress >= 0 && loadingProgress < 100" :percentage="loadingProgress" />
</v-img>
</template>
@ -12,10 +13,10 @@ import * as sdk from "matrix-js-sdk";
import logoMixin from "./logoMixin";
import LoadProgress from "./LoadProgress.vue";
import { VImg } from "vuetify/components/VImg";
import { emit } from "process";
export default {
name: "ImageWithProgress",
extends: VImg,
components: { LoadProgress },
props: {
loadingProgress: {
@ -28,6 +29,14 @@ export default {
data() {
return {};
},
methods: {
loaded() {
this.$emit('loaded', this.$refs.image);
},
handleResize() {
this.loaded();
}
}
};
</script>

View file

@ -1,6 +1,6 @@
<template>
<div class="cc-detail-info" v-if="infoText !== undefined" v-html="infoText" />
<div class="attachment-info__detail-box" v-if="!showFlagsOnly">
<div class="attachment-info__detail-box" v-if="!showFlagsOnly && details.length > 0">
<div class="detail-title">
{{ t("cc.details") }}
<v-icon v-if="hasC2PA">$vuetify.icons.ic_cr</v-icon>

View file

@ -24,16 +24,16 @@
<div :class="{ 'send-attachments__selecting__current-item': true, 'drop-target': dropTarget }"
@drop.prevent="filesDropped" @dragover.prevent="dropTarget = true" @dragleave.prevent="dropTarget = false"
@dragenter.prevent="dropTarget = true">
<ThumbnailView :item="currentAttachment" />
<div v-if="currentAttachment && currentAttachment.status === 'loading'"
class="send-attachments__selecting__current-item__preparing">
<div style="font-size: 0.7em; opacity: 0.7">
<v-progress-circular indeterminate class="mb-0"></v-progress-circular>
</div>
</div>
<div v-else-if="showCCIcon" class="send-attachments__selecting__current-item__cc">
<v-icon style="width:24px;height:24px">$vuetify.icons.ic_cr</v-icon>
</div>
<ThumbnailView :item="currentAttachment">
<template v-slot:decorator v-if="currentAttachment && currentAttachment.status === 'loading'">
<div style="font-size: 0.7em; opacity: 0.7">
<v-progress-circular indeterminate class="mb-0"></v-progress-circular>
</div>
</template>
<template v-slot:decorator v-else-if="showCCIcon">
<v-icon style="width:24px;height:24px">$vuetify.icons.ic_cr</v-icon>
</template>
</ThumbnailView>
</div>
<div class="file-drop-thumbnail-container">
@ -68,7 +68,7 @@
<v-btn class="send-button clickable" icon="arrow_upward" size="default" elevation="0" color="black"
@click.stop="sendAll" :disabled="sendButtonDisabled"></v-btn>
</div>
<v-badge location="top right" color="#ff3300" dot class="cc-badge" :model-value="anyContainsCC">
<v-badge location="top right" color="#ff3300" dot class="cc-badge" :model-value="showRedDotBadge">
<v-btn class="info-button clickable" icon="$vuetify.icons.ic_share_settings" size="44" elevation="0"
color="black" @click.stop="showInformation" :disabled="currentAttachment?.status !== 'loaded'"></v-btn>
</v-badge>
@ -228,11 +228,17 @@ export default defineComponent({
}
return undefined;
},
anyContainsCC(): boolean {
return this.batch.attachments.some((a: Attachment) => a.proof?.integrity?.c2pa !== undefined);
showRedDotBadge(): boolean {
return this.currentAttachment && this.currentAttachment.proof?.integrity?.c2pa !== undefined && !this.currentAttachment.detailsViewed;
},
showCCIcon(): boolean {
return this.currentAttachment && this.currentAttachment.proof?.integrity?.c2pa !== undefined && !this.currentAttachment.useScaled;
},
currentlyViewedItem(): Attachment | undefined {
if (this.showAttachmentInformation) {
return this.currentAttachment;
}
return undefined;
}
},
watch: {
@ -247,6 +253,11 @@ export default defineComponent({
},
deep: 1,
},
currentlyViewedItem(newVal) {
if (newVal) {
newVal.detailsViewed = true; // We have seen this now
}
}
},
methods: {
showInformation() {

View file

@ -13,6 +13,8 @@
:contain="!previewOnly"
:cover="previewOnly"
:loadingProgress="loadingProgress"
ref="imageRef"
v-on:loaded="imageLoaded"
/>
<div v-else :class="{ 'thumbnail-item': true, preview: previewOnly, 'file-item': true, 'pdf-file': isPDF }">
<div class="pdf-container" v-if="showInlinePDF && isPDF">
@ -34,6 +36,10 @@
<div class="file-size">{{ fileSize }}</div>
</template>
</div>
<div :style="decoratorStyle" id="asdi">
<slot name="decorator"></slot>
</div>
</div>
</template>
@ -58,6 +64,7 @@ function isAttachment(source: EventAttachment | Attachment | undefined): source
const $$sanitize: any = inject("globalSanitize");
const thumbnailRef = useTemplateRef("thumbnailRef");
const imageRef = useTemplateRef("imageRef");
interface ThumbnailProps {
item?: EventAttachment | Attachment;
@ -78,6 +85,7 @@ let { isVideo, isImage, fileTypeIcon, fileTypeIconClass, fileName, fileSize, isP
const fileURL: Ref<string | undefined> = ref(undefined);
const source: Ref<string | undefined> = ref(undefined);
const poster: Ref<string | undefined> = ref(undefined);
const decoratorStyle: Ref<string | undefined> = ref(undefined);
const updateSource = () => {
if (isEventAttachment(props.item)) {
@ -130,6 +138,33 @@ const updatePoster = () => {
updateSource();
updatePoster();
const imageLoaded = (image: any) => {
if (imageRef.value) {
const rect = image.$el.getBoundingClientRect();
const nw = image.naturalWidth;
const nh = image.naturalHeight;
let t = 0;
let l = 0;
let w = 0;
let h = 0;
const wRatio = rect.width / rect.height;
const iRatio = nw / nh;
if (iRatio > wRatio) {
w = rect.width;
h = rect.width / iRatio;
} else {
w = rect.height * iRatio;
h = rect.height;
}
l = (rect.width - w) / 2;
t = (rect.height -h) / 2;
decoratorStyle.value = `position:absolute;top:${t}px;left:${l}px;width:${w}px;height:${h}px;display:flex;align-items:end;justify-content:end;padding:10px`;
}
}
watch(props, (props: ThumbnailProps) => {
const updates = useThumbnail(isEventAttachment(props.item) ? props.item.event : isAttachment(props.item) ? props.item.file : undefined);