Add a spoiler message to the mockups

This commit is contained in:
JC Brand 2018-04-26 19:10:06 +02:00
parent 1fe6015787
commit 57f7e31aa1
16 changed files with 173 additions and 85 deletions

View File

@ -7252,8 +7252,6 @@ body.reset {
#conversejs .chatbox {
margin: 0;
width: 100%; } }
#conversejs .chatbox .spoiler {
background-color: #e7f7ee; }
#conversejs .chatbox .box-flyout {
display: flex;
flex-direction: column;
@ -7327,9 +7325,6 @@ body.reset {
border: 0;
background-color: #ffffff;
line-height: 1.3em; }
#conversejs .chatbox .chat-content .toggle-spoiler:before {
padding-right: 0.25em;
whitespace: nowrap; }
#conversejs .chatbox .chat-content video {
width: 100%; }
#conversejs .chatbox .chat-content progress {
@ -8415,6 +8410,16 @@ body.reset {
color: #6899b2; }
#conversejs .message.chat-msg:hover {
background-color: rgba(0, 0, 0, 0.035); }
#conversejs .message.chat-msg .spoiler-hint {
margin-bottom: 1em; }
#conversejs .message.chat-msg .toggle-spoiler {
color: white; }
#conversejs .message.chat-msg .toggle-spoiler i {
color: white;
padding-right: 0.5em; }
#conversejs .message.chat-msg .toggle-spoiler:before {
padding-right: 0.25em;
whitespace: nowrap; }
#conversejs .message.chat-msg .avatar {
background: #818479;
height: 36px;
@ -8427,13 +8432,10 @@ body.reset {
color: #666;
max-width: 100%;
word-wrap: break-word; }
#conversejs .message.chat-msg .chat-msg-text.spoiler {
border-radius: 4px;
padding: 0.5em; }
#conversejs .message.chat-msg .chat-msg-text .emojione {
margin-bottom: -6px; }
#conversejs .message.chat-msg .chat-msg-heading {
padding-bottom: 0.5rem;
padding-bottom: 0.25rem;
display: block; }
#conversejs .message.chat-msg .chat-msg-heading .chat-msg-author {
font-weight: bold; }

View File

@ -7305,8 +7305,6 @@ body {
#conversejs .chatbox {
margin: 0;
width: 100%; } }
#conversejs .chatbox .spoiler {
background-color: #e7f7ee; }
#conversejs .chatbox .box-flyout {
display: flex;
flex-direction: column;
@ -7380,9 +7378,6 @@ body {
border: 0;
background-color: #ffffff;
line-height: 1.3em; }
#conversejs .chatbox .chat-content .toggle-spoiler:before {
padding-right: 0.25em;
whitespace: nowrap; }
#conversejs .chatbox .chat-content video {
width: 100%; }
#conversejs .chatbox .chat-content progress {
@ -8603,6 +8598,16 @@ body {
color: #6899b2; }
#conversejs .message.chat-msg:hover {
background-color: rgba(0, 0, 0, 0.035); }
#conversejs .message.chat-msg .spoiler-hint {
margin-bottom: 0.5em; }
#conversejs .message.chat-msg .toggle-spoiler {
color: white; }
#conversejs .message.chat-msg .toggle-spoiler i {
color: white;
padding-right: 0.5em; }
#conversejs .message.chat-msg .toggle-spoiler:before {
padding-right: 0.25em;
whitespace: nowrap; }
#conversejs .message.chat-msg .avatar {
background: #818479;
height: 36px;
@ -8615,13 +8620,10 @@ body {
color: #666;
max-width: 100%;
word-wrap: break-word; }
#conversejs .message.chat-msg .chat-msg-text.spoiler {
border-radius: 4px;
padding: 0.5em; }
#conversejs .message.chat-msg .chat-msg-text .emojione {
margin-bottom: -6px; }
#conversejs .message.chat-msg .chat-msg-heading {
padding-bottom: 0.5rem;
padding-bottom: 0.25rem;
display: block; }
#conversejs .message.chat-msg .chat-msg-heading .chat-msg-author {
font-weight: bold; }

View File

@ -1,24 +0,0 @@
/*global _ */
window.renderAvatars = function (el) {
const canvasses = el.querySelectorAll('canvas.avatar');
_.each(canvasses, (canvas_el) => {
const avatar_url = canvas_el.getAttribute('data-avatar');
if (!avatar_url) {
return;
}
const ctx = canvas_el.getContext('2d');
const img = new Image();
img.onload = function () {
const canvas = ctx.canvas ;
const hRatio = canvas.width / img.width ;
const vRatio = canvas.height / img.height ;
const ratio = Math.min ( hRatio, vRatio );
const centerShift_x = ( canvas.width - img.width*ratio ) / 2;
const centerShift_y = ( canvas.height - img.height*ratio ) / 2;
ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.drawImage(img, 0,0, img.width, img.height, centerShift_x,centerShift_y,img.width*ratio, img.height*ratio);
};
img.src = avatar_url;
});
}

View File

@ -153,7 +153,9 @@
<script type="text/javascript" src="../../node_modules/lodash/lodash.js"></script>
<script type="text/javascript" src="../../node_modules/backbone/backbone.js"></script>
<script type="text/javascript" src="../../node_modules/backbone.nativeview/backbone.nativeview.js"></script>
<script type="text/javascript" src="avatars.js"></script>
<script type="text/javascript" src="../../node_modules/strophe.js/strophe.js"></script>
<script type="text/javascript" src="../../src/utils/core.js"></script>
<script type="text/javascript" src="utils.js"></script>
<script type="text/javascript" src="sidebar.js"></script>
<script type="text/javascript" src="user-panel.js"></script>
<script type="text/javascript" src="modals.js"></script>
@ -164,7 +166,6 @@
new Modals();
new Sidebar();
new UserPanel();
window.renderAvatars(document.querySelector('.chatbox:not(#controlbox)'));
});
</script>

View File

@ -114,6 +114,23 @@
</div>
</div>
<div class="message chat-msg {{{o.extra_classes}}}" data-isodate="{{{o.time}}}" data-msgid="{{{o.msgid}}}">
<canvas data-avatar="/mockup/images/romeo.jpg" height="36" width="36" class="avatar"></canvas>
<div class="chat-msg-content">
<span class="chat-msg-heading">
<span class="chat-msg-author">Romeo Montague</span>
<span class="chat-msg-time text-muted">19:36</span>
</span>
<div class="spoiler-hint">By a name
<a class="badge badge-info toggle-spoiler" data-toggle-state="closed" href="#"><i class="fa fa-eye"></i>Show more</a>
</div>
<div class="chat-msg-text spoiler collapsed">
I know not how to tell thee who I am: My name, dear saint, is hateful to
myself, Because it is an enemy to thee. Had I it written, I would tear the word.
</div>
</div>
</div>
<div class="message chat-info chat-event" data-isodate="2018-03-07T10:21:09+01:00" data-join="&quot;Mercutio&quot;">Mercutio has entered the room</div>
<div class="message chat-info chat-event" data-isodate="2018-03-07T10:21:09+01:00" data-join="&quot;Mercutio&quot;">Topic set by Mercutio</div>
<div class="message chat-info chat-topic" data-isodate="2018-03-07T10:21:09+01:00">Converse.js: The latest release is 3.3.4. Please be
@ -241,7 +258,9 @@
<script type="text/javascript" src="../../node_modules/lodash/lodash.js"></script>
<script type="text/javascript" src="../../node_modules/backbone/backbone.js"></script>
<script type="text/javascript" src="../../node_modules/backbone.nativeview/backbone.nativeview.js"></script>
<script type="text/javascript" src="avatars.js"></script>
<script type="text/javascript" src="../../node_modules/strophe.js/strophe.js"></script>
<script type="text/javascript" src="../../src/utils/core.js"></script>
<script type="text/javascript" src="utils.js"></script>
<script type="text/javascript" src="sidebar.js"></script>
<script type="text/javascript" src="user-panel.js"></script>
<script type="text/javascript" src="modals.js"></script>
@ -252,7 +271,6 @@
new Modals();
new Sidebar();
new UserPanel();
window.renderAvatars(document.querySelector('.chatroom'));
});
</script>

View File

@ -76,7 +76,9 @@
<script type="text/javascript" src="../../node_modules/backbone/backbone.js"></script>
<script type="text/javascript" src="../../node_modules/backbone.nativeview/backbone.nativeview.js"></script>
<script type="text/javascript" src="avatars.js"></script>
<script type="text/javascript" src="../../node_modules/strophe.js/strophe.js"></script>
<script type="text/javascript" src="../../src/utils/core.js"></script>
<script type="text/javascript" src="utils.js"></script>
<script type="text/javascript" src="sidebar.js"></script>
<script type="text/javascript" src="user-panel.js"></script>
<script type="text/javascript" src="modals.js"></script>

