merge devel

This commit is contained in:
or-else
2025-02-08 19:50:34 +03:00
133 changed files with 9381 additions and 9444 deletions
+10 -2
View File
@@ -159,6 +159,7 @@ class BaseChatMessage extends React.PureComponent {
const sideClass = this.props.sequence + ' ' + (this.props.response ? 'left' : 'right');
const bubbleClass = (this.props.sequence == 'single' || this.props.sequence == 'last') ? 'bubble tip' : 'bubble';
const avatar = this.props.userAvatar || true;
let textSizeClass = 'message-content';
const fullDisplay = (this.props.isGroup && this.props.response &&
(this.props.sequence == 'single' || this.props.sequence == 'last'));
@@ -185,7 +186,14 @@ class BaseChatMessage extends React.PureComponent {
}, this);
const tree = Drafty.format(content, fullFormatter, this.formatterContext);
content = React.createElement(React.Fragment, null, tree);
} else if (typeof content != 'string') {
} else if (typeof content == 'string') {
// Make font bigger for emoji-only messages.
// Must use 'new RegExp(...)' because React does not like /{1-5}/.
if (new RegExp('^\\p{RGI_Emoji}{1,5}$', 'v').test(content || '')) {
// Content consists of 1-5 emoji characters. Count how many and use it to increase the font size.
textSizeClass += ' emoji-' + (content || '').match(/\p{RGI_Emoji}/vg).length;
}
} else {
content = <><i className="material-icons gray">warning_amber</i> <i className="gray">
<FormattedMessage id="invalid_content"
defaultMessage="invalid content" description="Shown when the message is unreadable" /></i></>
@@ -207,7 +215,7 @@ class BaseChatMessage extends React.PureComponent {
<div>
<div className={bubbleClass}>
<div className="content-meta">
<div className="message-content">
<div className={textSizeClass}>
{content}
{attachments}
</div>
+5 -1
View File
@@ -5,6 +5,7 @@ import SendMessage from './send-message.jsx';
import { REM_SIZE } from '../config.js';
import { fitImageSize } from '../lib/blob-helpers.js';
import { bytesToHumanSize, shortenFileName } from '../lib/strformat.js';
import { urlAsAttachment } from '../lib/utils.js';
export default class ImagePreview extends React.PureComponent {
constructor(props) {
@@ -71,13 +72,16 @@ export default class ImagePreview extends React.PureComponent {
const width = this.props.content.width || '-';
const height = this.props.content.height || '-';
const download_url = urlAsAttachment(this.props.content.url);
return (
<div id="image-preview">
<div id="image-preview-caption-panel">
{this.props.onSendMessage ?
<span>{fname}</span>
:
<a href={this.props.content.url} download={this.props.content.filename}>
<a href={download_url} download={this.props.content.filename}>
<i className="material-icons">file_download</i> <FormattedMessage
id="download_action" defaultMessage="download" description="Call to action [download]" />
</a>
+20 -2
View File
@@ -1,6 +1,9 @@
import QRCode from 'qrcodejs';
import React from 'react';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import { QRCODE_SIZE } from '../config';
const messages = defineMessages({
invalid_id: {
id: 'error_invalid_id',
@@ -13,6 +16,8 @@ class NewTopicById extends React.PureComponent {
constructor(props) {
super(props);
this.qrCodeRef = React.createRef();
this.state = {
groupId: '',
};
@@ -22,6 +27,14 @@ class NewTopicById extends React.PureComponent {
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
new QRCode(this.qrCodeRef.current, {
text: this.props.myURI,
width: QRCODE_SIZE,
height: QRCODE_SIZE,
});
}
handleChange(e) {
this.setState({groupId: e.target.value});
}
@@ -36,7 +49,7 @@ class NewTopicById extends React.PureComponent {
e.preventDefault();
if (this.state.groupId) {
const name = this.state.groupId.trim();
const prefix = name.substr(0, 3);
const prefix = name.substring(0, 3);
if (name.length > 3 && ['usr', 'grp', 'chn'].includes(prefix)) {
this.props.onSubmit(name);
} else {
@@ -53,7 +66,7 @@ class NewTopicById extends React.PureComponent {
description="Prompt for entering user or group ID">{
(prompt) => <input type="text" placeholder={prompt}
value={this.state.groupId} onChange={this.handleChange}
onKeyPress={this.handleKeyPress} required autoFocus />
onKeyDown={this.handleKeyPress} required autoFocus />
}</FormattedMessage>
</div>
<div className="dialog-buttons">
@@ -62,6 +75,11 @@ class NewTopicById extends React.PureComponent {
description="Button [Subscribe]" />
</button>
</div>
<br />
<div className="panel-form-column">
<label className="small">Scan my ID:</label>
<div className="qr-code" ref={this.qrCodeRef} />
</div>
</div>
);
}
+34
View File
@@ -0,0 +1,34 @@
import QRCode from 'qrcodejs';
import React from 'react';
import { FormattedMessage } from 'react-intl';
import { QRCODE_SIZE } from '../config';
export default class ShowQRCode extends React.PureComponent {
constructor(props) {
super(props);
this.qrCodeRef = React.createRef();
}
componentDidMount() {
new QRCode(this.qrCodeRef.current, {
text: this.props.uri,
width: QRCODE_SIZE,
height: QRCODE_SIZE,
});
}
render() {
return (
<div className="panel-form-column">
<br />
<div className="qr-code" ref={this.qrCodeRef} />
<div className="dialog-buttons">
<button className="outline" onClick={this.props.onCancel}>
<FormattedMessage id="button_ok" defaultMessage="OK" description="Button [OK]" />
</button>
</div>
</div>
);
}
};