diff --git a/package-lock.json b/package-lock.json index 2fc0bde..685198d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "keanuapp-weblite", - "version": "0.1.59", + "version": "0.1.70", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "keanuapp-weblite", - "version": "0.1.59", + "version": "0.1.70", "dependencies": { "@guardianproject/proofmode": "^0.4.0", "@matrix-org/olm": "^3.2.12", @@ -3073,12 +3073,16 @@ } }, "node_modules/cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", + "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", + "license": "MIT", "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1" + }, + "engines": { + "node": ">= 0.10" } }, "node_modules/clean-insights-sdk": { @@ -6535,15 +6539,23 @@ "dev": true }, "node_modules/sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", + "license": "(MIT AND BSD-3-Clause)", "dependencies": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" }, "bin": { "sha.js": "bin.js" + }, + "engines": { + "node": ">= 0.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/shebang-command": { @@ -7367,9 +7379,9 @@ "dev": true }, "node_modules/vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "6.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.6.tgz", + "integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==", "license": "MIT", "dependencies": { "esbuild": "^0.25.0", @@ -7441,9 +7453,9 @@ } }, "node_modules/vite-plugin-static-copy": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.3.0.tgz", - "integrity": "sha512-LLKwhhHetGaCnWz4mas4qqjjguDka6/6b4+SeIohRroj8aCE7QTfiZECfPecslFQkWZ3HdQuq5kOPmWZjNYlKA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.3.2.tgz", + "integrity": "sha512-iwrrf+JupY4b9stBttRWzGHzZbeMjAHBhkrn67MNACXJVjEMRpCI10Q3AkxdBkl45IHaTfw/CNVevzQhP7yTwg==", "dev": true, "license": "MIT", "dependencies": { @@ -9914,12 +9926,12 @@ "peer": true }, "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.6.tgz", + "integrity": "sha512-3Ek9H3X6pj5TgenXYtNWdaBon1tgYCaebd+XPg0keyjEbEfkD4KkmAxkQ/i1vYvxdcT5nscLBfq9VJRmCBcFSw==", "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1" } }, "clean-insights-sdk": { @@ -12358,12 +12370,13 @@ "dev": true }, "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "version": "2.4.12", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.12.tgz", + "integrity": "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==", "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "^2.0.4", + "safe-buffer": "^5.2.1", + "to-buffer": "^1.2.0" } }, "shebang-command": { @@ -12921,9 +12934,9 @@ "dev": true }, "vite": { - "version": "6.3.5", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", - "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "version": "6.3.6", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.6.tgz", + "integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==", "requires": { "esbuild": "^0.25.0", "fdir": "^6.4.4", @@ -12948,9 +12961,9 @@ } }, "vite-plugin-static-copy": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.3.0.tgz", - "integrity": "sha512-LLKwhhHetGaCnWz4mas4qqjjguDka6/6b4+SeIohRroj8aCE7QTfiZECfPecslFQkWZ3HdQuq5kOPmWZjNYlKA==", + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-2.3.2.tgz", + "integrity": "sha512-iwrrf+JupY4b9stBttRWzGHzZbeMjAHBhkrn67MNACXJVjEMRpCI10Q3AkxdBkl45IHaTfw/CNVevzQhP7yTwg==", "dev": true, "requires": { "chokidar": "^3.5.3", diff --git a/package.json b/package.json index c659d3d..646fe36 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keanuapp-weblite", - "version": "0.1.68", + "version": "0.1.72", "private": true, "scripts": { "dev": "vite", diff --git a/package.json.bak b/package.json.bak index 793cb18..852555b 100644 --- a/package.json.bak +++ b/package.json.bak @@ -1,6 +1,6 @@ { "name": "keanuapp-weblite", - "version": "0.1.67", + "version": "0.1.71", "private": true, "scripts": { "dev": "vite", diff --git a/src/assets/css/chat.scss b/src/assets/css/chat.scss index fbb47f7..c1a941d 100644 --- a/src/assets/css/chat.scss +++ b/src/assets/css/chat.scss @@ -132,6 +132,7 @@ body { .icon-dropdown { margin: 0px 8px; + color: var(--v-foreground-color); } .notification-alert { @@ -467,6 +468,10 @@ body { position: relative; max-width: 70%; + .bubble-inset { + padding: 8px 8px; + } + @media #{map.get($display-breakpoints, 'sm-and-down')} { min-height: $min-touch-target; } @@ -561,6 +566,10 @@ body { position: relative; max-width: 70%; + .bubble-inset { + padding: 8px 8px; + } + @media #{map.get($display-breakpoints, 'sm-and-down')} { min-height: $min-touch-target; } diff --git a/src/assets/css/contentcredentials.scss b/src/assets/css/contentcredentials.scss new file mode 100644 index 0000000..ace2182 --- /dev/null +++ b/src/assets/css/contentcredentials.scss @@ -0,0 +1,13 @@ + .cc-detail-info { + color: #333333; + background-color: #DAD9FC; + padding: 16px; + margin: 16px 0 16px 0; + border-radius: 8px 8px 0 8px; + font-family: "Inter", sans-serif; + font-weight: 400; + font-size: 14px; + line-height: 125%; + letter-spacing: 0.4px; + vertical-align: middle; + } \ No newline at end of file diff --git a/src/assets/css/sendattachments.scss b/src/assets/css/sendattachments.scss index 4ffd699..4ce3301 100644 --- a/src/assets/css/sendattachments.scss +++ b/src/assets/css/sendattachments.scss @@ -482,7 +482,8 @@ $hiliteColor: #4642f1; } .send-attachments-info-popup { - background-color: rgba(0, 0, 0, 0.9); + background-color: rgba(0, 0, 0, 0.8); + border-radius: 24px 24px 0 0; .done-button { padding: 14px 24px; @@ -629,9 +630,29 @@ $hiliteColor: #4642f1; line-height: 125%; letter-spacing: 0.4px; color: rgba(255, 255, 255, 0.9); + display: flex; .v-icon { + padding: 9.33px; margin-right: 8px; + width: 32px; + height: 32px; + background-color: black; + } + + .detail-row__text { + display: flex; + flex-direction: column; + } + + .detail-row__title { + color: #dad9fc; + font-family: "Inter", sans-serif; + font-weight: 400; + font-size: 12px; + line-height: 125%; + letter-spacing: 0.4px; + vertical-align: middle; } } } diff --git a/src/assets/css/typography.scss b/src/assets/css/typography.scss index 76bc975..1231033 100644 --- a/src/assets/css/typography.scss +++ b/src/assets/css/typography.scss @@ -74,3 +74,16 @@ text-decoration-skip-ink: none; color: rgba(0,0,0,0.60); } + +.common-caption-small { + font-family: "Inter"; + font-size: 12 * $chat-text-size; + font-weight: 400; + font-style: italic; + line-height: 125%; + letter-spacing: 0.40 * $chat-text-size; + text-align: left; + text-underline-position: from-font; + text-decoration-skip-ink: none; + color: #545F71; +} diff --git a/src/assets/icons/ic_dropdown.vue b/src/assets/icons/ic_dropdown.vue index 1e2510a..3983266 100644 --- a/src/assets/icons/ic_dropdown.vue +++ b/src/assets/icons/ic_dropdown.vue @@ -2,6 +2,11 @@ + /> - \ No newline at end of file + + \ No newline at end of file diff --git a/src/assets/icons/ic_intervention.vue b/src/assets/icons/ic_intervention.vue new file mode 100644 index 0000000..ed977ea --- /dev/null +++ b/src/assets/icons/ic_intervention.vue @@ -0,0 +1,23 @@ + diff --git a/src/assets/icons/ic_intervention_check.vue b/src/assets/icons/ic_intervention_check.vue new file mode 100644 index 0000000..904f86b --- /dev/null +++ b/src/assets/icons/ic_intervention_check.vue @@ -0,0 +1,23 @@ + diff --git a/src/assets/translations/en.json b/src/assets/translations/en.json index ab3763e..1f10929 100644 --- a/src/assets/translations/en.json +++ b/src/assets/translations/en.json @@ -500,12 +500,23 @@ "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. ", "screenshot_taken_on": "Screenshot taken on {date}", - "captured_with_camera": "Captured with a camera", - "old_photo": "Photo older than 3 months" + "captured_with_camera": "Captured with a real camera. ", + "captured_screenshot": "Screenshot. ", + "captured_screenshot_ago": "Screenshot captured {ago} ago. ", + "generated_with_ai": "Generated with AI. ", + "generated_with_ai_ago": "Generated with AI {ago} ago. ", + "old_photo": "Photo older than 3 months. ", + "cc_source": "Source", + "cc_capture_timestamp": "Capture Timestamp", + "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." } } diff --git a/src/components/RoomExport.vue b/src/components/RoomExport.vue index c9728a4..eda85df 100644 --- a/src/components/RoomExport.vue +++ b/src/components/RoomExport.vue @@ -393,6 +393,7 @@ export default { break; case "image/gif": extension = ".gif"; + break; } let fileName = event.getId() + extension; @@ -407,6 +408,14 @@ export default { } } else if (mime.startsWith("audio/")) { var extension = ".webm"; + switch (mime) { + case "audio/mpeg": + extension = ".mp3"; + break; + case "audio/x-m4a": + extension = ".m4a"; + break; + } let fileName = event.getId() + extension; audioFolder.file(fileName, blob); // TODO calc bytes let elements = comp.el.getElementsByTagName("audio"); diff --git a/src/components/chatMixin.js b/src/components/chatMixin.js index 29beffd..85bee75 100644 --- a/src/components/chatMixin.js +++ b/src/components/chatMixin.js @@ -198,7 +198,7 @@ export default { if (isForExport) { return MessageIncomingImageExport; } - return MessageImage; + return MessageThread; } else if (event.getContent().msgtype == "m.audio") { if (isForExport) { return MessageIncomingAudioExport; @@ -208,7 +208,7 @@ export default { if (isForExport) { return MessageIncomingVideoExport; } - return MessageVideo; + return MessageThread; } else if (event.getContent().msgtype == "m.file") { if (isForExport) { return MessageIncomingFileExport; @@ -245,7 +245,7 @@ export default { if (isForExport) { return MessageOutgoingImageExport; } - return MessageImage; + return MessageThread; } else if (event.getContent().msgtype == "m.audio") { if (isForExport) { return MessageOutgoingAudioExport; @@ -255,7 +255,7 @@ export default { if (isForExport) { return MessageOutgoingVideoExport; } - return MessageVideo; + return MessageThread; } else if (event.getContent().msgtype == "m.file") { if (isForExport) { return MessageOutgoingFileExport; diff --git a/src/components/content-credentials/C2PAInfo.vue b/src/components/content-credentials/C2PAInfo.vue index 4df016b..bbd9a46 100644 --- a/src/components/content-credentials/C2PAInfo.vue +++ b/src/components/content-credentials/C2PAInfo.vue @@ -1,134 +1,98 @@ diff --git a/src/components/content-credentials/CCProperty.vue b/src/components/content-credentials/CCProperty.vue new file mode 100644 index 0000000..0352151 --- /dev/null +++ b/src/components/content-credentials/CCProperty.vue @@ -0,0 +1,23 @@ + + + + + diff --git a/src/components/content-credentials/CCSummary.vue b/src/components/content-credentials/CCSummary.vue new file mode 100644 index 0000000..c9832da --- /dev/null +++ b/src/components/content-credentials/CCSummary.vue @@ -0,0 +1,55 @@ + + + + + diff --git a/src/components/content-credentials/EXIFInfo.vue b/src/components/content-credentials/EXIFInfo.vue index 5f3b32f..2ec59d7 100644 --- a/src/components/content-credentials/EXIFInfo.vue +++ b/src/components/content-credentials/EXIFInfo.vue @@ -3,16 +3,13 @@
{{ t("file_mode.exif_data") }}
-
- $vuetify.icons.ic_exif_time{{ dateTime }} -
-
- $vuetify.icons.ic_exif_location{{ location }} -
-
- $vuetify.icons.ic_exif_device_camera{{ makeAndModel }} -
- + + + + + @@ -20,6 +17,7 @@ import { computed } from "vue"; import dayjs from "dayjs"; import { useI18n } from "vue-i18n"; +import CCProperty from "./CCProperty.vue"; const { t } = useI18n(); diff --git a/src/components/file_mode/AttachmentInfo.vue b/src/components/file_mode/AttachmentInfo.vue index 2fdfa91..87ee095 100644 --- a/src/components/file_mode/AttachmentInfo.vue +++ b/src/components/file_mode/AttachmentInfo.vue @@ -28,7 +28,7 @@ - + @@ -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(() => { diff --git a/src/components/file_mode/EventAttachmentInfo.vue b/src/components/file_mode/EventAttachmentInfo.vue new file mode 100644 index 0000000..ba36e83 --- /dev/null +++ b/src/components/file_mode/EventAttachmentInfo.vue @@ -0,0 +1,71 @@ + + + + + diff --git a/src/components/file_mode/GalleryItemsView.vue b/src/components/file_mode/GalleryItemsView.vue index 82dd87e..2c0494e 100644 --- a/src/components/file_mode/GalleryItemsView.vue +++ b/src/components/file_mode/GalleryItemsView.vue @@ -1,108 +1,125 @@ - \ No newline at end of file + diff --git a/src/components/file_mode/ThumbnailView.vue b/src/components/file_mode/ThumbnailView.vue index c405a3d..7922ee4 100644 --- a/src/components/file_mode/ThumbnailView.vue +++ b/src/components/file_mode/ThumbnailView.vue @@ -64,7 +64,7 @@ const poster: Ref = ref(undefined); const updateSource = () => { if (isEventAttachment(props.item)) { const eventAttachment = props.item; - if (isVideo.value || eventAttachment.src) { + if (eventAttachment.src) { source.value = eventAttachment.src; } else if (previewOnly) { eventAttachment.loadThumbnail().then((url) => { @@ -74,6 +74,10 @@ const updateSource = () => { eventAttachment.loadSrc().then((url) => { source.value = url.data; }) + } else if (isVideo.value) { + eventAttachment.loadSrc().then((url) => { + source.value = url.data; + }) } } else if (isAttachment(props.item)) { const attachment = props.item; diff --git a/src/components/messages/composition/MessageImage.vue b/src/components/messages/composition/MessageImage.vue index 9c828ef..b4cf1d5 100644 --- a/src/components/messages/composition/MessageImage.vue +++ b/src/components/messages/composition/MessageImage.vue @@ -5,6 +5,10 @@ v-bind="{ ...$props, ...$attrs }" >
+
+ +
+ - +
-
+
+ +
+
{{ inReplyToSender }}
@@ -18,24 +16,26 @@ v-bind="$attrs" /> - - + + - - block - {{ - redactedBySomeoneElse(event) - ? $t("message.incoming_message_deleted_text") - : $t("message.outgoing_message_deleted_text") - }} - - - - {{ t("message.edited") }} - +
+ + block + {{ + redactedBySomeoneElse(event) + ? $t("message.incoming_message_deleted_text") + : $t("message.outgoing_message_deleted_text") + }} + + + + {{ t("message.edited") }} + +
+type RootType = InstanceType; const rootRef = useTemplateRef("root"); -const emits = defineEmits<{(event: "layout-change", value: {element: Element | undefined, action: () => void}): void}>(); +const emits = defineEmits<{ + (event: "layout-change", value: { element: Element | undefined; action: () => void }): void; +}>(); const items: Ref = ref([]); const showItem: Ref = ref(undefined); @@ -87,13 +91,11 @@ const { room } = props; const processThread = () => { if (!event.value?.isRedacted()) { const el = rootRef.value?.$el; - emits("layout-change", {element: el, action: _processThread}); + emits("layout-change", { element: el, action: _processThread }); } }; -const { - isVisible -} = useLazyLoad({ root: rootRef }); +const { isVisible } = useLazyLoad({ root: rootRef }); const { event, @@ -108,8 +110,8 @@ const { } = useMessage($matrix, t, props, undefined, processThread); const rootComponent = computed(() => { - return isIncoming.value ? MessageIncoming : MessageOutgoing; -}) + return isIncoming.value ? MessageIncoming : MessageOutgoing; +}); const onRelationsCreated = () => { if (event.value) { @@ -122,31 +124,71 @@ const onRelationsCreated = () => { } }; -watch(event, () => { - if (event.value) { - if (thread.value === undefined) { - thread.value = props.timelineSet.relations.getChildEventsForEvent( - event.value.getId() ?? "", - util.threadMessageType(), - "m.room.message" - ); +watch( + event, + () => { + if (event.value) { + if (["m.image", "m.video"].includes(event.value.getContent().msgtype ?? "")) { + // Single image mode + items.value = [event.value].map((e: MatrixEvent) => { + let ea = $matrix.attachmentManager.getEventAttachment(e); + if (isVisible.value) { + ea.loadThumbnail(); + } + return ea; + }); + } else if (thread.value === undefined) { + thread.value = props.timelineSet.relations.getChildEventsForEvent( + event.value.getId() ?? "", + util.threadMessageType(), + "m.room.message" + ); + } + if (!thread.value) { + event.value.on(MatrixEventEvent.RelationsCreated, onRelationsCreated); + } } - if (!thread.value) { - event.value.on(MatrixEventEvent.RelationsCreated, onRelationsCreated); - } - } -}, { immediate: true}); + }, + { immediate: true } +); onBeforeUnmount(() => { event.value?.off(MatrixEventEvent.RelationsCreated, onRelationsCreated); }); +const showMessageText = computed((): boolean => { + if (["m.image", "m.video"].includes(event.value?.getContent().msgtype ?? "")) { + return false; + } + return true; +}); + const showMultiview = computed((): boolean => { - return (isIncoming.value && props.room.displayType == ROOM_TYPE_FILE_MODE) || - items.value?.length > 1 || - (event.value && event.value.isRedacted()) || - (props.room.displayType == ROOM_TYPE_CHANNEL && items.value.length == 1 && util.isFileTypePDF(items.value[0].event)) || + if (["m.image", "m.video"].includes(event.value?.getContent().msgtype ?? "")) { + return true; + } + return ( + (isIncoming.value && props.room.displayType == ROOM_TYPE_FILE_MODE) || + items.value?.length > 1 || + (event.value && event.value.isRedacted()) || + (props.room.displayType == ROOM_TYPE_CHANNEL && + items.value.length == 1 && + util.isFileTypePDF(items.value[0].event)) || messageText.value?.length > 0 + ); +}); + +const showCCSummary = computed(() => { + return items.value?.some((i) => i.proofHintFlags !== undefined); +}); + +const proofHintFlags = computed(() => { + return items.value.reduce((res: ProofHintFlags[], item) => { + if (item.proofHintFlags) { + res.push(item.proofHintFlags); + } + return res; + }, []); }); watch(isVisible, (visible) => { @@ -190,9 +232,9 @@ const layoutedItems = computed(() => { rows.push({ size: 3, item: array[6] }); array = array.slice(7); } else if (array.length >= 3) { - rows.push({ size: 6, item: array[0] }); + rows.push({ size: 12, item: array[0] }); rows.push({ size: 6, item: array[1] }); - rows.push({ size: 12, item: array[2] }); + rows.push({ size: 6, item: array[2] }); array = array.slice(3); } else if (array.length >= 2) { rows.push({ size: 6, item: array[0] }); @@ -205,7 +247,6 @@ const layoutedItems = computed(() => { } return rows; }); -