Emitted events not passed to child

Issue #665. So make sure wrapper messages don't emit MessageEmits. More info here: https://github.com/vuejs/rfcs/discussions/397.
This commit is contained in:
N-Pex 2025-07-15 12:10:35 +02:00
parent 33c6e7cb64
commit 0194339102
8 changed files with 27 additions and 28 deletions

View file

@ -86,14 +86,14 @@
" v-on:touchend="touchEnd" v-on:touchcancel="touchCancel" v-on:touchmove="touchMove">
<!-- Note: For threaded media messages, IF there is only one item we show that media item as a single component.
We might therefore get calls to v-on:context-menu that has the event set to that single media item, not the top level thread event
We might therefore get calls to v-on:contextMenu that has the event set to that single media item, not the top level thread event
that is really displayed in the flow. Therefore, we rewrite these events with "{event: event, anchor: $event.anchor}",
see below. Otherwise things like context menus won't work as designed.
-->
<component :is="event.component" :room="room" :originalEvent="event" :nextEvent="event.nextDisplayedEvent"
:timelineSet="timelineSet" v-on:send-quick-reaction="sendQuickReaction"
:componentFn="componentForEvent"
v-on:context-menu="showContextMenuForEvent({event: event, anchor: $event.anchor})"
v-on:contextMenu="showContextMenuForEvent({event: event, anchor: $event.anchor})"
v-on:own-avatar-clicked="viewProfile"
v-on:other-avatar-clicked="showAvatarMenuForEvent({event: event, anchor: $event.anchor})"
v-on:download="download(event)"

View file

@ -21,7 +21,7 @@ import MessageIncoming from "./MessageIncoming.vue";
import MessageOutgoing from "./MessageOutgoing.vue";
import ThumbnailView from "../../file_mode/ThumbnailView.vue";
import { useI18n } from "vue-i18n";
import { MessageEmits, MessageProps, useMessage } from "./useMessage";
import { MessageProps, useMessage } from "./useMessage";
import { KeanuEvent } from "../../../models/eventAttachment";
const { t } = useI18n();
@ -30,14 +30,14 @@ const $$sanitize: any = inject("globalSanitize");
const inOut: Ref<"in" | "out"> = ref("in");
const emits = defineEmits<MessageEmits & { (event: "download", value: KeanuEvent | undefined): void }>();
const emits = defineEmits<{ (event: "download", value: KeanuEvent | undefined): void }>();
const props = defineProps<MessageProps>();
const { event, isIncoming, attachment, inReplyToText, inReplyToSender, linkify } = useMessage(
$matrix,
t,
props,
emits,
undefined,
undefined
);

View file

@ -2,7 +2,8 @@
<component
:is="rootComponent"
ref="root"
v-bind="{ ...$props, ...$attrs }">
v-bind="{ ...$props, ...$attrs }"
>
<div class="bubble image-bubble" ref="imageRef">
<ImageWithProgress v-if="attachment"
:aspect-ratio="16 / 9"
@ -26,7 +27,7 @@ import MessageOutgoing from "./MessageOutgoing.vue";
import ImageWithProgress from "../../ImageWithProgress.vue";
import { useLazyLoad } from "./useLazyLoad";
import { useI18n } from "vue-i18n";
import { MessageEmits, MessageProps, useMessage } from "./useMessage";
import { MessageProps, useMessage } from "./useMessage";
import { EventAttachment } from "../../../models/eventAttachment";
import { useDisplay } from "vuetify";
import utils from "@/plugins/utils";
@ -39,7 +40,6 @@ type RootType = InstanceType<typeof MessageOutgoing | typeof MessageIncoming>
const rootRef = useTemplateRef<RootType>("root");
const imageRef = useTemplateRef("imageRef");
const emits = defineEmits<MessageEmits>();
const props = defineProps<MessageProps>();
const cover = ref(true);
@ -56,7 +56,7 @@ const {
event,
isIncoming,
attachment,
} = useMessage($matrix, t, props, emits, undefined);
} = useMessage($matrix, t, props, undefined, undefined);
const rootComponent = computed(() => {
return isIncoming.value ? MessageIncoming : MessageOutgoing;

View file

@ -57,7 +57,7 @@
<script setup lang="ts">
import MessageIncoming from "./MessageIncoming.vue";
import MessageOutgoing from "./MessageOutgoing.vue";
import { MessageEmits, MessageProps, useMessage } from "./useMessage";
import { MessageProps, useMessage } from "./useMessage";
import util, { ROOM_TYPE_CHANNEL, ROOM_TYPE_FILE_MODE } from "@/plugins/utils";
import GalleryItemsView from "../../file_mode/GalleryItemsView.vue";
import ThumbnailView from "../../file_mode/ThumbnailView.vue";
@ -75,7 +75,7 @@ const $$sanitize: any = inject('globalSanitize');
type RootType = InstanceType<typeof MessageOutgoing | typeof MessageIncoming>
const rootRef = useTemplateRef<RootType>("root");
const emits = defineEmits<MessageEmits & {(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<EventAttachment[]> = ref([]);
const showItem: Ref<EventAttachment | undefined> = ref(undefined);
@ -105,7 +105,7 @@ const {
messageText,
redactedBySomeoneElse,
linkify,
} = useMessage($matrix, t, props, emits, processThread);
} = useMessage($matrix, t, props, undefined, processThread);
const rootComponent = computed(() => {
return isIncoming.value ? MessageIncoming : MessageOutgoing;

View file

@ -42,9 +42,9 @@ import MessageIncoming from "./MessageIncoming.vue";
import MessageOutgoing from "./MessageOutgoing.vue";
import MessageIncomingText from "../MessageIncomingText.vue";
import MessageOutgoingText from "../MessageOutgoingText.vue";
import { MessageEmits, MessageProps, useMessage } from "./useMessage";
import { MessageProps, useMessage } from "./useMessage";
import util from "@/plugins/utils";
import { computed, inject, onBeforeUnmount, ref, Ref, watch, useAttrs } from "vue";
import { computed, inject, onBeforeUnmount, ref, Ref, watch } from "vue";
import { EventAttachment } from "../../../models/eventAttachment";
import { useI18n } from "vue-i18n";
import { MatrixEvent, MatrixEventEvent } from "matrix-js-sdk";
@ -53,7 +53,7 @@ const { t } = useI18n();
const $matrix: any = inject("globalMatrix");
const emits = defineEmits<
MessageEmits & { (event: "layout-change", value: { element: Element | undefined; action: () => void }): void } & {
{ (event: "layout-change", value: { element: Element | undefined; action: () => void }): void } & {
(event: "componentMounted", value: any): void;
}
>();
@ -74,7 +74,7 @@ const processThread = () => {
}
};
const { event, thread, isIncoming, messageText } = useMessage($matrix, t, props, emits, processThread);
const { event, thread, isIncoming, messageText } = useMessage($matrix, t, props, undefined, processThread);
const rootComponent = computed(() => {
return isIncoming.value ? MessageIncoming : MessageOutgoing;

View file

@ -43,7 +43,6 @@ const $matrix: any = inject('globalMatrix');
type RootType = InstanceType<typeof MessageOutgoing | typeof MessageIncoming>
const rootRef = useTemplateRef<RootType>("root");
const emits = defineEmits<MessageEmits>();
const props = defineProps<MessageProps>();
const {
@ -53,7 +52,7 @@ const {
const {
isIncoming,
attachment,
} = useMessage($matrix, t, props, emits, undefined);
} = useMessage($matrix, t, props, undefined, undefined);
const rootComponent = computed(() => {
return isIncoming.value ? MessageIncoming : MessageOutgoing;

View file

@ -19,8 +19,8 @@ export interface MessageProps {
}
export type MessageEmits = {
(event: "ownAvatarClicked", value: { event: KeanuEvent }): void;
(event: "otherAvatarClicked", value: { event: KeanuEvent; anchor: any }): void;
(event: "own-avatar-clicked", value: { event: KeanuEvent }): void;
(event: "other-avatar-clicked", value: { event: KeanuEvent; anchor: any }): void;
(event: "contextMenu", value: { event: KeanuEvent; anchor: any }): void;
(event: "addQuickHeartReaction", value: { position: { top: string; left: string } }): void;
};
@ -29,7 +29,7 @@ export const useMessage = (
$matrix: any,
$t: any,
props: MessageProps,
emits: MessageEmits,
emits?: MessageEmits,
processThread?: () => void
) => {
const event: Ref<KeanuEvent | undefined> = ref(undefined);
@ -216,19 +216,19 @@ export const useMessage = (
};
const ownAvatarClicked = () => {
if (event.value) {
emits("ownAvatarClicked", { event: event.value });
if (event.value && emits) {
emits("own-avatar-clicked", { event: event.value });
}
};
const otherAvatarClicked = (avatarRef: any) => {
if (event.value) {
emits("otherAvatarClicked", { event: event.value, anchor: avatarRef });
if (event.value && emits) {
emits("other-avatar-clicked", { event: event.value, anchor: avatarRef });
}
};
const showContextMenu = (buttonRef: any) => {
if (event.value) {
if (event.value && emits) {
emits("contextMenu", { event: event.value, anchor: buttonRef });
}
};
@ -350,7 +350,7 @@ export const useMessage = (
mcCustom.value.on("doubletap", (evt: Hammer.HammerInput) => {
var { top, left } = evt.target.getBoundingClientRect();
var position = { top: `${top}px`, left: `${left}px` };
emits("addQuickHeartReaction", { position });
if (emits) emits("addQuickHeartReaction", { position });
});
mc.value.on("press", () => {
showContextMenu(opbutton);

View file

@ -225,7 +225,7 @@ export default {
},
showContextMenu(buttonRef) {
this.$emit("context-menu", { event: this.event, anchor: buttonRef });
this.$emit("contextMenu", { event: this.event, anchor: buttonRef });
},
/**