Fixes for "scroll to latest"
This commit is contained in:
parent
e3f7f1758f
commit
f0382afd83
2 changed files with 54 additions and 35 deletions
|
|
@ -369,10 +369,16 @@ body {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 102px;
|
bottom: 102px;
|
||||||
right: 16px;
|
right: 16px;
|
||||||
|
opacity: 1;
|
||||||
|
transition: opacity 0.3s linear;
|
||||||
&.reversed {
|
&.reversed {
|
||||||
top: 120px;
|
top: 120px;
|
||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
|
&.hidden {
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.op-button {
|
.op-button {
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- "Scroll to end"-button -->
|
<!-- "Scroll to end"-button -->
|
||||||
<v-btn v-if="!useVoiceMode" icon="arrow_downward" :class="{'scroll-to-end': true, 'reversed': reverseOrder}" v-show="showScrollToEnd" theme="dark" size="x-small" elevation="0" color="black"
|
<v-btn v-if="!useVoiceMode" icon="arrow_downward" :class="{'scroll-to-end': true, 'reversed': reverseOrder, 'hidden': !showScrollToEnd}" theme="dark" size="x-small" elevation="0" color="black"
|
||||||
@click.stop="scrollToEndOfTimeline">
|
@click.stop="scrollToEndOfTimeline">
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
|
|
@ -410,6 +410,7 @@ export default {
|
||||||
timelineWindowPaginating: false,
|
timelineWindowPaginating: false,
|
||||||
|
|
||||||
scrollPosition: null,
|
scrollPosition: null,
|
||||||
|
scrollUpdateTimer: null,
|
||||||
uploadBatch: undefined,
|
uploadBatch: undefined,
|
||||||
showEmojiPicker: false,
|
showEmojiPicker: false,
|
||||||
selectedEvent: null,
|
selectedEvent: null,
|
||||||
|
|
@ -1210,13 +1211,7 @@ export default {
|
||||||
this.handleScrolledToLatest(false);
|
this.handleScrolledToLatest(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
this.delayedUpdateOfScrollToBottom();
|
||||||
this.showScrollToEnd =
|
|
||||||
container.scrollHeight === container.clientHeight
|
|
||||||
? false
|
|
||||||
: (this.reverseOrder ? (container.scrollTop.toFixed(0) > 0) : (container.scrollHeight - container.scrollTop.toFixed(0) > container.clientHeight)) ||
|
|
||||||
(this.timelineWindow && this.timelineWindow.canPaginate(EventTimeline.FORWARDS));
|
|
||||||
|
|
||||||
this.restartRRTimer();
|
this.restartRRTimer();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -1284,6 +1279,24 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
delayedUpdateOfScrollToBottom() {
|
||||||
|
if (this.scrollUpdateTimer) {
|
||||||
|
clearTimeout(this.scrollUpdateTimer);
|
||||||
|
}
|
||||||
|
this.scrollUpdateTimer = setTimeout(() => {
|
||||||
|
this.scrollUpdateTimer = null;
|
||||||
|
const container = this.chatContainer;
|
||||||
|
if (!container) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.showScrollToEnd =
|
||||||
|
container.scrollHeight === container.clientHeight
|
||||||
|
? false
|
||||||
|
: (this.reverseOrder ? (container.scrollTop.toFixed(0) > 0) : (container.scrollHeight - container.scrollTop.toFixed(0) > container.clientHeight)) ||
|
||||||
|
(this.timelineWindow && this.timelineWindow.canPaginate(EventTimeline.FORWARDS));
|
||||||
|
}, 1000);
|
||||||
|
},
|
||||||
|
|
||||||
onEvent(event) {
|
onEvent(event) {
|
||||||
//console.log("OnEvent", JSON.stringify(event));
|
//console.log("OnEvent", JSON.stringify(event));
|
||||||
if (event.getRoomId() !== this.roomId) {
|
if (event.getRoomId() !== this.roomId) {
|
||||||
|
|
@ -1307,16 +1320,7 @@ export default {
|
||||||
if (loadingDone && event.forwardLooking && (!event.isRelation() || event.isMxThread || event.threadRootId || event.parentThread)) {
|
if (loadingDone && event.forwardLooking && (!event.isRelation() || event.isMxThread || event.threadRootId || event.parentThread)) {
|
||||||
// If we are at bottom, scroll to see new events...
|
// If we are at bottom, scroll to see new events...
|
||||||
var scrollToSeeNew = !event.isRedaction() && event.getSender() == this.$matrix.currentUserId; // When we sent, scroll
|
var scrollToSeeNew = !event.isRedaction() && event.getSender() == this.$matrix.currentUserId; // When we sent, scroll
|
||||||
const container = this.chatContainer;
|
this.handleScrolledToLatest(scrollToSeeNew || !this.showScrollToEnd);
|
||||||
if (container) {
|
|
||||||
if (this.reverseOrder && container.scrollTop.toFixed(0) == 0) {
|
|
||||||
scrollToSeeNew = true;
|
|
||||||
}
|
|
||||||
else if (!this.reverseOrder && container.scrollHeight - container.scrollTop.toFixed(0) == container.clientHeight) {
|
|
||||||
scrollToSeeNew = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.handleScrolledToLatest(scrollToSeeNew);
|
|
||||||
|
|
||||||
// If kick or ban event, redirect to "goodbye"...
|
// If kick or ban event, redirect to "goodbye"...
|
||||||
if (event.getType() === "m.room.member" &&
|
if (event.getType() === "m.room.member" &&
|
||||||
|
|
@ -1516,32 +1520,41 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
smoothScrollToLatest() {
|
smoothScrollToLatest() {
|
||||||
this.$nextTick(function () {
|
this.$nextTick(() => {
|
||||||
|
// TODO - fix this. We need to wait until the "lastChild" below has been
|
||||||
|
// laid out correctly. If we do it "too early" it will have zero height and
|
||||||
|
// thus not correctly scrolled into the viewport. So we wait a few ticks...
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
|
window.requestAnimationFrame(() => {
|
||||||
const container = this.chatContainer;
|
const container = this.chatContainer;
|
||||||
if (container && container.children.length > 0) {
|
if (container && container.children.length > 0) {
|
||||||
if (this.reverseOrder) {
|
if (this.reverseOrder) {
|
||||||
const firstChild = container.children[0];
|
const firstChild = container.children[0];
|
||||||
console.log("Scroll into view", firstChild);
|
window.requestAnimationFrame(() => {
|
||||||
window.requestAnimationFrame(() => {
|
firstChild.scrollIntoView({
|
||||||
firstChild.scrollIntoView({
|
behavior: "smooth",
|
||||||
behavior: "smooth",
|
block: "end",
|
||||||
block: "end",
|
inline: "nearest",
|
||||||
inline: "nearest",
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
const lastChild = container.children[container.children.length - 1];
|
const lastChild = container.children[container.children.length - 1];
|
||||||
console.log("Scroll into view", lastChild);
|
window.requestAnimationFrame(() => {
|
||||||
window.requestAnimationFrame(() => {
|
lastChild.scrollIntoView({
|
||||||
lastChild.scrollIntoView({
|
behavior: "smooth",
|
||||||
behavior: "smooth",
|
block: "start",
|
||||||
block: "start",
|
inline: "nearest",
|
||||||
inline: "nearest",
|
});
|
||||||
});
|
});
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
showMoreMessageOperations(e) {
|
showMoreMessageOperations(e) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue