Message display improvements

* Checkmark and edit modal button are now on the right
* Instead of showing checkmarks for MUC messages,
  we now show them as light grey before MUC reflection
* Simplify message markup by requiring less `if` statements
This commit is contained in:
JC Brand 2019-06-03 21:53:19 +02:00
parent f2ac9ef4d7
commit 1d9bbb8ddd
6 changed files with 42 additions and 24 deletions

View File

@ -130,7 +130,21 @@
margin-left: 0.5rem; margin-left: 0.5rem;
width: calc(100% - var(--message-avatar-width)); width: calc(100% - var(--message-avatar-width));
} }
.chat-msg__content--me {
.chat-msg__body--groupchat {
.chat-msg__text {
color: var(--subdued-color);
}
&.chat-msg__body--delayed .chat-msg__text,
&.chat-msg__body--received .chat-msg__text {
color: var(--message-text-color);
}
}
}
.chat-msg__content--action { .chat-msg__content--action {
width: 100%;
margin-left: 0; margin-left: 0;
} }
@ -164,8 +178,8 @@
} }
.chat-msg__text { .chat-msg__text {
padding: 0;
color: var(--message-text-color); color: var(--message-text-color);
padding: 0;
width: 100%; width: 100%;
white-space: pre-wrap; white-space: pre-wrap;
a { a {
@ -255,7 +269,7 @@
} }
&.chat-msg--action { &.chat-msg--action {
.chat-msg__content { .chat-msg__content {
flex-wrap: wrap; flex-wrap: nowrap;
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
} }
@ -286,6 +300,7 @@
} }
.chat-msg__content { .chat-msg__content {
margin-left: 2.75rem; margin-left: 2.75rem;
width: 100%;
} }
} }

View File

@ -2301,7 +2301,7 @@
expect(view.model.messages.last().get('affiliation')).toBe('owner'); expect(view.model.messages.last().get('affiliation')).toBe('owner');
expect(view.model.messages.last().get('role')).toBe('moderator'); expect(view.model.messages.last().get('role')).toBe('moderator');
expect(view.el.querySelectorAll('.chat-msg').length).toBe(1); expect(view.el.querySelectorAll('.chat-msg').length).toBe(1);
expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author chat-msg__me moderator'); expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author moderator');
let presence = $pres({ let presence = $pres({
to:'romeo@montague.lit/orchard', to:'romeo@montague.lit/orchard',
@ -2328,7 +2328,7 @@
expect(view.model.messages.last().get('affiliation')).toBe('member'); expect(view.model.messages.last().get('affiliation')).toBe('member');
expect(view.model.messages.last().get('role')).toBe('participant'); expect(view.model.messages.last().get('role')).toBe('participant');
expect(view.el.querySelectorAll('.chat-msg').length).toBe(2); expect(view.el.querySelectorAll('.chat-msg').length).toBe(2);
expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author chat-msg__me participant'); expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author participant');
presence = $pres({ presence = $pres({
to:'romeo@montague.lit/orchard', to:'romeo@montague.lit/orchard',
@ -2348,7 +2348,7 @@
expect(view.model.messages.last().get('affiliation')).toBe('owner'); expect(view.model.messages.last().get('affiliation')).toBe('owner');
expect(view.model.messages.last().get('role')).toBe('moderator'); expect(view.model.messages.last().get('role')).toBe('moderator');
expect(view.el.querySelectorAll('.chat-msg').length).toBe(3); expect(view.el.querySelectorAll('.chat-msg').length).toBe(3);
expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author chat-msg__me moderator'); expect(sizzle('.chat-msg__author', view.el).pop().classList.value.trim()).toBe('chat-msg__author moderator');
done(); done();
})); }));
@ -2562,21 +2562,24 @@
keyCode: 13 // Enter keyCode: 13 // Enter
}); });
await new Promise((resolve, reject) => view.once('messageInserted', resolve)); await new Promise((resolve, reject) => view.once('messageInserted', resolve));
expect(view.el.querySelectorAll('.chat-msg__body.chat-msg__body--received').length).toBe(0);
const msg_obj = view.model.messages.at(0); const msg_obj = view.model.messages.at(0);
const stanza = u.toStanza(` const stanza = u.toStanza(`
<message xmlns="jabber:client" <message xmlns="jabber:client"
from="${msg_obj.get('from')}" from="${msg_obj.get('from')}"
to="${_converse.connection.jid}" to="${_converse.connection.jid}"
type="groupchat"> type="groupchat">
<body>${msg_obj.get('message')}</body> <msg_body>${msg_obj.get('message')}</msg_body>
<stanza-id xmlns="urn:xmpp:sid:0" <stanza-id xmlns="urn:xmpp:sid:0"
id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad" id="5f3dbc5e-e1d3-4077-a492-693f3769c7ad"
by="lounge@montague.lit"/> by="lounge@montague.lit"/>
<origin-id xmlns="urn:xmpp:sid:0" id="${msg_obj.get('origin_id')}"/> <origin-id xmlns="urn:xmpp:sid:0" id="${msg_obj.get('origin_id')}"/>
</message>`); </message>`);
await view.model.onMessage(stanza); await view.model.onMessage(stanza);
await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-msg__receipt').length, 500); await test_utils.waitUntil(() => view.el.querySelectorAll('.chat-msg__body.chat-msg__body--received').length, 500);
expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(1); expect(view.el.querySelectorAll('.chat-msg__receipt').length).toBe(0);
expect(view.el.querySelectorAll('.chat-msg__body.chat-msg__body--received').length).toBe(1);
expect(view.model.messages.length).toBe(1); expect(view.model.messages.length).toBe(1);
const message = view.model.messages.at(0); const message = view.model.messages.at(0);

View File

@ -164,6 +164,7 @@ converse.plugins.add('converse-message-view', {
Object.assign( Object.assign(
this.model.toJSON(), { this.model.toJSON(), {
'__': __, '__': __,
'is_groupchat_message': this.model.get('type') === 'groupchat',
'is_me_message': is_me_message, 'is_me_message': is_me_message,
'roles': roles, 'roles': roles,
'pretty_time': time.format(_converse.time_format), 'pretty_time': time.format(_converse.time_format),

View File

@ -397,7 +397,7 @@ converse.plugins.add('converse-chatboxes', {
// Overridden in converse-muc and converse-mam // Overridden in converse-muc and converse-mam
const attrs = this.getUpdatedMessageAttributes(message, stanza); const attrs = this.getUpdatedMessageAttributes(message, stanza);
if (attrs) { if (attrs) {
message.save(attrs, {'patch': true}); message.save(attrs);
} }
}, },

View File

@ -1308,9 +1308,8 @@ converse.plugins.add('converse-muc', {
*/ */
async onMessage (stanza) { async onMessage (stanza) {
this.fetchFeaturesIfConfigurationChanged(stanza); this.fetchFeaturesIfConfigurationChanged(stanza);
const original_stanza = stanza;
const original_stanza = stanza, const forwarded = sizzle(`forwarded[xmlns="${Strophe.NS.FORWARD}"]`, stanza).pop();
forwarded = sizzle(`forwarded[xmlns="${Strophe.NS.FORWARD}"]`, stanza).pop();
if (forwarded) { if (forwarded) {
stanza = forwarded.querySelector('message'); stanza = forwarded.querySelector('message');
} }

View File

@ -3,20 +3,19 @@
{[ if (o.type !== 'headline' && !o.is_me_message) { ]} {[ if (o.type !== 'headline' && !o.is_me_message) { ]}
<canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas> <canvas class="avatar chat-msg__avatar" height="36" width="36"></canvas>
{[ } ]} {[ } ]}
<div class="chat-msg__content {[ if (o.is_me_message) { ]}chat-msg__content--action{[ } ]}"> <div class="chat-msg__content chat-msg__content--{{{o.sender}}} {{{o.is_me_message ? 'chat-msg__content--action' : ''}}}">
<span class="chat-msg__heading"> <span class="chat-msg__heading">
{[ if (o.is_me_message) { ]}<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 class="chat-msg__author chat-msg__{{{o.sender}}} {{{o.type === 'groupchat' && o.role ? o.role : ''}}}">{[ if (o.is_me_message) { ]}**{[ }; ]}{{{o.username}}}</span> <span class="chat-msg__author {{{o.is_groupchat_message && o.role ? o.role : ''}}}">{[ if (o.is_me_message) { ]}**{[ }; ]}{{{o.username}}}</span>
{[ if (!o.is_me_message) { ]} {[ if (!o.is_me_message) { ]}
{[o.roles.forEach(function (role) { ]} <span class="badge badge-secondary">{{{role}}}</span> {[ }); ]} {[o.roles.forEach(function (role) { ]} <span class="badge badge-secondary">{{{role}}}</span> {[ }); ]}
<time timestamp="{{{o.isodate}}}" class="chat-msg__time">{{{o.pretty_time}}}</time> <time timestamp="{{{o.isodate}}}" class="chat-msg__time">{{{o.pretty_time}}}</time>
{[ } ]} {[ } ]}
{[ if (o.is_encrypted) { ]}<span class="fa fa-lock"></span>{[ } ]} {[ if (o.is_encrypted) { ]}<span class="fa fa-lock"></span>{[ } ]}
</span> </span>
{[ if (!o.is_me_message) { ]}<div class="chat-msg__body">{[ } ]} <div class="chat-msg__body chat-msg__body--{{{o.type}}} {{{o.received ? 'chat-msg__body--received' : '' }}} {{{o.is_delayed ? 'chat-msg__body--delayed' : '' }}}">
{[ if (o.received && !o.is_me_message) { ]} <span class="fa fa-check chat-msg__receipt"></span> {[ } ]}
{[ if (o.edited) { ]} <i title="{{{o.__('This message has been edited')}}}" class="fa fa-edit chat-msg__edit-modal"></i> {[ } ]} <div class="chat-msg__message">
{[ if (!o.is_me_message) { ]}<div class="chat-msg__message">{[ } ]}
{[ if (o.is_spoiler) { ]} {[ if (o.is_spoiler) { ]}
<div class="chat-msg__spoiler-hint"> <div class="chat-msg__spoiler-hint">
<span class="spoiler-hint">{{{o.spoiler_hint}}}</span> <span class="spoiler-hint">{{{o.spoiler_hint}}}</span>
@ -30,13 +29,14 @@
{[ if (o.is_single_emoji) { ]} chat-msg__text--larger{[ } ]} {[ if (o.is_single_emoji) { ]} chat-msg__text--larger{[ } ]}
{[ if (o.is_spoiler) { ]} spoiler collapsed{[ } ]}"><!-- message gets added here via renderMessage --></div> {[ if (o.is_spoiler) { ]} spoiler collapsed{[ } ]}"><!-- message gets added here via renderMessage --></div>
<div class="chat-msg__media"></div> <div class="chat-msg__media"></div>
{[ if (!o.is_me_message) { ]}</div>{[ } ]}
{[ if (o.type !== 'headline' && !o.is_me_message && o.sender === 'me') { ]}
<div class="chat-msg__actions">
<button class="chat-msg__action chat-msg__action-edit fa fa-pencil-alt" title="{{{o.__('Edit this message')}}}"></button>
</div> </div>
{[ if (o.received && !o.is_me_message && !o.is_groupchat_message) { ]} <span class="fa fa-check chat-msg__receipt"></span> {[ } ]}
{[ if (o.edited) { ]} <i title="{{{o.__('This message has been edited')}}}" class="fa fa-edit chat-msg__edit-modal"></i> {[ } ]}
{[ if (o.type !== 'headline' && o.sender === 'me') { ]}
<div class="chat-msg__actions">
<button class="chat-msg__action chat-msg__action-edit fa fa-pencil-alt" title="{{{o.__('Edit this message')}}}"></button>
</div>
{[ } ]} {[ } ]}
</div>
{[ if (!o.is_me_message) { ]}</div>{[ } ]}
</div> </div>
</div> </div>