Merge branch 'catch-component-errors' into 'dev'
Handle message rendering errors via the errorCaptured hook See merge request keanuapp/keanuapp-weblite!298
This commit is contained in:
commit
134b1f8cff
5 changed files with 68 additions and 34 deletions
|
|
@ -109,7 +109,8 @@
|
|||
"files": "Files",
|
||||
"images": "Images",
|
||||
"send_attachements_dialog_title": "Do you want to send following attachments ?",
|
||||
"download_all": "Download all"
|
||||
"download_all": "Download all",
|
||||
"failed_to_render": "Failed to render event"
|
||||
},
|
||||
"room": {
|
||||
"invitations": "You have no invitations | You have 1 invitation | You have {count} invitations",
|
||||
|
|
|
|||
|
|
@ -62,35 +62,37 @@
|
|||
<div v-if="showDayMarkerBeforeEvent(event) && !!componentForEvent(event, isForExport = false)" class="day-marker"><div class="line"></div><div class="text">{{ dayForEvent(event) }}</div><div class="line"></div></div>
|
||||
|
||||
<div v-if="!event.isRelation() && !event.isRedaction()" :ref="event.getId()">
|
||||
<div class="message-wrapper" v-on:touchstart="
|
||||
(e) => {
|
||||
touchStart(e, event);
|
||||
}
|
||||
" 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
|
||||
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="componentForEvent(event)" :room="room" :originalEvent="event" :nextEvent="filteredEvents[index + 1]"
|
||||
:timelineSet="timelineSet" v-on:send-quick-reaction.stop="sendQuickReaction"
|
||||
:componentFn="componentForEvent"
|
||||
v-on:context-menu="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)"
|
||||
v-on:poll-closed="pollWasClosed(event)"
|
||||
v-on:more="
|
||||
isEmojiQuickReaction = true
|
||||
showMoreMessageOperations({event: event, anchor: $event.anchor})
|
||||
"
|
||||
v-on:layout-change="onLayoutChange"
|
||||
v-on:addQuickHeartReaction="addQuickHeartReaction(event)"
|
||||
/>
|
||||
<!-- <div v-if="debugging" style="user-select:text">EventID: {{ event.getId() }}</div> -->
|
||||
<!-- <div v-if="debugging" style="user-select:text">Event: {{ JSON.stringify(event) }}</div> -->
|
||||
<div v-if="event.getId() == readMarker && index < filteredEvents.length - 1" class="read-marker"><div class="line"></div><div class="text">{{ $t('message.unread_messages') }}</div><div class="line"></div></div>
|
||||
</div>
|
||||
<MessageErrorHandler>
|
||||
<div class="message-wrapper" v-on:touchstart="
|
||||
(e) => {
|
||||
touchStart(e, event);
|
||||
}
|
||||
" 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
|
||||
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="componentForEvent(event)" :room="room" :originalEvent="event" :nextEvent="filteredEvents[index + 1]"
|
||||
:timelineSet="timelineSet" v-on:send-quick-reaction.stop="sendQuickReaction"
|
||||
:componentFn="componentForEvent"
|
||||
v-on:context-menu="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)"
|
||||
v-on:poll-closed="pollWasClosed(event)"
|
||||
v-on:more="
|
||||
isEmojiQuickReaction = true
|
||||
showMoreMessageOperations({event: event, anchor: $event.anchor})
|
||||
"
|
||||
v-on:layout-change="onLayoutChange"
|
||||
v-on:addQuickHeartReaction="addQuickHeartReaction(event)"
|
||||
/>
|
||||
<!-- <div v-if="debugging" style="user-select:text">EventID: {{ event.getId() }}</div> -->
|
||||
<!-- <div v-if="debugging" style="user-select:text">Event: {{ JSON.stringify(event) }}</div> -->
|
||||
<div v-if="event.getId() == readMarker && index < filteredEvents.length - 1" class="read-marker"><div class="line"></div><div class="text">{{ $t('message.unread_messages') }}</div><div class="line"></div></div>
|
||||
</div>
|
||||
</MessageErrorHandler>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -213,7 +215,7 @@
|
|||
</v-container>
|
||||
|
||||
<input ref="attachment" type="file" name="attachment" @change="handlePickedAttachment($event)"
|
||||
accept="image/*,audio/*,video/*,.pdf,application/pdf,.apk,application/vnd.android.package-archive,.ipa,.zip,application/zip,application/x-zip-compressed,multipart/x-zip" class="d-none" multiple/>
|
||||
accept="image/*,audio/*,video/*,.mp3,.mp4,.wav,.m4a,.pdf,application/pdf,.apk,application/vnd.android.package-archive,.ipa,.zip,application/zip,application/x-zip-compressed,multipart/x-zip" class="d-none" multiple/>
|
||||
|
||||
<div v-if="currentFileInputsDialog && !useFileModeNonAdmin">
|
||||
<v-dialog v-model="currentFileInputsDialog" class="ma-0 pa-0" :width="$vuetify.breakpoint.smAndUp ? '50%' : '85%'" persistent scrollable>
|
||||
|
|
@ -364,6 +366,7 @@ import FileDropLayout from "./file_mode/FileDropLayout";
|
|||
import roomTypeMixin from "./roomTypeMixin";
|
||||
import roomMembersMixin from "./roomMembersMixin";
|
||||
import PurgeRoomDialog from "../components/PurgeRoomDialog";
|
||||
import MessageErrorHandler from "./MessageErrorHandler";
|
||||
|
||||
const sizeOf = require("image-size");
|
||||
const dataUriToBuffer = require("data-uri-to-buffer");
|
||||
|
|
@ -417,7 +420,8 @@ export default {
|
|||
FileDropLayout,
|
||||
UserProfileDialog,
|
||||
PurgeRoomDialog,
|
||||
WelcomeHeaderChannelUser
|
||||
WelcomeHeaderChannelUser,
|
||||
MessageErrorHandler
|
||||
},
|
||||
|
||||
data() {
|
||||
|
|
|
|||
29
src/components/MessageErrorHandler.vue
Normal file
29
src/components/MessageErrorHandler.vue
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
<template>
|
||||
<div>
|
||||
<slot
|
||||
v-if="err"
|
||||
name="error"
|
||||
v-bind:err="err"
|
||||
><div class="text-center">{{ $t('message.failed_to_render') }}</div></slot>
|
||||
<slot v-else></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "MessageErrorHandler",
|
||||
data() {
|
||||
return {
|
||||
err: false,
|
||||
};
|
||||
},
|
||||
errorCaptured(err, ignoredvm, ignoredinfo) {
|
||||
this.err = err;
|
||||
return false;
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
</style>
|
||||
|
|
@ -27,7 +27,7 @@ export default {
|
|||
components: { MessageIncoming },
|
||||
data() {
|
||||
return {
|
||||
src: null,
|
||||
src: undefined,
|
||||
cover: true,
|
||||
contain: false,
|
||||
dialog: false
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export default {
|
|||
components: { MessageOutgoing },
|
||||
data() {
|
||||
return {
|
||||
src: null,
|
||||
src: undefined,
|
||||
cover: true,
|
||||
contain: false,
|
||||
dialog: false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue