Commit acd9a186 authored by JC Brand's avatar JC Brand

Update with new message markup

parent 6a462f6c
......@@ -7381,7 +7381,7 @@ body.reset {
background-color: #3AA569;
box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
z-index: 1;
overflow-y: scroll;
overflow-y: hidden;
width: 100%; }
@media screen and (max-height: 450px) {
#conversejs .chatbox .box-flyout {
......@@ -7648,18 +7648,6 @@ body.reset {
#conversejs.converse-overlayed .chatbox .box-flyout {
min-width: 250px !important;
width: 250px; }
#conversejs.converse-embedded .chatbox .chat-body .chat-message,
#conversejs.converse-overlayed .chatbox .chat-body .chat-message {
line-height: 20px; }
#conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-author,
#conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-author {
line-height: 20px; }
#conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-content,
#conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-content {
line-height: 20px; }
#conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-content .emojione,
#conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-content .emojione {
margin-bottom: -5px; }
#conversejs.converse-embedded .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu,
#conversejs.converse-overlayed .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu {
min-width: 235px; }
......@@ -7746,16 +7734,6 @@ body.reset {
background-color: #3AA569;
border-top-left-radius: 4px;
border-top-right-radius: 4px; }
#conversejs.converse-fullscreen .chatbox .chat-body .chat-message {
line-height: 16px;
font-size: 12px; }
#conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-author {
line-height: 16px; }
#conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-content {
line-height: 16px; }
#conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-content .emojione {
height: 16px;
margin-bottom: -4px; }
#conversejs.converse-fullscreen .chatbox .chat-content {
border-top-left-radius: 4px;
border-top-right-radius: 4px; }
......@@ -8884,6 +8862,8 @@ body.reset {
align-items: stretch;
margin-left: 0.5rem;
width: 100%; }
#conversejs .message.chat-msg .chat-msg__content--action {
margin-left: 0; }
#conversejs .message.chat-msg .chat-msg__body {
display: flex;
flex-direction: row;
......@@ -8893,8 +8873,9 @@ body.reset {
display: flex;
flex-direction: column;
width: 100%; }
#conversejs .message.chat-msg .chat-msg-edited {
cursor: pointer; }
#conversejs .message.chat-msg .chat-msg__edit-modal {
cursor: pointer;
padding-right: 0.5em; }
#conversejs .message.chat-msg.headline .chat-msg__body {
margin-left: 0; }
#conversejs .message.chat-msg .chat-msg__text {
......@@ -8906,11 +8887,12 @@ body.reset {
word-break: break-all; }
#conversejs .message.chat-msg .chat-msg__text .emojione {
margin-bottom: -6px; }
#conversejs .message.chat-msg .chat-msg-media {
margin-top: 0.25rem; }
#conversejs .message.chat-msg .chat-msg-media a {
#conversejs .message.chat-msg .chat-msg__media {
margin-top: 0.25rem;
word-break: break-all; }
#conversejs .message.chat-msg .chat-msg__media a {
word-wrap: break-word; }
#conversejs .message.chat-msg .chat-msg-media audio {
#conversejs .message.chat-msg .chat-msg__media audio {
width: 100%; }
#conversejs .message.chat-msg .chat-msg__actions .chat-msg__action {
height: 14px;
......@@ -8934,6 +8916,7 @@ body.reset {
padding-bottom: 0.25rem;
display: block; }
#conversejs .message.chat-msg .chat-msg__heading .chat-msg__author {
white-space: nowrap;
font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
font-size: 115%; }
#conversejs .message.chat-msg .chat-msg__heading .chat-msg__author .badge {
......@@ -8943,6 +8926,7 @@ body.reset {
padding-left: 0.25em;
color: #8c8c8c; }
#conversejs .message.chat-msg.chat-msg--action .chat-msg__content {
flex-wrap: wrap;
flex-direction: row;
justify-content: flex-start; }
#conversejs .message.chat-msg.chat-msg--action .chat-msg__text {
......@@ -8951,6 +8935,10 @@ body.reset {
margin-top: 0;
padding-bottom: 0;
width: auto; }
#conversejs .message.chat-msg.chat-msg--action .chat-msg__author {
font-size: 14px; }
#conversejs .message.chat-msg.chat-msg--action .chat-msg__time {
margin-left: 0; }
#conversejs .message.chat-msg.chat-msg--followup .chat-msg__heading,
#conversejs .message.chat-msg.chat-msg--followup .chat-msg__avatar {
display: none; }
......
This diff is collapsed.
......@@ -45,8 +45,11 @@
Romeo Montague has entered the room</div>
<div class="message chat-msg chat-msg--action" data-isodate="2018-04-36T18:07:38+02:00">
<div class="chat-msg__content">
<span class="chat-msg__heading"><span class="chat-msg__author">**Romeo Montague</span></span>
<div class="chat-msg__content chat-msg__content--action">
<span class="chat-msg__heading">
<time timestamp="2018-12-29" class="chat-msg__time">15:29</time>
<span class="chat-msg__author">**Romeo Montague</span>
</span>
<span class="chat-msg__text">looks around</span>
</div>
</div>
......@@ -177,7 +180,7 @@
</div>
<div class="chat-msg__body">
<div class="chat-msg__message">
<div class="chat-msg-media">
<div class="chat-msg__media">
<a href="https://images.unsplash.com/photo-1496660067708-010ebdd7ce72?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ea3514e6e00d8ce25c24d992b97929d9&dpr=1&auto=format&fit=crop&w=1000&q=80&cs=tinysrgb"
target="_blank" rel="noopener">
<img class="chat-image img-thumbnail" src="https://images.unsplash.com/photo-1496660067708-010ebdd7ce72?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=ea3514e6e00d8ce25c24d992b97929d9&dpr=1&auto=format&fit=crop&w=1000&q=80&cs=tinysrgb">
......@@ -227,6 +230,7 @@
<span class="chat-msg__time">19:49</span>
</div>
<div class="chat-msg__body">
<i title="This message has been edited" class="fa fa-edit chat-msg__edit-modal"></i>
<div class="chat-msg__message">
<span class="chat-msg__text">I mean, sir, in delay We waste our lights in vain, like lamps by day.</span>
</div>
......
......@@ -124,7 +124,7 @@
background-color: $chat-head-color;
box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
z-index: 1;
overflow-y: scroll;
overflow-y: hidden;
width: 100%;
@media screen and (max-height: $mobile-landscape-height) {
......@@ -464,21 +464,6 @@
min-width: $overlayed-chat-width!important;
width: $overlayed-chat-width;
}
.chat-body {
.chat-message {
line-height: $line-height-large;
.chat-msg-author {
line-height: $line-height-large;
}
.chat-msg-content {
line-height: $line-height-large;
.emojione {
margin-bottom: -5px;
}
}
}
}
}
.chatbox {
form.sendXMPPMessage {
......@@ -597,21 +582,6 @@
background-color: $chat-head-color;
border-top-left-radius: $chatbox-border-radius;
border-top-right-radius: $chatbox-border-radius;
.chat-message {
line-height: $line-height;
font-size: $font-size-small;
.chat-msg-author {
line-height: $line-height;
}
.chat-msg-content {
line-height: $line-height;
.emojione {
height: $line-height;
margin-bottom: -$line-height/4;
}
}
}
}
.chat-content {
border-top-left-radius: $chatbox-border-radius;
......
......@@ -104,6 +104,7 @@
whitespace: nowrap;
}
}
.chat-msg__content {
display: flex;
flex-direction: column;
......@@ -112,6 +113,9 @@
margin-left: 0.5rem;
width: 100%;
}
.chat-msg__content--action {
margin-left: 0;
}
.chat-msg__body {
display: flex;
......@@ -126,8 +130,9 @@
width: 100%;
}
.chat-msg-edited {
.chat-msg__edit-modal {
cursor: pointer;
padding-right: 0.5em;
}
&.headline {
.chat-msg__body {
......@@ -148,8 +153,9 @@
}
}
.chat-msg-media {
.chat-msg__media {
margin-top: 0.25rem;
word-break: break-all;
a {
word-wrap: break-word;
}
......@@ -188,6 +194,7 @@
display: block;
.chat-msg__author {
white-space: nowrap;
font-family: $heading-font;
font-size: 115%;
.badge {
......@@ -202,6 +209,7 @@
}
&.chat-msg--action {
.chat-msg__content {
flex-wrap: wrap;
flex-direction: row;
justify-content: flex-start;
}
......@@ -213,6 +221,12 @@
padding-bottom: 0;
width: auto;
}
.chat-msg__author {
font-size: $message-font-size;
}
.chat-msg__time {
margin-left: 0;
}
}
&.chat-msg--followup {
......
......@@ -76,33 +76,33 @@
test_utils.waitUntil(function () {
return u.isVisible(view.el);
}).then(function () {
expect(view.el.querySelectorAll('.chat-action').length).toBe(1);
expect(_.includes(view.el.querySelector('.chat-msg-author').textContent, '**Max Frankfurter')).toBeTruthy();
expect($(view.el).find('.chat-msg-text').text()).toBe(' is tired');
expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(1);
expect(_.includes(view.el.querySelector('.chat-msg__author').textContent, '**Max Frankfurter')).toBeTruthy();
expect($(view.el).find('.chat-msg__text').text()).toBe(' is tired');
message = '/me is as well';
test_utils.sendMessage(view, message);
expect(view.el.querySelectorAll('.chat-action').length).toBe(2);
expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(2);
return test_utils.waitUntil(() => $(view.el).find('.chat-msg-author:last').text() === '**Max Mustermann');
return test_utils.waitUntil(() => $(view.el).find('.chat-msg__author:last').text().trim() === '**Max Mustermann');
}).then(function () {
expect($(view.el).find('.chat-msg-text:last').text()).toBe(' is as well');
expect($(view.el).find('.chat-msg:last').hasClass('chat-msg-followup')).toBe(false);
expect($(view.el).find('.chat-msg__text:last').text()).toBe(' is as well');
expect($(view.el).find('.chat-msg:last').hasClass('chat-msg--followup')).toBe(false);
// Check that /me messages after a normal message don't
// get the 'chat-msg-followup' class.
// get the 'chat-msg--followup' class.
message = 'This a normal message';
test_utils.sendMessage(view, message);
let message_el = view.el.querySelector('.message:last-child');
expect(u.hasClass('chat-msg-followup', message_el)).toBeFalsy();
expect(u.hasClass('chat-msg--followup', message_el)).toBeFalsy();
message = '/me wrote a 3rd person message';
test_utils.sendMessage(view, message);
message_el = view.el.querySelector('.message:last-child');
expect(view.el.querySelectorAll('.chat-action').length).toBe(3);
expect($(view.el).find('.chat-msg-text:last').text()).toBe(' wrote a 3rd person message');
expect($(view.el).find('.chat-msg-author:last').is(':visible')).toBeTruthy();
expect(u.hasClass('chat-msg-followup', message_el)).toBeFalsy();
expect(view.el.querySelectorAll('.chat-msg--action').length).toBe(3);
expect($(view.el).find('.chat-msg__text:last').text()).toBe(' wrote a 3rd person message');
expect($(view.el).find('.chat-msg__author:last').is(':visible')).toBeTruthy();
expect(u.hasClass('chat-msg--followup', message_el)).toBeFalsy();
done();
});
});
......@@ -1627,7 +1627,7 @@
return $(view.el).find('.chat-content').find('.chat-msg').length;
}, 1000).then(function () {
expect(view.model.sendMessage).toHaveBeenCalled();
var msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg-text');
var msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg__text');
expect(msg.html()).toEqual(
'<a target="_blank" rel="noopener" href="https://www.openstreetmap.org/?mlat=37.786971&amp;'+
'mlon=-122.399677#map=18/37.786971/-122.399677">https://www.openstreetmap.org/?mlat=37.7869'+
......
......@@ -867,8 +867,8 @@
'type': 'groupchat'
}).c('body').t(message).tree();
view.model.onMessage(msg);
expect(_.includes($(view.el).find('.chat-msg-author').text(), '**Dyon van de Wege')).toBeTruthy();
expect($(view.el).find('.chat-msg-text').text()).toBe(' is tired');
expect(_.includes($(view.el).find('.chat-msg__author').text(), '**Dyon van de Wege')).toBeTruthy();
expect($(view.el).find('.chat-msg__text').text()).toBe(' is tired');
message = '/me is as well';
msg = $msg({
......@@ -878,8 +878,8 @@
type: 'groupchat'
}).c('body').t(message).tree();
view.model.onMessage(msg);
expect(_.includes($(view.el).find('.chat-msg-author:last').text(), '**Max Mustermann')).toBeTruthy();
expect($(view.el).find('.chat-msg-text:last').text()).toBe(' is as well');
expect(_.includes($(view.el).find('.chat-msg__author:last').text(), '**Max Mustermann')).toBeTruthy();
expect($(view.el).find('.chat-msg__text:last').text()).toBe(' is as well');
done();
});
}));
......@@ -1545,7 +1545,7 @@
view.model.onMessage(message.nodeTree);
var $chat_content = $(view.el).find('.chat-content');
expect($chat_content.find('.chat-msg').length).toBe(1);
expect($chat_content.find('.chat-msg-text').text()).toBe(text);
expect($chat_content.find('.chat-msg__text').text()).toBe(text);
expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
done();
});
......@@ -1583,7 +1583,7 @@
}).c('body').t(text);
view.model.onMessage(message.nodeTree);
expect($chat_content.find('.chat-msg').length).toBe(1);
expect($chat_content.find('.chat-msg-text').last().text()).toBe(text);
expect($chat_content.find('.chat-msg__text').last().text()).toBe(text);
// We don't emit an event if it's our own message
expect(_converse.emit.calls.count(), 1);
done();
......@@ -1624,7 +1624,7 @@
// Now check that the message appears inside the chatbox in the DOM
var $chat_content = $(view.el).find('.chat-content');
var msg_txt = $chat_content.find('.chat-msg:last').find('.chat-msg-text').text();
var msg_txt = $chat_content.find('.chat-msg:last').find('.chat-msg__text').text();
expect(msg_txt).toEqual(message);
expect(view.content.scrollTop).toBe(0);
done();
......@@ -3475,7 +3475,7 @@
var messages = view.el.querySelectorAll('.message');
expect(messages.length).toBe(8);
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(view.el.querySelector('.chat-msg .chat-msg-text').textContent).toBe('hello world');
expect(view.el.querySelector('.chat-msg .chat-msg__text').textContent).toBe('hello world');
// Test that the composing notifications get removed
// via timeout.
......
......@@ -364,7 +364,7 @@
}, 1000);
}).then(function () {
// Check that the image renders
expect(view.el.querySelector('.chat-msg .chat-msg-media').innerHTML.trim()).toEqual(
expect(view.el.querySelector('.chat-msg .chat-msg__media').innerHTML.trim()).toEqual(
'<!-- src/templates/image.html -->\n'+
'<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">'+
'<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg">'+
......@@ -472,7 +472,7 @@
}, 1000);
}).then(function () {
// Check that the image renders
expect(view.el.querySelector('.chat-msg .chat-msg-media').innerHTML.trim()).toEqual(
expect(view.el.querySelector('.chat-msg .chat-msg__media').innerHTML.trim()).toEqual(
'<!-- src/templates/image.html -->\n'+
'<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">'+
'<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg"></a>')
......@@ -683,7 +683,7 @@
expect(view.el.querySelector('.chat-content progress').getAttribute('value')).toBe('0.5');
message.set('progress', 1);
expect(view.el.querySelector('.chat-content progress').getAttribute('value')).toBe('1');
expect(view.el.querySelector('.chat-content .chat-msg-text').textContent).toBe('Uploading file: my-juliet.jpg, 22.91 KB');
expect(view.el.querySelector('.chat-content .chat-msg__text').textContent).toBe('Uploading file: my-juliet.jpg, 22.91 KB');
done();
});
var sent_stanza;
......
This diff is collapsed.
......@@ -40,9 +40,9 @@
return test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Max Frankfurter')
.then(function () {
expect(view.el.querySelector('.chat-msg-author').textContent).toBe('Max Frankfurter');
expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Max Frankfurter');
var message_content = view.el.querySelector('.chat-msg-text');
var message_content = view.el.querySelector('.chat-msg__text');
expect(message_content.textContent).toBe(spoiler);
var spoiler_hint_el = view.el.querySelector('.spoiler-hint');
......@@ -79,9 +79,9 @@
var view = _converse.chatboxviews.get(sender_jid);
return test_utils.waitUntil(() => view.model.vcard.get('fullname') === 'Max Frankfurter')
.then(function () {
expect(_.includes(view.el.querySelector('.chat-msg-author').textContent, 'Max Frankfurter')).toBeTruthy();
expect(_.includes(view.el.querySelector('.chat-msg__author').textContent, 'Max Frankfurter')).toBeTruthy();
var message_content = view.el.querySelector('.chat-msg-text');
var message_content = view.el.querySelector('.chat-msg__text');
expect(message_content.textContent).toBe(spoiler);
var spoiler_hint_el = view.el.querySelector('.spoiler-hint');
......@@ -148,9 +148,9 @@
expect(body_el.textContent).toBe('This is the spoiler');
/* Test the HTML spoiler message */
expect(view.el.querySelector('.chat-msg-author').textContent).toBe('Max Mustermann');
expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Max Mustermann');
var spoiler_msg_el = view.el.querySelector('.chat-msg-text.spoiler');
var spoiler_msg_el = view.el.querySelector('.chat-msg__text.spoiler');
expect(spoiler_msg_el.textContent).toBe('This is the spoiler');
expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
......@@ -227,9 +227,9 @@
expect(body_el.textContent).toBe('This is the spoiler');
/* Test the HTML spoiler message */
expect(view.el.querySelector('.chat-msg-author').textContent).toBe('Max Mustermann');
expect(view.el.querySelector('.chat-msg__author').textContent.trim()).toBe('Max Mustermann');
var spoiler_msg_el = view.el.querySelector('.chat-msg-text.spoiler');
var spoiler_msg_el = view.el.querySelector('.chat-msg__text.spoiler');
expect(spoiler_msg_el.textContent).toBe('This is the spoiler');
expect(_.includes(spoiler_msg_el.classList, 'collapsed')).toBeTruthy();
......
......@@ -9,7 +9,6 @@
"bootstrap",
"emojione",
"xss",
"templates/action.html",
"templates/chatbox.html",
"templates/chatbox_head.html",
"templates/chatbox_message_form.html",
......@@ -33,7 +32,6 @@
bootstrap,
emojione,
xss,
tpl_action,
tpl_chatbox,
tpl_chatbox_head,
tpl_chatbox_message_form,
......@@ -747,19 +745,19 @@
date = moment(el.getAttribute('data-isodate')),
next_el = el.nextElementSibling;
if (!u.hasClass('chat-action', el) && !u.hasClass('chat-action', previous_el) &&
if (!u.hasClass('chat-msg--action', el) && !u.hasClass('chat-msg--action', previous_el) &&
previous_el.getAttribute('data-from') === from &&
date.isBefore(moment(previous_el.getAttribute('data-isodate')).add(10, 'minutes'))) {
u.addClass('chat-msg-followup', el);
u.addClass('chat-msg--followup', el);
}
if (!next_el) { return; }
if (!u.hasClass('chat-action', 'el') &&
if (!u.hasClass('chat-msg--action', 'el') &&
next_el.getAttribute('data-from') === from &&
moment(next_el.getAttribute('data-isodate')).isBefore(date.add(10, 'minutes'))) {
u.addClass('chat-msg-followup', next_el);
u.addClass('chat-msg--followup', next_el);
} else {
u.removeClass('chat-msg-followup', next_el);
u.removeClass('chat-msg--followup', next_el);
}
},
......
......@@ -10,26 +10,22 @@
"xss",
"emojione",
"filesize",
"templates/action.html",
"templates/csn.html",
"templates/file_progress.html",
"templates/info.html",
"templates/message.html",
"templates/message_versions_modal.html",
"templates/spoiler_message.html"
], factory);
}(this, function (
converse,
xss,
emojione,
filesize,
tpl_action,
tpl_csn,
tpl_file_progress,
tpl_info,
tpl_message,
tpl_message_versions_modal,
tpl_spoiler_message
tpl_message_versions_modal
) {
"use strict";
const { Backbone, _, moment } = converse.env;
......@@ -101,7 +97,7 @@
},
render () {
const is_followup = u.hasClass('chat-msg-followup', this.el);
const is_followup = u.hasClass('chat-msg--followup', this.el);
let msg;
if (this.model.isOnlyChatStateNotification()) {
this.renderChatStateNotification()
......@@ -113,7 +109,7 @@
this.renderChatMessage();
}
if (is_followup) {
u.addClass('chat-msg-followup', this.el);
u.addClass('chat-msg--followup', this.el);
}
return this.el;
},
......@@ -135,21 +131,16 @@
},
renderChatMessage () {
let template, text = this.model.get('message');
if (this.isMeCommand()) {
template = tpl_action;
text = this.model.get('message').replace(/^\/me/, '');
} else {
template = this.model.get('is_spoiler') ? tpl_spoiler_message : tpl_message;
}
const moment_time = moment(this.model.get('time')),
const is_me_message = this.isMeCommand(),
moment_time = moment(this.model.get('time')),
role = this.model.vcard.get('role'),
roles = role ? role.split(',') : [];
const msg = u.stringToElement(template(
const msg = u.stringToElement(tpl_message(
_.extend(
this.model.toJSON(), {
'__': __,
'is_me_message': is_me_message,
'roles': roles,
'pretty_time': moment_time.format(_converse.time_format),
'time': moment_time.format(),
......@@ -159,16 +150,20 @@
})
));
var url = this.model.get('oob_url');
const url = this.model.get('oob_url');
if (url) {
msg.querySelector('.chat-msg-media').innerHTML = _.flow(
msg.querySelector('.chat-msg__media').innerHTML = _.flow(
_.partial(u.renderFileURL, _converse),
_.partial(u.renderMovieURL, _converse),
_.partial(u.renderAudioURL, _converse),
_.partial(u.renderImageURL, _converse))(url);
}
const msg_content = msg.querySelector('.chat-msg-text');
let text = this.model.get('message');
if (is_me_message) {
text = text.replace(/^\/me/, '');
}
const msg_content = msg.querySelector('.chat-msg__text');
if (text !== url) {
text = xss.filterXSS(text, {'whiteList': {}});
msg_content.innerHTML = _.flow(
......
<div class="message chat-msg chat-action {{{o.extra_classes}}}" data-isodate="{{{o.time}}}" data-from="{{{o.from}}}">
<span class="chat-msg-heading">
<span class="chat-msg-author">**{{{o.username}}}</span>
</span>
<p class="chat-msg-text"><!-- message gets added here via renderMessage --></p>
</div>
<div class="message chat-msg" data-isodate="{{{o.time}}}" data-msgid="{{{o.msgid}}}">
<canvas class="avatar" height="36" width="36"></canvas>
<div class="chat-msg-content">
<span class="chat-msg-text">Uploading file: <strong>{{{o.file.name}}}</strong>, {{{o.filesize}}}</span>
<canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>
<div class="chat-msg__content">
<span class="chat-msg__text">Uploading file: <strong>{{{o.file.name}}}</strong>, {{{o.filesize}}}</span>
<progress value="{{{o.progress}}}"/>
</div>
</div>
<div class="message chat-msg {{{o.type}}} {{{o.extra_classes}}}" data-isodate="{{{o.time}}}" data-msgid="{{{o.msgid}}}" data-from="{{{o.from}}}">
{[ if (o.type !== 'headline') { ]}
<canvas class="avatar" height="36" width="36"></canvas>
<div class="message chat-msg {{{o.type}}} {[ if (o.is_me_message) { ]} chat-msg--action {[ } ]} {{{o.extra_classes}}}" data-isodate="{{{o.time}}}" data-msgid="{{{o.msgid}}}" data-from="{{{o.from}}}">
{[ if (o.type !== 'headline' && !o.is_me_message) { ]}
<canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>
{[ } ]}
<div class="chat-msg-content">
<span class="chat-msg-heading">
<span class="chat-msg-author">{{{o.username}}}
<div class="chat-msg__content {[ if (o.is_me_message) { ]}chat-msg__content--action{[ } ]}">
<span class="chat-msg__heading">
{[ if (o.is_me_message) { ]}<time timestamp="{{{o.isodate}}}" class="chat-msg__time">{{{o.pretty_time}}}</time>{[ } ]}
<span class="chat-msg__author">{[ if (o.is_me_message) { ]}**{[ }; ]}{{{o.username}}}
{[o.roles.forEach(function (role) { ]} <span class="badge badge-secondary">{{{role}}}</span> {[ }); ]}
</span>
<time timestamp="{{{o.isodate}}}" class="chat-msg-time">{{{o.pretty_time}}}</time>
{[ if (!o.is_me_message) { ]}<time timestamp="{{{o.isodate}}}" class="chat-msg__time">{{{o.pretty_time}}}</time>{[ } ]}
</span>
{[ if (o.edited) { ]} <i title="{{{o.__('This message has been edited')}}}" class="fa fa-edit chat-msg-edited"></i> {[ } ]}
<span class="chat-msg-text"></span>
<div class="chat-msg-media"></div>
{[ if (!o.is_me_message) { ]}<div class="chat-msg__body">{[ } ]}
{[ if (o.edited) { ]} <i title="{{{o.__('This message has been edited')}}}" class="fa fa-edit chat-msg-edited"></i> {[ } ]}
{[ if (!o.is_me_message) { ]}<div class="chat-msg__message">{[ } ]}
{[ if (o.is_spoiler) { ]}
<div class="chat-msg__spoiler-hint">
<span class="spoiler-hint">{{{o.spoiler_hint}}}</span>
<a class="badge badge-info spoiler-toggle" data-toggle-state="closed" href="#"><i class="fa fa-eye"></i>{{{o.label_show}}}</a>
</div>
{[ } ]}
<div class="chat-msg__text{[ if (o.is_spoiler) { ]} spoiler collapsed{[ } ]}"><!-- message gets added here via renderMessage --></div>
<div class="chat-msg__media"></div>
{[ if (!o.is_me_message) { ]}</div>{[ } ]}
{[ if (!o.is_me_message) { ]}</div>{[ } ]}
</div>
</div>
<div class="message chat-msg {{{o.extra_classes}}}" data-isodate="{{{o.time}}}" data-msgid="{{{o.msgid}}}">
<canvas class="avatar" height="36" width="36"></canvas>
<div class="chat-msg-content">
<span class="chat-msg-heading">
<span class="chat-msg-author">{{{o.username}}}</span>
<span class="chat-msg-time">{{{o.pretty_time}}}</span>
</span>
<div>
<span class="spoiler-hint">{{{o.spoiler_hint}}}</span>
<a class="badge badge-info spoiler-toggle" data-toggle-state="closed" href="#"><i class="fa fa-eye"></i>{{{o.label_show}}}</a>
</div>
<div class="chat-msg-text spoiler collapsed"><!-- message gets added here via renderMessage --></div>
</div>
</div>
......@@ -210,6 +210,10 @@
.replace(/"/g, "&quot;");
};
u.escapeURL = function (url) {
return encodeURI(decodeURI(url)).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
};
u.addHyperlinks = function (text) {
return URI.withinString(text, function (url) {
var uri = new URI(url);
......@@ -217,8 +221,8 @@
if (!url.startsWith('http://') && !url.startsWith('https://')) {
url = 'http://' + url;
}
url = encodeURI(decodeURI(url)).replace(/[!'()]/g, escape).replace(/\*/g, "%2A");
return `<a target="_blank" rel="noopener" href="${u.escapeHTML(url)}">${u.escapeHTML(uri.readable())}</a>`;
url = u.escapeHTML(u.escapeURL(url));
return `<a target="_blank" rel="noopener" href="${url}">${u.escapeHTML(uri.readable())}</a>`;
});
};
......@@ -255,7 +259,8 @@
};
u.renderFileURL = function (_converse, url) {
const uri = new URI(url), { __ } = _converse,
const uri = new URI(url),
{ __ } = _converse,
filename = uri.filename();
if (!_.includes(["https", "http"], uri.protocol()) ||
filename.endsWith('mp3') || filename.endsWith('mp4') ||
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment