mirror of
https://github.com/RetroShare/RSNewWebUI.git
synced 2026-09-12 19:50:04 +05:00
webui v157: read further back in a room by scrolling up
A room opens on its last 20 messages and that was all there ever was: reaching the top of the pane loaded nothing, so anything older was only reachable through the separate history browser. Scrolling near the top now asks for a larger slice. p3HistoryMgr::getMessages takes a count and nothing else -- no cursor, no "before this message" -- and always answers with the newest ones, so the only way to reach older text is to ask for more and let addMessages() drop what is already held. It re-sends what we have, which is the price of that API; the slice is small, and the core keeps ten days at most anyway. An answer shorter than the count asked for means there is nothing older left, and the pane stops asking. The opening slice stays at 20: every room opening pays for it, and on a phone each request is a fresh connection on a core that answers one at a time. Older messages are inserted above what is on screen, which would push the conversation down by their height; that height goes back into scrollTop, so the reader does not move while a slice lands.
This commit is contained in:
parent
e67c4c3170
commit
597ef472d8
@ -128,6 +128,29 @@ function updateChatStickToBottom(element) {
|
||||
element.scrollHeight - element.scrollTop - element.clientHeight <= CHAT_STICK_SLACK_PX;
|
||||
}
|
||||
|
||||
// Far enough from the top to have the next slice ready before the reader gets
|
||||
// there, close enough not to fire on the first flick of a long conversation.
|
||||
const CHAT_LOAD_OLDER_AT_PX = 120;
|
||||
|
||||
function loadOlderWhenAtTop(element) {
|
||||
if (!element || element.scrollTop > CHAT_LOAD_OLDER_AT_PX) return;
|
||||
|
||||
// Older messages are inserted above the ones on screen, which pushes
|
||||
// everything down by exactly the height they add. Put that height back into
|
||||
// scrollTop and the reader does not move at all -- without it the pane jumps
|
||||
// to a different part of the conversation each time a slice lands.
|
||||
const previousHeight = element.scrollHeight;
|
||||
const previousTop = element.scrollTop;
|
||||
|
||||
ChatLobbyModel.loadOlderHistory(() => {
|
||||
requestAnimationFrame(() => {
|
||||
const pane = document.querySelector('.chat-hub-messages');
|
||||
if (!pane) return;
|
||||
pane.scrollTop = previousTop + (pane.scrollHeight - previousHeight);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function renderUserTooltip(gxsId, name) {
|
||||
const details = ChatHubState.gxsDetails[gxsId];
|
||||
if (!details) return null;
|
||||
@ -390,6 +413,7 @@ const ChatConversationView = () => {
|
||||
// while the reader drags the pane.
|
||||
event.redraw = false;
|
||||
updateChatStickToBottom(event.target);
|
||||
loadOlderWhenAtTop(event.target);
|
||||
},
|
||||
},
|
||||
ChatLobbyModel.messages
|
||||
|
||||
@ -734,7 +734,12 @@ const ChatLobbyModel = {
|
||||
}
|
||||
},
|
||||
|
||||
loadHistory(id, type) {
|
||||
// How much of a conversation is on screen when it opens. Small on purpose:
|
||||
// every room opening pays for it, and on a phone each request is a fresh
|
||||
// connection on a core that answers one at a time.
|
||||
HISTORY_PAGE: 20,
|
||||
|
||||
historyChatPeerId(id, type) {
|
||||
const chatPeerId = {
|
||||
broadcast_status_peer_id: '00000000000000000000000000000000',
|
||||
type,
|
||||
@ -746,20 +751,66 @@ const ChatLobbyModel = {
|
||||
if (type === 3) chatPeerId.lobby_id.xstr64 = id;
|
||||
else if (type === 2) chatPeerId.distant_chat_id = id;
|
||||
else if (type === 1) chatPeerId.peer_id = id;
|
||||
return chatPeerId;
|
||||
},
|
||||
|
||||
loadHistory(id, type) {
|
||||
this.historyLoaded = this.HISTORY_PAGE;
|
||||
this.historyExhausted = false;
|
||||
this.historyLoading = false;
|
||||
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsHistory/getMessages',
|
||||
{
|
||||
chatPeerId,
|
||||
loadCount: 20,
|
||||
chatPeerId: this.historyChatPeerId(id, type),
|
||||
loadCount: this.HISTORY_PAGE,
|
||||
},
|
||||
(data, success) => {
|
||||
if (success && data.msgs) {
|
||||
if (data.msgs.length < this.HISTORY_PAGE) this.historyExhausted = true;
|
||||
this.addMessages(data.msgs);
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
// Reading further back. p3HistoryMgr::getMessages takes a count and nothing
|
||||
// else -- no cursor, no "before this message" -- and always answers with the
|
||||
// newest ones, so the only way to see older text is to ask for a bigger slice
|
||||
// and let addMessages() drop what is already here. It re-sends what we hold,
|
||||
// which is the price of that API; a page is small and the core keeps ten days
|
||||
// at most anyway (mMaxStorageDurationSeconds).
|
||||
loadOlderHistory(done) {
|
||||
const detail = this.currentLobby;
|
||||
if (!detail || this.historyLoading || this.historyExhausted) return false;
|
||||
|
||||
const id = this.lastLobbyId;
|
||||
if (!id) return false;
|
||||
|
||||
this.historyLoading = true;
|
||||
const wanted = (this.historyLoaded || this.HISTORY_PAGE) + this.HISTORY_PAGE * 2;
|
||||
|
||||
rs.rsJsonApiRequest(
|
||||
'/rsHistory/getMessages',
|
||||
{
|
||||
chatPeerId: this.historyChatPeerId(id, detail.chatType),
|
||||
loadCount: wanted,
|
||||
},
|
||||
(data, success) => {
|
||||
this.historyLoading = false;
|
||||
if (!success || !data.msgs) {
|
||||
if (done) done();
|
||||
return;
|
||||
}
|
||||
// Fewer than asked for means the core has nothing older left.
|
||||
if (data.msgs.length < wanted) this.historyExhausted = true;
|
||||
this.historyLoaded = wanted;
|
||||
this.addMessages(data.msgs);
|
||||
if (done) done();
|
||||
}
|
||||
);
|
||||
return true;
|
||||
},
|
||||
loadAllHistoryForRoom(lobbyId, callback) {
|
||||
ChatHubState.isHistoryLoading = true;
|
||||
ChatHubState.fullHistoryMessages = [];
|
||||
|
||||
@ -135,7 +135,7 @@ const navbar = () => {
|
||||
? 'Connected to RetroShare Core'
|
||||
: 'Connection Lost',
|
||||
}),
|
||||
m('span.webui-version', { style: { fontSize: '0.7em' } }, 'v156'),
|
||||
m('span.webui-version', { style: { fontSize: '0.7em' } }, 'v157'),
|
||||
m('i.fas.fa-sync-alt.refresh-icon', {
|
||||
style: { cursor: 'pointer', fontSize: '0.8em' },
|
||||
onclick: () => window.location.reload(true),
|
||||
@ -258,7 +258,7 @@ const MobileStatus = () => {
|
||||
m('small', statusbar.formatBytes(state.totalOut)),
|
||||
]),
|
||||
]),
|
||||
m('.mobile-status-sheet__version', 'WebUI v156'),
|
||||
m('.mobile-status-sheet__version', 'WebUI v157'),
|
||||
])),
|
||||
];
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user