More work on CC display
This commit is contained in:
parent
27b27876c0
commit
a27864e3d2
7 changed files with 45 additions and 20 deletions
|
|
@ -500,8 +500,6 @@
|
|||
"metadata_info_compressed": "Compressing the image automatically excludes its metadata.",
|
||||
"metadata_info_original": "Sharing the original automatically includes its metadata.",
|
||||
"exif_data": "Exif Data",
|
||||
"content_credentials": "Content Credentials",
|
||||
"content_credentials_info": "Source or history information is available for this media to be verified.",
|
||||
"learn_more": "Learn more",
|
||||
"ai_used": "Photo modified with AI",
|
||||
"screenshot": "Screenshot. ",
|
||||
|
|
@ -517,6 +515,8 @@
|
|||
"cc_location": "Location"
|
||||
},
|
||||
"cc": {
|
||||
"content_credentials": "Content Credentials",
|
||||
"content_credentials_info": "Source or history information is available for this media to be verified.",
|
||||
"metadata-stripped": "Image has been compressed and stripped of metadata.\n\nWe think this image has additional file information. If you want to learn more, ask the sender to share the original."
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<div v-if="props.flags">
|
||||
<div class="detail-title">
|
||||
{{ t("file_mode.content_credentials") }}
|
||||
{{ t("cc.content_credentials") }}
|
||||
<v-icon>$vuetify.icons.ic_cr</v-icon>
|
||||
</div>
|
||||
<div class="detail-subtitle">
|
||||
{{ t("file_mode.content_credentials_info") }}
|
||||
<div class="detail-subtitle" v-if="hasC2PA">
|
||||
{{ t("cc.content_credentials_info") }}
|
||||
</div>
|
||||
|
||||
<div class="cc-detail-info" v-if="infoText !== undefined">
|
||||
|
|
@ -29,8 +29,8 @@
|
|||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { ProofHintFlags } from "../../models/proof";
|
||||
import { ref, Ref, watch } from "vue";
|
||||
import { Proof, ProofHintFlags } from "../../models/proof";
|
||||
import { computed, ref, Ref, watch } from "vue";
|
||||
import dayjs from "dayjs";
|
||||
import CCProperty from "./CCProperty.vue";
|
||||
import relativeTime from "dayjs/plugin/relativeTime";
|
||||
|
|
@ -40,6 +40,7 @@ dayjs.extend(relativeTime);
|
|||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps<{
|
||||
proof?: Proof;
|
||||
flags?: ProofHintFlags;
|
||||
}>();
|
||||
|
||||
|
|
@ -47,6 +48,10 @@ const infoText: Ref<string | undefined> = ref(undefined);
|
|||
const creationDate: Ref<string | undefined> = ref(undefined);
|
||||
const valid: Ref<boolean> = ref(false);
|
||||
|
||||
const hasC2PA = computed(() => {
|
||||
return props.proof?.integrity?.c2pa !== undefined;
|
||||
});
|
||||
|
||||
watch(
|
||||
props,
|
||||
() => {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="cc-summary" v-if="props.flags.length > 0 && infoText.length > 0">
|
||||
<div class="cc-summary" v-if="flags.length > 0 && infoText.length > 0">
|
||||
<v-icon class="intervention-icon">{{
|
||||
showCheck ? "$vuetify.icons.ic_intervention_check" : "$vuetify.icons.ic_intervention"
|
||||
}}</v-icon
|
||||
|
|
@ -11,18 +11,30 @@
|
|||
import { computed } from "vue";
|
||||
import { ProofHintFlags } from "../../models/proof";
|
||||
|
||||
const props = defineProps<{
|
||||
const { multiple, flags } = defineProps<{
|
||||
multiple: boolean;
|
||||
flags: ProofHintFlags[];
|
||||
}>();
|
||||
|
||||
const showCheck = computed(() => {
|
||||
return props.flags.some((f) => f?.valid);
|
||||
if (!multiple && flags.length == 1) {
|
||||
return flags[0].generatorSource === "c2pa";
|
||||
} else if (multiple) {
|
||||
return flags.some((f) => f.generatorSource === "c2pa")
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
const infoText = computed(() => {
|
||||
if (props.flags.some((f) => f.generator === "ai")) {
|
||||
if (!multiple && flags.length == 1) {
|
||||
if (flags[0].generator === "ai") {
|
||||
return "<b>This image is generated by AI.</b> Take a closer look at the file details.";
|
||||
} else if (flags[0].generator === "screenshot") {
|
||||
return "<b>This is a screenshot.</b> Take a closer look at the file details.";
|
||||
}
|
||||
} else if (flags.some((f) => f.generator === "ai")) {
|
||||
return "<b>Contains AI generated media.</b> Take a closer look at the file details for each.";
|
||||
} else if (props.flags.some((f) => f.generator === "screenshot")) {
|
||||
} else if (flags.some((f) => f.generator === "screenshot")) {
|
||||
return "<b>Contains screenshots.</b> Take a closer look at the file details for each.";
|
||||
}
|
||||
return "TODO - Content Credentials Info";
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<C2PAInfo class="attachment-info__detail-box" v-if="hasC2PA" :flags="attachment.proofHintFlags" />
|
||||
<C2PAInfo class="attachment-info__detail-box" v-if="showC2PAInfo" :proof="attachment.proof" :flags="attachment.proofHintFlags" />
|
||||
<EXIFInfo class="attachment-info__detail-box" v-if="hasExif" :exif="attachment.proof?.integrity?.exif" />
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -49,8 +49,8 @@ const { attachment } = defineProps<{
|
|||
|
||||
//console.error("ATTACHMENT", attachment.proof);
|
||||
|
||||
const hasC2PA = computed(() => {
|
||||
return attachment.proof?.integrity?.c2pa !== undefined;
|
||||
const showC2PAInfo = computed(() => {
|
||||
return attachment.proof?.integrity?.c2pa !== undefined || attachment.proofHintFlags !== undefined;
|
||||
});
|
||||
|
||||
const hasExif = computed(() => {
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@
|
|||
<v-progress-circular indeterminate class="mb-0"></v-progress-circular>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else-if="metaStripped" class="cc-detail-info white-space-pre">{{ t("cc.metadata-stripped") }}</div>
|
||||
<div v-else>
|
||||
<C2PAInfo class="attachment-info__detail-box" v-if="hasC2PA" :flags="attachment?.proofHintFlags" />
|
||||
<div v-if="metaStripped" class="cc-detail-info white-space-pre">{{ t("cc.metadata-stripped") }}</div>
|
||||
<C2PAInfo class="attachment-info__detail-box" :proof="attachment?.proof" :flags="attachment?.proofHintFlags" />
|
||||
<EXIFInfo class="attachment-info__detail-box" v-if="hasExif" :exif="attachment?.proof?.integrity?.exif" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<component :is="rootComponent" ref="root" v-bind="{ ...$props, ...$attrs }" v-if="showMultiview">
|
||||
<div class="bubble">
|
||||
<div class="bubble-inset" v-if="showCCSummary"><CCSummary :flags="proofHintFlags" /></div>
|
||||
<div class="bubble-inset" v-if="showCCSummary"><CCSummary :multiple="items.length > 1" :flags="proofHintFlags" /></div>
|
||||
<div class="original-message bubble-inset" v-if="inReplyToText">
|
||||
<div class="original-message-sender">{{ inReplyToSender }}</div>
|
||||
<div class="original-message-text" v-html="linkify($$sanitize(inReplyToText))" />
|
||||
|
|
@ -158,7 +158,7 @@ const showMultiview = computed((): boolean => {
|
|||
});
|
||||
|
||||
const showCCSummary = computed(() => {
|
||||
return items.value?.some((i) => i.proofHintFlags !== undefined && i.proofHintFlags.valid);
|
||||
return items.value?.some((i) => i.proofHintFlags !== undefined);
|
||||
});
|
||||
|
||||
const proofHintFlags = computed(() => {
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ const ruleAiGenerated = (): FlagMatchRule[] => {
|
|||
];
|
||||
};
|
||||
|
||||
const aiHintFlags = (): FlagMatchRule[] => {
|
||||
const ruleAiMeta = (): FlagMatchRule[] => {
|
||||
const knownAIServices = [
|
||||
"ChatGPT",
|
||||
"OpenAI-API",
|
||||
|
|
@ -292,9 +292,17 @@ export const extractProofHintFlags = (proof?: Proof): ProofHintFlags | undefined
|
|||
if (matchFlag(ruleScreenshotMeta(), proof).result) {
|
||||
generator = "screenshot";
|
||||
generatorSource = "metadata";
|
||||
} else if (matchFlag(ruleAiMeta(), proof).result) {
|
||||
generator = "ai";
|
||||
generatorSource = "metadata";
|
||||
}
|
||||
}
|
||||
|
||||
// Do we have any data? Else, return "undefined", we don't just want to send an object with all defaults.
|
||||
if (source.length === 0 && dateCreated.length === 0 && generator === "unknown") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const flags: ProofHintFlags = {
|
||||
valid: valid,
|
||||
device: source && source.length == 1 ? source[0].value : undefined,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue