drafty previews

This commit is contained in:
or-else
2021-01-13 15:17:56 -08:00
parent a319e2b0bc
commit 4b07c3b5c9
12 changed files with 18402 additions and 15 deletions
+24 -3
View File
@@ -42,7 +42,7 @@ a.gray:focus {
color: #999; color: #999;
} }
a.flat-button { .flat-button {
display: flex; display: flex;
align-items: center; align-items: center;
margin: 0.15rem 0.35rem; margin: 0.15rem 0.35rem;
@@ -55,11 +55,21 @@ a.flat-button {
white-space: nowrap; white-space: nowrap;
text-transform: uppercase; text-transform: uppercase;
} }
a.flat-button:hover, .flat-button:hover,
a.flat-button:focus { .flat-button:focus {
text-decoration: none; text-decoration: none;
} }
.flat-button .faux {
height: 1.5em;
line-height: 1.5em;
text-transform: none;
padding-left: .5rem;
padding-right: .5rem;
border: 1px solid gray;
border-radius: 3px;
}
form { form {
font-size: 1.1rem; font-size: 1.1rem;
padding: 0.5rem 0.75rem; padding: 0.5rem 0.75rem;
@@ -2066,3 +2076,14 @@ ul.tabbar li.active > a:after {
background-color: #1e88e5; background-color: #1e88e5;
border-radius: 0.08rem; border-radius: 0.08rem;
} }
/* Highlighted text */
.highlight {
color: teal;
font-weight: bolder;
}
.highlight .preview {
color: #5f9ea0;
font-weight: inherit;
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -627,7 +627,7 @@ class TinodeWeb extends React.Component {
} }
// Merge search results and contact list to create a single flat // Merge search results and contact list to create a single flat
// list of kown contacts for GroupManager to use. // list of known contacts for GroupManager to use.
static prepareSearchableContacts(chatList, foundContacts) { static prepareSearchableContacts(chatList, foundContacts) {
const merged = {}; const merged = {};
+20 -2
View File
@@ -1,7 +1,7 @@
// Single message, sent or received. // Single message, sent or received.
import React from 'react'; import React from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { Drafty } from 'tinode-sdk' import { Drafty } from 'tinode-sdk';
import Attachment from './attachment.jsx'; import Attachment from './attachment.jsx';
import LetterTile from './letter-tile.jsx'; import LetterTile from './letter-tile.jsx';
@@ -165,12 +165,23 @@ export default class ChatMessage extends React.Component {
import { BROKEN_IMAGE_SIZE, REM_SIZE } from '../config.js'; import { BROKEN_IMAGE_SIZE, REM_SIZE } from '../config.js';
import { fitImageSize } from '../lib/blob-helpers.js'; import { fitImageSize } from '../lib/blob-helpers.js';
// Converts Drafty elements into React classes.
// 'this' is set by the caller.
function draftyFormatter(style, data, values, key) { function draftyFormatter(style, data, values, key) {
if (style == 'EX') {
// attachments are handled elsewhere.
return null;
}
let el = Drafty.tagName(style); let el = Drafty.tagName(style);
if (el) { if (el) {
const attr = Drafty.attrValue(style, data) || {}; const attr = Drafty.attrValue(style, data) || {};
attr.key = key; attr.key = key;
switch (style) { switch (style) {
case 'HL':
// Highlighted text. Assign class name.
attr.className = 'highlight';
break;
case 'IM': case 'IM':
// Additional processing for images // Additional processing for images
if (data) { if (data) {
@@ -210,9 +221,16 @@ function draftyFormatter(style, data, values, key) {
// Form // Form
attr.className = 'bot-form'; attr.className = 'bot-form';
break; break;
case 'FE': case 'RW':
// Form element formatting is dependent on element content. // Form element formatting is dependent on element content.
break; break;
default:
if (el == '_UNKN') {
// Unknown element.
// TODO: make it prettier.
el = <><span className="material-icons">extension</span></>;
}
break;
} }
return React.createElement(el, attr, values); return React.createElement(el, attr, values);
} else { } else {
+55
View File
@@ -3,6 +3,7 @@
import React from 'react'; import React from 'react';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { Drafty } from 'tinode-sdk';
import Tinode from 'tinode-sdk'; import Tinode from 'tinode-sdk';
import Contact from './contact.jsx'; import Contact from './contact.jsx';
@@ -10,6 +11,11 @@ import ContactAction from './contact-action.jsx';
import { makeImageUrl } from '../lib/blob-helpers.js'; import { makeImageUrl } from '../lib/blob-helpers.js';
const junk = {
"ent":[{"data":{"mime":"image/jpeg","name":"hello.jpg","val":"<38992, bytes: ...>","width":100, "height":80},"tp":"EX"}],
"fmt":[{"at":-1, "key":0}]
};
const messages = defineMessages({ const messages = defineMessages({
badge_you: { badge_you: {
id: 'badge_you', id: 'badge_you',
@@ -70,6 +76,7 @@ class ContactList extends React.Component {
badges.push({name: formatMessage(messages.badge_owner), color: 'blue'}); badges.push({name: formatMessage(messages.badge_owner), color: 'blue'});
} }
} }
// const comment = React.createElement(React.Fragment, null, Drafty.format(junk, draftyFormatter, this));
const comment = Array.isArray(c.private) ? const comment = Array.isArray(c.private) ?
c.private.join(',') : (c.private ? c.private.comment : null); c.private.join(',') : (c.private ? c.private.comment : null);
@@ -118,4 +125,52 @@ class ContactList extends React.Component {
} }
}; };
// Converts Drafty elements into a one-line preview.
function draftyFormatter(style, data, values, key) {
let el = Drafty.tagName(style);
const attr = { key: key };
if (el) {
switch (style) {
case 'HL':
// Make highlight less prominent in preview.
attr.className = 'highlight preview';
break;
case 'LN':
// Disable links in previews.
el = 'span';
break;
case 'IM':
// Replace image with '[icon] Image'.
el = React.Fragment;
values = [<i className="material-icons">photo</i>, 'Picture'];
break;
case 'BN':
el = 'span';
attr.className = 'flat-button faux';
break;
case 'FM':
el = React.Fragment;
values = [<i className="material-icons">dashboard</i>, 'Form:'];
break;
case 'RW':
el = React.Fragment;
break;
case 'EX':
el = React.Fragment;
values = [<i className="material-icons">attachment</i>, 'Attachment'];
break;
default:
if (el == '_UNKN') {
el = React.Fragment;
values = [<i className="material-icons">extension</i>];
}
break;
}
return React.createElement(el, attr, values);
} else {
return values;
}
};
export default injectIntl(ContactList); export default injectIntl(ContactList);
+10541 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+7754 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -26,7 +26,7 @@ module.exports = (env, argv) => {
publicPath: '/umd/' publicPath: '/umd/'
}, },
optimization: { optimization: {
minimize: true, minimize: (argv.mode === 'production'),
minimizer: [ minimizer: [
new TerserPlugin({ new TerserPlugin({
terserOptions: { terserOptions: {