drafty previews
This commit is contained in:
+24
-3
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -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 = {};
|
||||||
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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',
|
||||||
@@ -25,7 +31,7 @@ const messages = defineMessages({
|
|||||||
|
|
||||||
class ContactList extends React.Component {
|
class ContactList extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
const {formatMessage} = this.props.intl;
|
const { formatMessage } = this.props.intl;
|
||||||
const showCheckmark = Array.isArray(this.props.topicSelected);
|
const showCheckmark = Array.isArray(this.props.topicSelected);
|
||||||
const contactNodes = [];
|
const contactNodes = [];
|
||||||
let contactsCount = 0;
|
let contactsCount = 0;
|
||||||
@@ -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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+7754
-1
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
+1
-1
@@ -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: {
|
||||||
|
|||||||
Reference in New Issue
Block a user