Work on read markers
Don't update read marker for outgoing events (they might be local echoes etc).
This commit is contained in:
parent
ae09d3a78a
commit
7cf9d5b949
3 changed files with 107 additions and 25 deletions
|
|
@ -149,7 +149,7 @@
|
||||||
|
|
||||||
<v-col
|
<v-col
|
||||||
class="input-area-button text-center flex-grow-0 flex-shrink-1"
|
class="input-area-button text-center flex-grow-0 flex-shrink-1"
|
||||||
v-if="!currentInput || currentInput.length == 0"
|
v-if="!currentInput || currentInput.length == 0"
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
ref="mic_button"
|
ref="mic_button"
|
||||||
|
|
@ -158,7 +158,7 @@
|
||||||
elevation="0"
|
elevation="0"
|
||||||
color="transparent"
|
color="transparent"
|
||||||
v-blur
|
v-blur
|
||||||
style="z-index:10"
|
style="z-index: 10"
|
||||||
@touchstart.native.stop="startRecording"
|
@touchstart.native.stop="startRecording"
|
||||||
@mousedown.native.stop="startRecording"
|
@mousedown.native.stop="startRecording"
|
||||||
>
|
>
|
||||||
|
|
@ -166,8 +166,9 @@
|
||||||
</v-btn>
|
</v-btn>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
<v-col class="input-area-button text-center flex-grow-0 flex-shrink-1"
|
<v-col
|
||||||
v-else
|
class="input-area-button text-center flex-grow-0 flex-shrink-1"
|
||||||
|
v-else
|
||||||
>
|
>
|
||||||
<v-btn
|
<v-btn
|
||||||
fab
|
fab
|
||||||
|
|
@ -204,9 +205,13 @@
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</v-col>
|
</v-col>
|
||||||
|
|
||||||
</v-row>
|
</v-row>
|
||||||
<VoiceRecorder :micButtonRef="$refs.mic_button" :show="showRecorder" v-on:close="showRecorder = false" v-on:file="onVoiceRecording" />
|
<VoiceRecorder
|
||||||
|
:micButtonRef="$refs.mic_button"
|
||||||
|
:show="showRecorder"
|
||||||
|
v-on:close="showRecorder = false"
|
||||||
|
v-on:file="onVoiceRecording"
|
||||||
|
/>
|
||||||
</v-container>
|
</v-container>
|
||||||
|
|
||||||
<div v-if="currentImageInput">
|
<div v-if="currentImageInput">
|
||||||
|
|
@ -264,7 +269,12 @@
|
||||||
</v-dialog>
|
</v-dialog>
|
||||||
|
|
||||||
<!-- Loading indicator -->
|
<!-- Loading indicator -->
|
||||||
<v-container fluid fill-height style="position: absolute" v-if="!initialLoadDone">
|
<v-container
|
||||||
|
fluid
|
||||||
|
fill-height
|
||||||
|
style="position: absolute"
|
||||||
|
v-if="!initialLoadDone"
|
||||||
|
>
|
||||||
<v-row align="center" justify="center">
|
<v-row align="center" justify="center">
|
||||||
<v-col class="text-center">
|
<v-col class="text-center">
|
||||||
<v-progress-circular
|
<v-progress-circular
|
||||||
|
|
@ -291,6 +301,7 @@ import ContactInvited from "./messages/ContactInvited.vue";
|
||||||
import RoomNameChanged from "./messages/RoomNameChanged.vue";
|
import RoomNameChanged from "./messages/RoomNameChanged.vue";
|
||||||
import RoomTopicChanged from "./messages/RoomTopicChanged.vue";
|
import RoomTopicChanged from "./messages/RoomTopicChanged.vue";
|
||||||
import RoomAvatarChanged from "./messages/RoomAvatarChanged.vue";
|
import RoomAvatarChanged from "./messages/RoomAvatarChanged.vue";
|
||||||
|
import RoomHistoryVisibility from "./messages/RoomHistoryVisibility.vue";
|
||||||
import DebugEvent from "./messages/DebugEvent.vue";
|
import DebugEvent from "./messages/DebugEvent.vue";
|
||||||
import util from "../plugins/utils";
|
import util from "../plugins/utils";
|
||||||
import MessageOperations from "./messages/MessageOperations.vue";
|
import MessageOperations from "./messages/MessageOperations.vue";
|
||||||
|
|
@ -343,6 +354,7 @@ export default {
|
||||||
RoomNameChanged,
|
RoomNameChanged,
|
||||||
RoomTopicChanged,
|
RoomTopicChanged,
|
||||||
RoomAvatarChanged,
|
RoomAvatarChanged,
|
||||||
|
RoomHistoryVisibility,
|
||||||
DebugEvent,
|
DebugEvent,
|
||||||
MessageOperations,
|
MessageOperations,
|
||||||
VoiceRecorder
|
VoiceRecorder
|
||||||
|
|
@ -533,7 +545,7 @@ export default {
|
||||||
onRoomJoined(initialEventId) {
|
onRoomJoined(initialEventId) {
|
||||||
console.log("Read up to " + initialEventId);
|
console.log("Read up to " + initialEventId);
|
||||||
|
|
||||||
//initialEventId = null;
|
initialEventId = null;
|
||||||
|
|
||||||
this.timelineWindow = new TimelineWindow(
|
this.timelineWindow = new TimelineWindow(
|
||||||
this.$matrix.matrixClient,
|
this.$matrix.matrixClient,
|
||||||
|
|
@ -554,10 +566,10 @@ export default {
|
||||||
self.timelineWindow.canPaginate(EventTimeline.BACKWARDS)
|
self.timelineWindow.canPaginate(EventTimeline.BACKWARDS)
|
||||||
) {
|
) {
|
||||||
return self.timelineWindow
|
return self.timelineWindow
|
||||||
.paginate(EventTimeline.BACKWARDS, 10, true)
|
.paginate(EventTimeline.BACKWARDS, 10, true, 5)
|
||||||
.then((success) => {
|
.then((success) => {
|
||||||
|
self.events = self.timelineWindow.getEvents();
|
||||||
if (success) {
|
if (success) {
|
||||||
self.events = self.timelineWindow.getEvents();
|
|
||||||
return _getMoreIfNeeded.call(self);
|
return _getMoreIfNeeded.call(self);
|
||||||
} else {
|
} else {
|
||||||
return Promise.reject("Failed to paginate");
|
return Promise.reject("Failed to paginate");
|
||||||
|
|
@ -587,6 +599,7 @@ export default {
|
||||||
this.onRoomJoined(null);
|
this.onRoomJoined(null);
|
||||||
} else {
|
} else {
|
||||||
// Error. Done loading.
|
// Error. Done loading.
|
||||||
|
this.events = this.timelineWindow.getEvents();
|
||||||
this.initialLoadDone = true;
|
this.initialLoadDone = true;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -700,6 +713,9 @@ export default {
|
||||||
|
|
||||||
case "m.room.avatar":
|
case "m.room.avatar":
|
||||||
return RoomAvatarChanged;
|
return RoomAvatarChanged;
|
||||||
|
|
||||||
|
case "m.room.history_visibility":
|
||||||
|
return RoomHistoryVisibility;
|
||||||
}
|
}
|
||||||
return DebugEvent;
|
return DebugEvent;
|
||||||
},
|
},
|
||||||
|
|
@ -1039,7 +1055,7 @@ export default {
|
||||||
/** Stop Read Receipt timer */
|
/** Stop Read Receipt timer */
|
||||||
stopRRTimer() {
|
stopRRTimer() {
|
||||||
if (this.rrTimer) {
|
if (this.rrTimer) {
|
||||||
clearInterval(this.rrTimer);
|
clearTimeout(this.rrTimer);
|
||||||
this.rrTimer = null;
|
this.rrTimer = null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -1049,32 +1065,48 @@ export default {
|
||||||
*/
|
*/
|
||||||
restartRRTimer() {
|
restartRRTimer() {
|
||||||
this.stopRRTimer();
|
this.stopRRTimer();
|
||||||
this.rrTimer = setInterval(this.rrTimerElapsed, READ_RECEIPT_TIMEOUT);
|
this.rrTimer = setTimeout(this.rrTimerElapsed, READ_RECEIPT_TIMEOUT);
|
||||||
},
|
},
|
||||||
|
|
||||||
rrTimerElapsed() {
|
rrTimerElapsed() {
|
||||||
const container = this.$refs.chatContainer;
|
this.rrTimer = null;
|
||||||
const el = util.getLastVisibleElement(container);
|
|
||||||
if (el) {
|
|
||||||
const eventId = el.getAttribute("eventId");
|
|
||||||
if (eventId && this.room) {
|
|
||||||
const event = this.room.findEventById(eventId);
|
|
||||||
if (event && (!this.lastRR || event.getTs() > this.lastRR.getTs())) {
|
|
||||||
// Disable timer while we are sending
|
|
||||||
clearInterval(this.rrTimer);
|
|
||||||
this.rrTimer = null;
|
|
||||||
|
|
||||||
// Send read receipt
|
const container = this.$refs.chatContainer;
|
||||||
|
const elFirst = util.getFirstVisibleElement(container);
|
||||||
|
const elLast = util.getLastVisibleElement(container);
|
||||||
|
if (elFirst && elLast) {
|
||||||
|
const eventIdFirst = elFirst.getAttribute("eventId");
|
||||||
|
const eventIdLast = elLast.getAttribute("eventId");
|
||||||
|
if (eventIdLast && this.room) {
|
||||||
|
var event = this.room.findEventById(eventIdLast);
|
||||||
|
const index = this.events.indexOf(event);
|
||||||
|
|
||||||
|
// Walk backwards through visible events to the first one that is incoming
|
||||||
|
//
|
||||||
|
var lastTimestamp = 0;
|
||||||
|
if (this.lastRR) {
|
||||||
|
lastTimestamp = this.lastRR.getTs();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = index; i >= 0; i--) {
|
||||||
|
event = this.events[i];
|
||||||
|
if (event == this.lastRR || event.getTs() <= lastTimestamp) {
|
||||||
|
// Already sent this or too old...
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Is it an incoming event?
|
||||||
|
if (event.getSender() !== this.$matrix.currentUserId) {
|
||||||
|
// Send read receipt
|
||||||
this.$matrix.matrixClient
|
this.$matrix.matrixClient
|
||||||
.sendReadReceipt(event)
|
.sendReadReceipt(event)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
this.$matrix.matrixClient.setRoomReadMarkers(
|
this.$matrix.matrixClient.setRoomReadMarkers(
|
||||||
this.room.roomId,
|
this.room.roomId,
|
||||||
eventId
|
event.getId()
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.log("RR sent for event: " + eventId);
|
console.log("RR sent for event: " + event.getId());
|
||||||
this.lastRR = event;
|
this.lastRR = event;
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
|
@ -1083,9 +1115,17 @@ export default {
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
this.restartRRTimer();
|
this.restartRRTimer();
|
||||||
});
|
});
|
||||||
|
return; // Bail out here
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop iterating at first visible
|
||||||
|
if (event.getId() == eventIdFirst) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.restartRRTimer();
|
||||||
},
|
},
|
||||||
|
|
||||||
showDayMarkerBeforeEvent(event) {
|
showDayMarkerBeforeEvent(event) {
|
||||||
|
|
|
||||||
34
src/components/messages/RoomHistoryVisibility.vue
Normal file
34
src/components/messages/RoomHistoryVisibility.vue
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
<template>
|
||||||
|
<!-- ROOM AVATAR CHANGED -->
|
||||||
|
<div class="statusEvent">
|
||||||
|
{{ stateEventDisplayName(event) }} made room history {{ history(event) }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import messageMixin from "./messageMixin";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [messageMixin],
|
||||||
|
methods: {
|
||||||
|
history(event) {
|
||||||
|
const visibility = event.getContent().history_visibility;
|
||||||
|
switch (visibility) {
|
||||||
|
case "world_readable":
|
||||||
|
return "readable by anyone";
|
||||||
|
case "shared":
|
||||||
|
return "readable to all members in the room";
|
||||||
|
case "invited":
|
||||||
|
return "readable to members from when they were invited";
|
||||||
|
case "joined":
|
||||||
|
return "readable to members from when they joined";
|
||||||
|
}
|
||||||
|
return visibility;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "@/assets/css/chat.scss";
|
||||||
|
</style>
|
||||||
|
|
@ -348,9 +348,17 @@ class Util {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFirstVisibleElement(parentNode) {
|
||||||
|
const y = parentNode.scrollTop;
|
||||||
|
return this.getElementAtY(parentNode, y);
|
||||||
|
}
|
||||||
|
|
||||||
getLastVisibleElement(parentNode) {
|
getLastVisibleElement(parentNode) {
|
||||||
const y = parentNode.scrollTop + parentNode.clientHeight;
|
const y = parentNode.scrollTop + parentNode.clientHeight;
|
||||||
|
return this.getElementAtY(parentNode, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
getElementAtY(parentNode, y) {
|
||||||
let start = 0;
|
let start = 0;
|
||||||
let end = parentNode.children.length - 1;
|
let end = parentNode.children.length - 1;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue