Tighten up CSS

- Remove extra padding at top of Android bubbles, via sibling selector
- Don't include .attachments, .quote-wrapper, .content in bubble unless
  we actually need them. This allows for sibling selectors.
- This is a different technique for adding the ReactWrapperView for
  quotes - it is now appended to the DOM instead of attaching to
  something already in the DOM. This allows us to use .remove(), so it's
  a bit cleaner.
- Users of ReactWrapperView can now specify tagName and className
This commit is contained in:
Scott Nonnenberg 2018-04-17 09:39:41 -07:00
parent 30957341e4
commit 26e4e97592
No known key found for this signature in database
GPG key ID: 5F82280C35134661
8 changed files with 54 additions and 20 deletions

View file

@ -279,11 +279,16 @@
</div> </div>
<div class='tail-wrapper {{ innerBubbleClasses }}'> <div class='tail-wrapper {{ innerBubbleClasses }}'>
<div class='inner-bubble'> <div class='inner-bubble'>
<div class='quote-wrapper'></div> {{ #hasAttachments }}
<div class='attachments'></div> <div class='attachments'></div>
<div class='content' dir='auto'> {{ /hasAttachments }}
{{ #message }}<div class='body'>{{ message }}</div>{{ /message }} {{ #hasBody }}
</div> <div class='content' dir='auto'>
{{ #message }}
<div class='body'>{{ message }}</div>
{{ /message }}
</div>
{{ /hasBody }}
</div> </div>
</div> </div>
<div class='meta'> <div class='meta'>

View file

@ -316,7 +316,6 @@
renderErrors() { renderErrors() {
const errors = this.model.get('errors'); const errors = this.model.get('errors');
this.$('.error-icon-container').remove(); this.$('.error-icon-container').remove();
if (this.errorIconView) { if (this.errorIconView) {
this.errorIconView.remove(); this.errorIconView.remove();
@ -437,16 +436,18 @@
}; };
if (this.replyView) { if (this.replyView) {
this.replyView.remove();
this.replyView = null; this.replyView = null;
} else if (contact) { } else if (contact) {
this.listenTo(contact, 'change:color', this.renderQuote); this.listenTo(contact, 'change:color', this.renderQuote);
} }
this.replyView = new Whisper.ReactWrapperView({ this.replyView = new Whisper.ReactWrapperView({
el: this.$('.quote-wrapper'), className: 'quote-wrapper',
Component: window.Signal.Components.Quote, Component: window.Signal.Components.Quote,
props, props,
}); });
this.$('.inner-bubble').prepend(this.replyView.el);
}, },
isImageWithoutCaption() { isImageWithoutCaption() {
const attachments = this.model.get('attachments'); const attachments = this.model.get('attachments');
@ -469,16 +470,23 @@
render() { render() {
const contact = this.model.isIncoming() ? this.model.getContact() : null; const contact = this.model.isIncoming() ? this.model.getContact() : null;
const errors = this.model.get('errors'); const errors = this.model.get('errors');
const attachments = this.model.get('attachments');
const hasErrors = errors && errors.length > 0; const hasErrors = errors && errors.length > 0;
const hasAttachments = attachments && attachments.length > 0;
const message = this.model.get('body');
const hasBody = message || (this.model.isIncoming() && hasErrors);
this.$el.html(Mustache.render(_.result(this, 'template', ''), { this.$el.html(Mustache.render(_.result(this, 'template', ''), {
message: this.model.get('body'), message,
hasBody,
timestamp: this.model.get('sent_at'), timestamp: this.model.get('sent_at'),
sender: (contact && contact.getTitle()) || '', sender: (contact && contact.getTitle()) || '',
avatar: (contact && contact.getAvatar()), avatar: (contact && contact.getAvatar()),
profileName: (contact && contact.getProfileName()), profileName: (contact && contact.getProfileName()),
innerBubbleClasses: this.isImageWithoutCaption() ? '' : 'with-tail', innerBubbleClasses: this.isImageWithoutCaption() ? '' : 'with-tail',
hoverIcon: !hasErrors, hoverIcon: !hasErrors,
hasAttachments,
}, this.render_partials())); }, this.render_partials()));
this.timeStampView.setElement(this.$('.timestamp')); this.timeStampView.setElement(this.$('.timestamp'));
this.timeStampView.update(); this.timeStampView.update();

View file

@ -17,6 +17,8 @@
const { Component, props, onClose } = options; const { Component, props, onClose } = options;
this.render(); this.render();
this.tagName = options.tagName;
this.className = options.className;
this.Component = Component; this.Component = Component;
this.onClose = onClose; this.onClose = onClose;

View file

@ -622,7 +622,6 @@ span.status {
} }
.body { .body {
margin-top: 0.5em;
white-space: pre-wrap; white-space: pre-wrap;
a { a {
@ -630,6 +629,13 @@ span.status {
} }
} }
.attachments + .content {
margin-top: 0.5em;
}
.quote-wrapper + .content {
margin-top: 0.5em;
}
p { p {
margin: 0; margin: 0;
} }

View file

@ -108,6 +108,10 @@ $ios-border-color: rgba(0,0,0,0.1);
.message-container, .message-container,
.message-list { .message-list {
.bubble .content {
margin-top: 0px;
}
.quote { .quote {
border-top-left-radius: 15px; border-top-left-radius: 15px;
border-top-right-radius: 15px; border-top-right-radius: 15px;

View file

@ -214,11 +214,16 @@
</div> </div>
<div class='tail-wrapper {{ innerBubbleClasses }}'> <div class='tail-wrapper {{ innerBubbleClasses }}'>
<div class='inner-bubble'> <div class='inner-bubble'>
<div class='quote-wrapper'></div> {{ #hasAttachments }}
<div class='attachments'></div> <div class='attachments'></div>
<div class='content' dir='auto'> {{ /hasAttachments }}
{{ #message }}<div class='body'>{{ message }}</div>{{ /message }} {{ #hasBody }}
</div> <div class='content' dir='auto'>
{{ #message }}
<div class='body'>{{ message }}</div>
{{ /message }}
</div>
{{ /hasBody }}
</div> </div>
</div> </div>
<div class='meta'> <div class='meta'>

View file

@ -34,11 +34,16 @@ window.Whisper.View.Templates = {
</div> </div>
<div class='tail-wrapper {{ innerBubbleClasses }}'> <div class='tail-wrapper {{ innerBubbleClasses }}'>
<div class='inner-bubble'> <div class='inner-bubble'>
<div class='quote-wrapper'></div> {{ #hasAttachments }}
<div class='attachments'></div> <div class='attachments'></div>
<div class='content' dir='auto'> {{ /hasAttachments }}
{{ #message }}<div class='body'>{{ message }}</div>{{ /message }} {{ #hasBody }}
</div> <div class='content' dir='auto'>
{{ #message }}
<div class='body'>{{ message }}</div>
{{ /message }}
</div>
{{ /hasBody }}
</div> </div>
</div> </div>
<div class='meta'> <div class='meta'>

View file

@ -15,7 +15,6 @@ export class Message extends React.Component<{}, {}> {
<div className="sender" dir="auto" /> <div className="sender" dir="auto" />
<div className="tail-wrapper with-tail"> <div className="tail-wrapper with-tail">
<div className="inner-bubble"> <div className="inner-bubble">
<div className="attachments" />
<p className="content" dir="auto"> <p className="content" dir="auto">
<span className="body"> <span className="body">
Hi there. How are you doing? Feeling pretty good? Awesome. Hi there. How are you doing? Feeling pretty good? Awesome.