Attachment info button

This commit is contained in:
N-Pex 2025-06-12 11:03:31 +02:00
parent a92d767fc2
commit bdca4ae3e3
5 changed files with 134 additions and 59 deletions

View file

@ -1617,17 +1617,4 @@ body {
.zip { .zip {
color: #1d1d1d; color: #1d1d1d;
} }
}
.c2pa-badge {
position: absolute;
top: 0;
right: 0;
width: 32px;
height: 32px;
overflow: hidden;
.v-icon {
width: 100%;
height: 100%;
}
} }

View file

@ -51,6 +51,14 @@ $hiliteColor: #4642f1;
z-index: 1; z-index: 1;
} }
.info-button {
position: absolute;
top: 16px;
right: 16px;
margin: 0;
z-index: 1;
}
.send-button { .send-button {
position: absolute; position: absolute;
top: 4px; top: 4px;
@ -123,8 +131,9 @@ $hiliteColor: #4642f1;
width: 12px; width: 12px;
height: 12px; height: 12px;
padding: 0; padding: 0;
min-width: 12px; min-width: 12px;
user-select: none; user-select: none;
span { span {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -417,4 +426,29 @@ $hiliteColor: #4642f1;
} }
} }
} }
}
.attachment-info {
text-align: start;
position: relative;
.attachment-info__size {
white-space: pre;
overflow: hidden;
margin-right: 36px;
text-overflow: ellipsis;
}
.attachment-info__size__filename {
opacity: 0.7;
font-size: 0.8em;
}
.c2pa-badge {
overflow: hidden;
.v-icon {
width: 32px;
height: 32px;
}
}
} }

View file

@ -1,45 +1,31 @@
<template> <template>
<div v-if="show" class="c2pa-badge"> <div v-if="hasC2PA" class="c2pa-badge">
<v-tooltip location="top"> <v-icon>$vuetify.icons.ic_cr</v-icon>
<template v-slot:activator="{ props }"> <span>This image contains C2PA data</span>
<v-icon v-bind="props" @click.stop="">$vuetify.icons.ic_cr</v-icon> </div>
</template> <div v-if="hasExif" class="c2pa-badge">
<span>This image contains C2PA data</span> <v-icon>camera_marker</v-icon>
</v-tooltip> <span>This image contains EXIF data</span>
</div> </div>
</template> </template>
<script lang="ts"> <script setup lang="ts">
import { defineComponent, PropType } from "vue"; import { computed } from "vue";
export default defineComponent({ const props = defineProps<{
name: "C2PABadge", proof?: {
emits: [], name?: string;
props: { json?: string;
proof: { integrity?: { pgp?: any; c2pa?: any; exif?: any; opentimestamps?: any };
type: Object as PropType<{ };
name?: string; }>();
json?: string;
integrity?: { pgp?: any; c2pa?: any; exif?: any; opentimestamps?: any }; const hasC2PA = computed(() => {
}>, return props.proof?.integrity?.c2pa !== undefined;
default: function () { });
return undefined;
}, const hasExif = computed(() => {
}, return props.proof?.integrity?.exif !== undefined;
},
computed: {
show() {
console.log("PROOFCHEKDATA", this.proof);
if (this.proof) {
const {
name,
json,
integrity: { pgp, c2pa, exif, opentimestamps },
} = this.proof;
return c2pa !== undefined;
}
},
},
}); });
</script> </script>

View file

@ -0,0 +1,50 @@
<template>
<div class="attachment-info">
<div class="attachment-info__size">
<span v-if="attachment.scaledFile && attachment.useScaled && attachment.scaledDimensions">
{{ attachment.scaledDimensions.width }} x {{ attachment.scaledDimensions.height }}</span
>
<span v-else-if="attachment.dimensions">
{{ attachment.dimensions.width }} x {{ attachment.dimensions.height }}
</span>
<span v-if="attachment.scaledFile && attachment.useScaled">
({{ formatBytes(attachment.scaledFile.size) }})
</span>
<span v-else> ({{ formatBytes(attachment.file.size) }}) </span>
<span class="attachment-info__size__filename" v-if="attachment.src && attachment.file.name">
- {{ attachment.file.name }}
</span>
</div>
<v-switch
v-if="attachment.scaledFile"
:label="$t('message.scale_image')"
v-model="attachment.useScaled"
:disabled="attachment.sendInfo !== undefined"
/>
<C2PABadge :proof="attachment.proof" />
</div>
</template>
<script setup lang="ts">
import { Attachment } from "../../models/attachment";
import prettyBytes from "pretty-bytes";
import C2PABadge from '../c2pa/C2PABadge.vue'
defineProps<{
attachment: Attachment;
}>();
const formatBytes = (bytes: number) => {
return prettyBytes(bytes);
};
</script>
<style lang="scss">
@use "@/assets/css/chat.scss" as *;
@use "@/assets/css/sendattachments.scss" as *;
</style>

View file

@ -31,14 +31,20 @@
<v-progress-linear indeterminate class="mb-0"></v-progress-linear> <v-progress-linear indeterminate class="mb-0"></v-progress-linear>
</div> </div>
</div> </div>
<v-btn
class="info-button clickable"
icon="information"
size="default"
elevation="0"
color="black"
@click.stop="showInformation"
></v-btn>
</div> </div>
<div class="file-drop-thumbnail-container"> <div class="file-drop-thumbnail-container">
<v-tooltip location="top" v-for="(attachment, index) in batch.attachments" :key="index"> <v-tooltip location="top" v-for="(attachment, index) in batch.attachments" :key="index">
<template v-slot:activator="{ props }"> <template v-slot:activator="{ props }">
<v-badge :model-value="batch.isTooLarge(attachment)" color="error"> <v-badge :model-value="batch.isTooLarge(attachment)" color="error">
<template v-slot:badge <template v-slot:badge><span v-bind="props">&nbsp;</span></template>
><span v-bind="props">&nbsp;</span></template
>
<div <div
:class="{ 'file-drop-thumbnail': true, clickable: true, current: index == currentItemIndex }" :class="{ 'file-drop-thumbnail': true, clickable: true, current: index == currentItemIndex }"
@click="currentItemIndex = index" @click="currentItemIndex = index"
@ -175,6 +181,14 @@
<v-btn class="close" @click.stop="close">{{ $t("file_mode.close") }}</v-btn> <v-btn class="close" @click.stop="close">{{ $t("file_mode.close") }}</v-btn>
</div> </div>
</template> </template>
<v-bottom-sheet v-model="showAttachmentInformation" theme="dark">
<v-card class="text-center">
<v-card-text>
<AttachmentInfo :attachment="currentAttachment" />
</v-card-text>
</v-card>
</v-bottom-sheet>
</div> </div>
</template> </template>
@ -185,10 +199,11 @@ import prettyBytes from "pretty-bytes";
import { Attachment } from "../../models/attachment"; import { Attachment } from "../../models/attachment";
import C2PABadge from "../c2pa/C2PABadge.vue"; import C2PABadge from "../c2pa/C2PABadge.vue";
import { createUploadBatch } from "../../models/attachmentManager"; import { createUploadBatch } from "../../models/attachmentManager";
import AttachmentInfo from "./AttachmentInfo.vue";
export default defineComponent({ export default defineComponent({
mixins: [messageMixin], mixins: [messageMixin],
components: { C2PABadge }, components: { C2PABadge, AttachmentInfo },
emits: ["pick-file", "close"], emits: ["pick-file", "close"],
props: { props: {
showBackButton: { showBackButton: {
@ -200,7 +215,7 @@ export default defineComponent({
batch: { batch: {
type: Object, type: Object,
default: function () { default: function () {
return reactive(createUploadBatch(null, null, 0)) return reactive(createUploadBatch(null, null, 0));
}, },
}, },
}, },
@ -215,6 +230,7 @@ export default defineComponent({
}), }),
status: 0, status: 0,
dropTarget: false, dropTarget: false,
showAttachmentInformation: false,
}; };
}, },
mounted() { mounted() {
@ -255,6 +271,11 @@ export default defineComponent({
}, },
}, },
methods: { methods: {
showInformation() {
if (this.currentAttachment) {
this.showAttachmentInformation = true;
}
},
filesDropped(e: DragEvent) { filesDropped(e: DragEvent) {
this.dropTarget = false; this.dropTarget = false;
let droppedFiles: FileList | undefined = e.dataTransfer?.files; let droppedFiles: FileList | undefined = e.dataTransfer?.files;
@ -264,9 +285,6 @@ export default defineComponent({
this.batch.addAttachment(this.$matrix.attachmentManager.createAttachment(file)); this.batch.addAttachment(this.$matrix.attachmentManager.createAttachment(file));
} }
}, },
formatBytes(bytes: number) {
return prettyBytes(bytes);
},
close() { close() {
this.batch.cancel(); this.batch.cancel();
this.status = this.mainStatuses.SELECTING; this.status = this.mainStatuses.SELECTING;