View File

@ -16,7 +16,8 @@ const UserPanel = Backbone.NativeView.extend({
backdrop: 'static', // we don't want to dismiss Modal when Modal or backdrop is the click event target
keyboard: true // we want to dismiss Modal on pressing Esc key
}));
window.renderAvatars(this.el);
window.renderAvatars();
window.initSpoilers();
}
xhr.send();
}

59
mockup/utils.js Normal file
View File

@ -0,0 +1,59 @@
/*global _, converse_utils */
const u = converse_utils;
window.renderAvatars = function (el) {
el = el || document;
const canvasses = el.querySelectorAll('canvas.avatar');
_.each(canvasses, (canvas_el) => {
const avatar_url = canvas_el.getAttribute('data-avatar');
if (!avatar_url) {
return;
}
const ctx = canvas_el.getContext('2d');
const img = new Image();
img.onload = function () {
const canvas = ctx.canvas ;
const hRatio = canvas.width / img.width ;
const vRatio = canvas.height / img.height ;
const ratio = Math.min ( hRatio, vRatio );
const centerShift_x = ( canvas.width - img.width*ratio ) / 2;
const centerShift_y = ( canvas.height - img.height*ratio ) / 2;
ctx.clearRect(0,0,canvas.width, canvas.height);
ctx.drawImage(img, 0,0, img.width, img.height, centerShift_x,centerShift_y,img.width*ratio, img.height*ratio);
};
img.src = avatar_url;
});
}
function toggleSpoilerMessage (ev) {
if (ev && ev.preventDefault) {
ev.preventDefault();
}
const toggle_el = ev.target,
icon_el = toggle_el.firstElementChild;
u.slideToggleElement(
toggle_el.parentElement.parentElement.querySelector('.spoiler')
);
if (toggle_el.getAttribute("data-toggle-state") == "closed") {
toggle_el.textContent = 'Show less';
icon_el.classList.remove("fa-eye");
icon_el.classList.add("fa-eye-slash");
toggle_el.insertAdjacentElement('afterBegin', icon_el);
toggle_el.setAttribute("data-toggle-state", "open");
} else {
toggle_el.textContent = 'Show more';
icon_el.classList.remove("fa-eye-slash");
icon_el.classList.add("fa-eye");
toggle_el.insertAdjacentElement('afterBegin', icon_el);
toggle_el.setAttribute("data-toggle-state", "closed");
}
}
window.initSpoilers = function () {
const spoilers = document.querySelectorAll('.toggle-spoiler');
_.each(spoilers, (spoiler_el) => {
spoiler_el.addEventListener('click', toggleSpoilerMessage);
});
}

View File

@ -112,10 +112,6 @@
width: $mobile-chat-width;
}
.spoiler {
background-color: lighten($chat-head-color, 50%);
}
.box-flyout {
display: flex;
flex-direction: column;
@ -198,10 +194,6 @@
background-color: #ffffff;
line-height: 1.3em;
.toggle-spoiler:before {
padding-right: 0.25em;
whitespace: nowrap;
}
video {
width: 100%
}

View File

@ -86,6 +86,20 @@
background-color: rgba(0, 0, 0, 0.035);
}
.spoiler-hint {
margin-bottom: 0.5em;
}
.toggle-spoiler {
color: white;
i {
color: white;
padding-right: 0.5em;
}
&:before {
padding-right: 0.25em;
whitespace: nowrap;
}
}
.avatar {
background: $gray-color;
height: 36px;
@ -103,17 +117,13 @@
max-width: 100%;
word-wrap: break-word;
&.spoiler {
border-radius: $chatbox-border-radius;
padding: 0.5em;
}
.emojione {
margin-bottom: -6px;
}
}
.chat-msg-heading {
padding-bottom: 0.5rem;
padding-bottom: 0.25rem;
display: block;
.chat-msg-author {

View File

@ -543,7 +543,7 @@
* up when using infinite scroll).
*/
if (this.model.get('scrolled')) {
const next_msg_el = u.getNextElement(message_el, ".chat-message");
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
@ -900,19 +900,21 @@
if (ev && ev.preventDefault) {
ev.preventDefault();
}
const toggle_el = ev.target;
const toggle_el = ev.target,
icon_el = toggle_el.firstElementChild;
u.slideToggleElement(
toggle_el.parentElement.querySelector('.spoiler')
toggle_el.parentElement.parentElement.querySelector('.spoiler')
);
if (toggle_el.getAttribute("data-toggle-state") == "closed") {
toggle_el.textContent = __('Hide hidden message');
toggle_el.classList.remove("icon-eye");
toggle_el.classList.add("icon-eye-blocked");
toggle_el.textContent = __('Show less');
icon_el.classList.remove("fa-eye");
icon_el.classList.add("fa-eye-slash");
toggle_el.setAttribute("data-toggle-state", "open");
} else {
toggle_el.textContent = __('Show hidden message');
toggle_el.classList.remove("icon-eye-blocked");
toggle_el.classList.add("icon-eye");
toggle_el.textContent = __('Show more');
icon_el.classList.remove("fa-eye-slash");
icon_el.classList.add("fa-eye");
toggle_el.setAttribute("data-toggle-state", "closed");
}
},

View File

@ -82,7 +82,7 @@
'time': moment_time.format(),
'username': username,
'extra_classes': this.getExtraMessageClasses(),
'label_show': __('Show hidden message')
'label_show': __('Show more')
})
));

View File

@ -1,4 +1,4 @@
<div class="message chat-message chat-action {{{o.extra_classes}}}" data-isodate="{{{o.time}}}">
<div class="message chat-msg chat-action {{{o.extra_classes}}}" data-isodate="{{{o.time}}}">
<span class="chat-msg-author chat-msg-{{{o.sender}}}">{{{o.pretty_time}}} **{{{o.username}}}</span>
<span class="chat-msg-content"><!-- message gets added here via renderMessage --></span>
</div>

View File

@ -1,4 +1,4 @@
<div class="message chat-message {{{o.extra_classes}}}" data-isodate="{{{o.time}}}" data-msgid="{{{o.msgid}}}">
<div class="message chat-msg {{{o.extra_classes}}}" data-isodate="{{{o.time}}}" data-msgid="{{{o.msgid}}}">
<span class="chat-msg-author chat-msg-{{{o.sender}}}">{{{o.pretty_time}}} {{{o.username}}}:&nbsp;</span>
<span class="chat-msg-content"></span>
<div class="chat-msg-media"></div>

View File

@ -1,6 +1,6 @@
<div class="message chat-message {{{o.extra_classes}}}" data-isodate="{{{o.time}}}" data-msgid="{{{o.msgid}}}">
<div class="message chat-msg {{{o.extra_classes}}}" data-isodate="{{{o.time}}}" data-msgid="{{{o.msgid}}}">
<span class="chat-msg-author chat-msg-{{{o.sender}}}">{{{o.pretty_time}}} {{{o.username}}}:&nbsp;</span>
<div class="spoiler-hint">{{{o.spoiler_hint}}}</div>
<a class="icon-eye toggle-spoiler" data-toggle-state="closed" href="#">{{{o.label_show}}}</a>
<a class="toggle-spoiler" data-toggle-state="closed" href="#"><i class="fa fa-eye"></li>{{{o.label_show}}}</a>
<div class="chat-msg-content spoiler collapsed"><!-- message gets added here via renderMessage --></div>
</div>

View File

@ -8,16 +8,39 @@
//
/*global define, escape, window */
(function (root, factory) {
define([
"sizzle",
"es6-promise",
"lodash.noconflict",
"strophe",
"tpl!audio",
"tpl!file",
"tpl!image",
"tpl!video"
], factory);
if (typeof define === 'function' && define.amd) {
define([
"sizzle",
"es6-promise",
"lodash.noconflict",
"strophe",
"tpl!audio",
"tpl!file",
"tpl!image",
"tpl!video"
], factory);
} else {
// Used by the mockups
const Strophe = {
'Strophe': root.Strophe,
'$build': root.$build,
'$iq': root.$iq,
'$msg': root.$msg,
'$pres': root.$pres,
'SHA1': root.SHA1,
'MD5': root.MD5,
'b64_hmac_sha1': root.b64_hmac_sha1,
'b64_sha1': root.b64_sha1,
'str_hmac_sha1': root.str_hmac_sha1,
'str_sha1': root.str_sha1
};
root.converse_utils = factory(
root.sizzle,
root.Promise,
root._,
Strophe
);
}
}(this, function (
sizzle,
Promise,