Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
converse.js
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
converse.js
Commits
4927d561
Commit
4927d561
authored
Jul 28, 2020
by
JC Brand
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Maintain scroll position when re-inserting #conversejs element
parent
867f80e9
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
47 additions
and
36 deletions
+47
-36
src/converse-chatboxviews.js
src/converse-chatboxviews.js
+4
-0
src/converse-chatview.js
src/converse-chatview.js
+40
-33
src/converse-muc-views.js
src/converse-muc-views.js
+1
-1
src/templates/directives/body.js
src/templates/directives/body.js
+2
-2
No files found.
src/converse-chatboxviews.js
View file @
4927d561
...
@@ -176,6 +176,10 @@ converse.plugins.add('converse-chatboxviews', {
...
@@ -176,6 +176,10 @@ converse.plugins.add('converse-chatboxviews', {
const
el
=
_converse
.
chatboxviews
?.
el
;
const
el
=
_converse
.
chatboxviews
?.
el
;
if
(
el
&&
!
container
.
contains
(
el
))
{
if
(
el
&&
!
container
.
contains
(
el
))
{
container
.
insertAdjacentElement
(
'
afterBegin
'
,
el
);
container
.
insertAdjacentElement
(
'
afterBegin
'
,
el
);
api
.
chatviews
.
get
()
.
filter
(
v
=>
v
.
model
.
get
(
'
id
'
)
!==
'
controlbox
'
)
.
forEach
(
v
=>
v
.
maintainScrollTop
());
}
else
if
(
!
el
)
{
}
else
if
(
!
el
)
{
throw
new
Error
(
"
Cannot insert non-existing #conversejs element into the DOM
"
);
throw
new
Error
(
"
Cannot insert non-existing #conversejs element into the DOM
"
);
}
}
...
...
src/converse-chatview.js
View file @
4927d561
...
@@ -208,7 +208,7 @@ converse.plugins.add('converse-chatview', {
...
@@ -208,7 +208,7 @@ converse.plugins.add('converse-chatview', {
this
.
listenTo
(
this
.
model
.
messages
,
'
add
'
,
this
.
onMessageAdded
);
this
.
listenTo
(
this
.
model
.
messages
,
'
add
'
,
this
.
onMessageAdded
);
this
.
listenTo
(
this
.
model
.
messages
,
'
change
'
,
this
.
renderChatHistory
);
this
.
listenTo
(
this
.
model
.
messages
,
'
change
'
,
this
.
renderChatHistory
);
this
.
listenTo
(
this
.
model
.
messages
,
'
remove
'
,
this
.
renderChatHistory
);
this
.
listenTo
(
this
.
model
.
messages
,
'
remove
'
,
this
.
renderChatHistory
);
this
.
listenTo
(
this
.
model
.
messages
,
'
rendered
'
,
this
.
maybeScrollDown
OnMessage
);
this
.
listenTo
(
this
.
model
.
messages
,
'
rendered
'
,
this
.
maybeScrollDown
);
this
.
listenTo
(
this
.
model
.
messages
,
'
reset
'
,
this
.
renderChatHistory
);
this
.
listenTo
(
this
.
model
.
messages
,
'
reset
'
,
this
.
renderChatHistory
);
this
.
listenTo
(
this
.
model
.
notifications
,
'
change
'
,
this
.
renderNotifications
);
this
.
listenTo
(
this
.
model
.
notifications
,
'
change
'
,
this
.
renderNotifications
);
this
.
listenTo
(
this
.
model
,
'
change:show_help_messages
'
,
this
.
renderHelpMessages
);
this
.
listenTo
(
this
.
model
,
'
change:show_help_messages
'
,
this
.
renderHelpMessages
);
...
@@ -241,7 +241,7 @@ converse.plugins.add('converse-chatview', {
...
@@ -241,7 +241,7 @@ converse.plugins.add('converse-chatview', {
render
()
{
render
()
{
const
result
=
tpl_chatbox
(
const
result
=
tpl_chatbox
(
Object
.
assign
(
this
.
model
.
toJSON
(),
{
'
markScrolled
'
:
()
=>
this
.
markScrolled
(
)})
Object
.
assign
(
this
.
model
.
toJSON
(),
{
'
markScrolled
'
:
ev
=>
this
.
markScrolled
(
ev
)})
);
);
render
(
result
,
this
.
el
);
render
(
result
,
this
.
el
);
this
.
content
=
this
.
el
.
querySelector
(
'
.chat-content
'
);
this
.
content
=
this
.
el
.
querySelector
(
'
.chat-content
'
);
...
@@ -486,19 +486,35 @@ converse.plugins.add('converse-chatview', {
...
@@ -486,19 +486,35 @@ converse.plugins.add('converse-chatview', {
api
.
trigger
(
'
afterMessagesFetched
'
,
this
.
model
);
api
.
trigger
(
'
afterMessagesFetched
'
,
this
.
model
);
},
},
maybeScrollDownOnMessage
(
message
)
{
/**
if
(
message
.
get
(
'
sender
'
)
===
'
me
'
||
!
this
.
model
.
get
(
'
scrolled
'
))
{
* Scrolls the chat down, *if* appropriate.
*
* Will only scroll down if we have received a message from
* ourselves, or if the chat was scrolled down before (i.e. the
* `scrolled` flag is `false`);
* @param { _converse.Message|_converse.ChatRoomMessage } [message]
* - An optional message that serves as the cause for needing to scroll down.
*/
maybeScrollDown
(
message
)
{
if
(
message
?.
get
(
'
sender
'
)
===
'
me
'
||
!
this
.
model
.
get
(
'
scrolled
'
))
{
this
.
debouncedScrollDown
();
this
.
debouncedScrollDown
();
}
}
},
},
/**
* Scrolls the chat down.
*
* This method will always scroll the chat down, regardless of
* whether the user scrolled up manually or not.
* @param { Event } [ev] - An optional event that is the cause for needing to scroll down.
*/
scrollDown
(
ev
)
{
scrollDown
(
ev
)
{
ev
?.
preventDefault
?.();
ev
?.
preventDefault
?.();
ev
?.
stopPropagation
?.();
ev
?.
stopPropagation
?.();
if
(
this
.
model
.
get
(
'
scrolled
'
))
{
if
(
this
.
model
.
get
(
'
scrolled
'
))
{
u
.
safeSave
(
this
.
model
,
{
u
.
safeSave
(
this
.
model
,
{
'
scrolled
'
:
false
,
'
scrolled
'
:
false
,
'
top_visible_message
'
:
null
,
'
scrollTop
'
:
null
,
});
});
}
}
if
(
this
.
msgs_container
.
scrollTo
)
{
if
(
this
.
msgs_container
.
scrollTo
)
{
...
@@ -510,6 +526,19 @@ converse.plugins.add('converse-chatview', {
...
@@ -510,6 +526,19 @@ converse.plugins.add('converse-chatview', {
this
.
onScrolledDown
();
this
.
onScrolledDown
();
},
},
/**
* Scroll to the previously saved scrollTop position, or scroll
* down if it wasn't set.
*/
maintainScrollTop
()
{
const
pos
=
this
.
model
.
get
(
'
scrollTop
'
);
if
(
pos
)
{
this
.
msgs_container
.
scrollTop
=
pos
;
}
else
{
this
.
scrollDown
();
}
},
insertIntoDOM
()
{
insertIntoDOM
()
{
_converse
.
chatboxviews
.
insertRowColumn
(
this
.
el
);
_converse
.
chatboxviews
.
insertRowColumn
(
this
.
el
);
/**
/**
...
@@ -537,28 +566,6 @@ converse.plugins.add('converse-chatview', {
...
@@ -537,28 +566,6 @@ converse.plugins.add('converse-chatview', {
this
.
content
.
querySelectorAll
(
'
.spinner
'
).
forEach
(
u
.
removeElement
);
this
.
content
.
querySelectorAll
(
'
.spinner
'
).
forEach
(
u
.
removeElement
);
},
},
setScrollPosition
(
message_el
)
{
/* Given a newly inserted message, determine whether we
* should keep the scrollbar in place (so as to not scroll
* up when using infinite scroll).
*/
if
(
this
.
model
.
get
(
'
scrolled
'
))
{
const
next_msg_el
=
u
.
getNextElement
(
message_el
,
"
.chat-msg
"
);
if
(
next_msg_el
)
{
// The currently received message is not new, there
// are newer messages after it. So let's see if we
// should maintain our current scroll position.
if
(
this
.
content
.
scrollTop
===
0
||
this
.
model
.
get
(
'
top_visible_message
'
))
{
const
top_visible_message
=
this
.
model
.
get
(
'
top_visible_message
'
)
||
next_msg_el
;
this
.
model
.
set
(
'
top_visible_message
'
,
top_visible_message
);
this
.
content
.
scrollTop
=
top_visible_message
.
offsetTop
-
30
;
}
}
}
else
{
this
.
scrollDown
();
}
},
onStatusMessageChanged
(
item
)
{
onStatusMessageChanged
(
item
)
{
this
.
renderHeading
();
this
.
renderHeading
();
/**
/**
...
@@ -1091,8 +1098,9 @@ converse.plugins.add('converse-chatview', {
...
@@ -1091,8 +1098,9 @@ converse.plugins.add('converse-chatview', {
* which debounces this method by 100ms.
* which debounces this method by 100ms.
* @private
* @private
*/
*/
_markScrolled
:
function
()
{
_markScrolled
:
function
(
ev
)
{
let
scrolled
=
true
;
let
scrolled
=
true
;
let
scrollTop
=
null
;
const
is_at_bottom
=
const
is_at_bottom
=
(
this
.
msgs_container
.
scrollTop
+
this
.
msgs_container
.
clientHeight
)
>=
(
this
.
msgs_container
.
scrollTop
+
this
.
msgs_container
.
clientHeight
)
>=
this
.
msgs_container
.
scrollHeight
-
62
;
// sigh...
this
.
msgs_container
.
scrollHeight
-
62
;
// sigh...
...
@@ -1108,15 +1116,14 @@ converse.plugins.add('converse-chatview', {
...
@@ -1108,15 +1116,14 @@ converse.plugins.add('converse-chatview', {
* @example _converse.api.listen.on('chatBoxScrolledUp', obj => { ... });
* @example _converse.api.listen.on('chatBoxScrolledUp', obj => { ... });
*/
*/
api
.
trigger
(
'
chatBoxScrolledUp
'
,
this
);
api
.
trigger
(
'
chatBoxScrolledUp
'
,
this
);
}
else
{
scrollTop
=
ev
.
target
.
scrollTop
;
}
}
u
.
safeSave
(
this
.
model
,
{
u
.
safeSave
(
this
.
model
,
{
scrolled
,
scrollTop
});
'
scrolled
'
:
scrolled
,
'
top_visible_message
'
:
null
});
},
},
viewUnreadMessages
()
{
viewUnreadMessages
()
{
this
.
model
.
save
({
'
scrolled
'
:
false
,
'
top_visible_message
'
:
null
});
this
.
model
.
save
({
'
scrolled
'
:
false
,
'
scrollTop
'
:
null
});
this
.
scrollDown
();
this
.
scrollDown
();
},
},
...
...
src/converse-muc-views.js
View file @
4927d561
...
@@ -190,7 +190,7 @@ converse.plugins.add('converse-muc-views', {
...
@@ -190,7 +190,7 @@ converse.plugins.add('converse-muc-views', {
this
.
listenTo
(
this
.
model
,
'
show
'
,
this
.
show
);
this
.
listenTo
(
this
.
model
,
'
show
'
,
this
.
show
);
this
.
listenTo
(
this
.
model
.
features
,
'
change:moderated
'
,
this
.
renderBottomPanel
);
this
.
listenTo
(
this
.
model
.
features
,
'
change:moderated
'
,
this
.
renderBottomPanel
);
this
.
listenTo
(
this
.
model
.
features
,
'
change:open
'
,
this
.
renderHeading
);
this
.
listenTo
(
this
.
model
.
features
,
'
change:open
'
,
this
.
renderHeading
);
this
.
listenTo
(
this
.
model
.
messages
,
'
rendered
'
,
this
.
maybeScrollDown
OnMessage
);
this
.
listenTo
(
this
.
model
.
messages
,
'
rendered
'
,
this
.
maybeScrollDown
);
this
.
listenTo
(
this
.
model
.
session
,
'
change:connection_status
'
,
this
.
onConnectionStatusChanged
);
this
.
listenTo
(
this
.
model
.
session
,
'
change:connection_status
'
,
this
.
onConnectionStatusChanged
);
// Bind so that we can pass it to addEventListener and removeEventListener
// Bind so that we can pass it to addEventListener and removeEventListener
...
...
src/templates/directives/body.js
View file @
4927d561
...
@@ -168,12 +168,12 @@ class MessageBodyRenderer {
...
@@ -168,12 +168,12 @@ class MessageBodyRenderer {
// image loads, it triggers 'scroll' and the chat will be marked as scrolled,
// image loads, it triggers 'scroll' and the chat will be marked as scrolled,
// which is technically true, but not what we want because the user
// which is technically true, but not what we want because the user
// didn't initiate the scrolling.
// didn't initiate the scrolling.
this
.
scrolled
=
this
.
chatview
.
model
.
get
(
'
scrolled
'
);
this
.
was_scrolled_up
=
this
.
chatview
.
model
.
get
(
'
scrolled
'
);
this
.
text
=
this
.
component
.
model
.
getMessageText
();
this
.
text
=
this
.
component
.
model
.
getMessageText
();
}
}
scrollDownOnImageLoad
()
{
scrollDownOnImageLoad
()
{
if
(
!
this
.
scrolled
)
{
if
(
!
this
.
was_scrolled_up
)
{
this
.
chatview
.
scrollDown
();
this
.
chatview
.
scrollDown
();
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment