add QR code display

This commit is contained in:
or-else
2024-02-02 16:26:49 -08:00
parent f932b973f8
commit 9eaa172030
65 changed files with 399 additions and 86 deletions
+6 -1
View File
@@ -1203,7 +1203,7 @@ img.channel {
flex-grow: 0;
padding: 0.5rem 0.75rem;
line-height: 1.5;
overflow-x: hidden;
overflow-x: clip;
}
/* Make sure padding is only applied at the top level panel */
@@ -1410,6 +1410,11 @@ img.channel {
vertical-align: top;
}
/* Div holding QR code */
.qr-code {
align-self: center;
}
/* Scrollable panel where the messages are shown */
#messages-panel {
position: relative;
+1 -1
View File
File diff suppressed because one or more lines are too long
+2
View File
@@ -34,6 +34,8 @@
<script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/react-dom@18/umd/react-dom.development.js"></script>
<!-- React-Intl for translations -->
<script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/react-intl@6/react-intl.iife.js"></script>
<!-- Displaying QR code with ID of the topic -->
<script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.js"></script>
</head>
<body>
+1
View File
@@ -26,6 +26,7 @@
<script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/react@18.2.0/umd/react.production.min.js"></script>
<script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/react-dom@18.2.0/umd/react-dom.production.min.js"></script>
<script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/react-intl@6.4.4/react-intl.iife.min.js"></script>
<script crossorigin="anonymous" src="https://cdn.jsdelivr.net/npm/qrcodejs@1.0.0/qrcode.min.js"></script>
</head>
<body>
<noscript><div id="noscript-message"><div id="noscript-title">Javascript support is required.</div>
+12 -6
View File
@@ -1,20 +1,21 @@
{
"name": "tinode-webapp",
"version": "0.22.10",
"version": "0.22.11",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "tinode-webapp",
"version": "0.22.10",
"version": "0.22.11",
"license": "Apache-2.0",
"dependencies": {
"firebase": "^10.1.0",
"libphonenumber-js": "^1.10.40",
"qrcodejs": "^1.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-intl": "^6.4.4",
"tinode-sdk": "^0.22.10",
"tinode-sdk": "^0.22.11",
"webm-duration-fix": "^1.0.4"
},
"devDependencies": {
@@ -5851,6 +5852,11 @@
"node": ">=6"
}
},
"node_modules/qrcodejs": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/qrcodejs/-/qrcodejs-1.0.0.tgz",
"integrity": "sha512-67rj3mMBhSBepaD57qENnltO+r8rSYlqM7HGThks/BiyDAkc86sLvkKqjkqPS5v13f7tvnt6dbEf3qt7zq+BCg=="
},
"node_modules/queue-microtask": {
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
@@ -6574,9 +6580,9 @@
"dev": true
},
"node_modules/tinode-sdk": {
"version": "0.22.10",
"resolved": "https://registry.npmjs.org/tinode-sdk/-/tinode-sdk-0.22.10.tgz",
"integrity": "sha512-+Uzt/BySCsuJVyxrKSm+bg0BPWHytM1+mjbXnR3G5uF7ZzXuzHsFRCZ2Xb/ZOnvO3LfpV9YvWKzEub4A/ifuyA=="
"version": "0.22.11",
"resolved": "https://registry.npmjs.org/tinode-sdk/-/tinode-sdk-0.22.11.tgz",
"integrity": "sha512-3RFnXBQKSRltCKEcBwTx/FKCYhz68VX1C3L86Cg0oOc4LdwxE0lo8ZsMTqi8vfnO+R4El/UW1O9jjP15sYAXcQ=="
},
"node_modules/to-fast-properties": {
"version": "2.0.0",
+1
View File
@@ -67,6 +67,7 @@
"dependencies": {
"firebase": "^10.1.0",
"libphonenumber-js": "^1.10.40",
"qrcodejs": "^1.0.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-intl": "^6.4.4",
+3
View File
@@ -129,3 +129,6 @@ export const IMMEDIATE_P2P_SUBSCRIPTION = false;
// URL schemes permitted to appear in links (i.e. no javascript: scheme).
export const CLICKABLE_URL_SCHEMES = ['http', 'https', 'ftp', 'ftps'];
// Size of the QR code in the app.
export const QRCODE_SIZE = 128;
+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
+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
+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
+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
+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
+1 -1
View File
File diff suppressed because one or more lines are too long
+7
View File
@@ -1640,5 +1640,12 @@
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
},
"scan_qr_code": {
"translation": "QR-Code scannen",
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code",
"missing": false,
"obsolete": false
}
}
+7
View File
@@ -1640,5 +1640,12 @@
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
},
"scan_qr_code": {
"translation": "Scan QR Code",
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code",
"missing": false,
"obsolete": false
}
}
+7
View File
@@ -1640,5 +1640,12 @@
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
},
"scan_qr_code": {
"translation": "Escanear código QR",
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code",
"missing": false,
"obsolete": false
}
}
+4
View File
@@ -796,6 +796,10 @@
"defaultMessage": "save",
"description": "Call to save an attachment"
},
"scan_qr_code": {
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code"
},
"search_for_contacts": {
"defaultMessage": "Use search to find contacts",
"description": "Text shown in contacts view when user entered no search query."
+7
View File
@@ -1640,5 +1640,12 @@
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
},
"scan_qr_code": {
"translation": "Scanner le code QR",
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code",
"missing": false,
"obsolete": false
}
}
+7
View File
@@ -1640,5 +1640,12 @@
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
},
"scan_qr_code": {
"translation": "QR 코드 스캔",
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code",
"missing": false,
"obsolete": false
}
}
+7
View File
@@ -1640,5 +1640,12 @@
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
},
"scan_qr_code": {
"translation": "Scanați codul QR",
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code",
"missing": false,
"obsolete": false
}
}
+7
View File
@@ -1640,5 +1640,12 @@
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
},
"scan_qr_code": {
"translation": "Отсканируйте QR код",
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code",
"missing": false,
"obsolete": false
}
}
+7
View File
@@ -1640,5 +1640,12 @@
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
},
"scan_qr_code": {
"translation": "สแกนรหัส QR",
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code",
"missing": false,
"obsolete": false
}
}
+7
View File
@@ -1640,5 +1640,12 @@
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
},
"scan_qr_code": {
"translation": "Відскануйте QR-код",
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code",
"missing": false,
"obsolete": false
}
}
+7
View File
@@ -1640,5 +1640,12 @@
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
},
"scan_qr_code": {
"translation": "掃描二維碼",
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code",
"missing": false,
"obsolete": false
}
}
+7
View File
@@ -1640,5 +1640,12 @@
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
},
"scan_qr_code": {
"translation": "扫描二维码",
"defaultMessage": "Scan QR Code",
"description": "Title for scanning QR code",
"missing": false,
"obsolete": false
}
}
+37 -4
View File
@@ -12,6 +12,7 @@ import ErrorPanel from '../widgets/error-panel.jsx';
import GroupManager from '../widgets/group-manager.jsx';
import MenuCancel from '../widgets/menu-cancel.jsx';
import PermissionsEditor from '../widgets/permissions-editor.jsx';
import ShowQRCode from '../widgets/show-qrcode.jsx';
import TopicCommonView from './topic-common-view.jsx';
import TopicSecurity from '../widgets/topic-security.jsx';
@@ -76,6 +77,11 @@ const messages = defineMessages({
defaultMessage: 'Edit permissions',
description: 'Menu item [Edit permissions]'
},
qrcode: {
id: 'scan_qr_code',
defaultMessage: 'Scan QR Code',
description: 'Title for scanning QR code'
},
});
class InfoView extends React.Component {
@@ -120,6 +126,8 @@ class InfoView extends React.Component {
this.handleUnarchive = this.handleUnarchive.bind(this);
this.handlePermissionsChanged = this.handlePermissionsChanged.bind(this);
this.handleLaunchPermissionsEditor = this.handleLaunchPermissionsEditor.bind(this);
this.handleCopyID = this.handleCopyID.bind(this);
this.handleShowQRCode = this.handleShowQRCode.bind(this);
this.handleShowAddMembers = this.handleShowAddMembers.bind(this);
this.handleMemberUpdateRequest = this.handleMemberUpdateRequest.bind(this);
this.handleMemberSelected = this.handleMemberSelected.bind(this);
@@ -368,6 +376,16 @@ class InfoView extends React.Component {
this.props.onNavigate(`perm/${which}`);
}
handleCopyID(e) {
e.preventDefault();
navigator.clipboard.writeText(this.props.myUserId);
}
handleShowQRCode(e) {
e.preventDefault();
this.props.onNavigate('qrcode');
}
handleShowAddMembers(e) {
e.preventDefault();
this.props.onInitFind();
@@ -514,6 +532,11 @@ class InfoView extends React.Component {
onLaunchPermissionsEditor={this.handleLaunchPermissionsEditor}
onNavigate={this.props.onNavigate} />
:
view == 'qrcode' ?
<ShowQRCode
uri={Tinode.URI_TOPIC_ID_PREFIX + this.props.tinode.myUserId}
onCancel={this.handleBackNavigate} />
:
<div id="info-view-content" className="scrollable-panel">
<div className="panel-form-column">
<a href="#" className="flat-button float-right" onClick={(e) => {e.preventDefault(); this.props.onNavigate('general');}}>
@@ -546,10 +569,20 @@ class InfoView extends React.Component {
</div>
: null
}
<div className="group">
<label className="small"><FormattedMessage id="label_user_id" defaultMessage="ID:"
description="Label for user address (ID)" /></label>&nbsp;
<tt>{this.state.address}</tt>
<div className="panel-form-row">
<div>
<label className="small"><FormattedMessage id="label_user_id" defaultMessage="ID:"
description="Label for user address (ID)" /></label>&nbsp;
<tt>{this.state.address}</tt>
</div>
<div style={{marginLeft: 'auto'}}>
&nbsp;<a href="#" onClick={this.handleCopyID}>
<i className="material-icons">content_copy</i>
</a>&nbsp;
&nbsp;<a href="#" onClick={this.handleShowQRCode}>
<i className="material-icons">qr_code</i>
</a>&nbsp;
</div>
</div>
<div className="group">
<BadgeList trustedBadges={this.state.trustedBadges} />
+1
View File
@@ -113,6 +113,7 @@ class NewTopicView extends React.Component {
onError={this.props.onError} /> :
this.state.tabSelected === 'byid' ?
<NewTopicById
myURI={Tinode.URI_TOPIC_ID_PREFIX + this.props.tinode.getCurrentUserID()}
onSubmit={this.handleGroupByID}
onError={this.props.onError} /> :
<div className="flex-column">
+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>
);
}
};
+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
+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
+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
+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
+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
+1 -1
View File
File diff suppressed because one or more lines are too long
+159 -33
View File
@@ -2239,6 +2239,7 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export */ NEW_GRP_ACCESS_MODE: () => (/* binding */ NEW_GRP_ACCESS_MODE),
/* harmony export */ NO_ACCESS_MODE: () => (/* binding */ NO_ACCESS_MODE),
/* harmony export */ NO_DIMENSIONS_VIDEO: () => (/* binding */ NO_DIMENSIONS_VIDEO),
/* harmony export */ QRCODE_SIZE: () => (/* binding */ QRCODE_SIZE),
/* harmony export */ QUOTED_REPLY_LENGTH: () => (/* binding */ QUOTED_REPLY_LENGTH),
/* harmony export */ READ_DELAY: () => (/* binding */ READ_DELAY),
/* harmony export */ REM_SIZE: () => (/* binding */ REM_SIZE),
@@ -2293,6 +2294,7 @@ const LINK_PRIVACY_POLICY = 'https://tinode.co/privacy.html';
const LINK_TERMS_OF_SERVICE = 'https://tinode.co/terms.html';
const IMMEDIATE_P2P_SUBSCRIPTION = false;
const CLICKABLE_URL_SCHEMES = ['http', 'https', 'ftp', 'ftps'];
const QRCODE_SIZE = 128;
/***/ }),
@@ -4189,11 +4191,13 @@ __webpack_require__.r(__webpack_exports__);
/* harmony import */ var _widgets_group_manager_jsx__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ../widgets/group-manager.jsx */ "./src/widgets/group-manager.jsx");
/* harmony import */ var _widgets_menu_cancel_jsx__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../widgets/menu-cancel.jsx */ "./src/widgets/menu-cancel.jsx");
/* harmony import */ var _widgets_permissions_editor_jsx__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../widgets/permissions-editor.jsx */ "./src/widgets/permissions-editor.jsx");
/* harmony import */ var _topic_common_view_jsx__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./topic-common-view.jsx */ "./src/views/topic-common-view.jsx");
/* harmony import */ var _widgets_topic_security_jsx__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ../widgets/topic-security.jsx */ "./src/widgets/topic-security.jsx");
/* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../config.js */ "./src/config.js");
/* harmony import */ var _lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../lib/blob-helpers.js */ "./src/lib/blob-helpers.js");
/* harmony import */ var _lib_utils_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../lib/utils.js */ "./src/lib/utils.js");
/* harmony import */ var _widgets_show_qrcode_jsx__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../widgets/show-qrcode.jsx */ "./src/widgets/show-qrcode.jsx");
/* harmony import */ var _topic_common_view_jsx__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./topic-common-view.jsx */ "./src/views/topic-common-view.jsx");
/* harmony import */ var _widgets_topic_security_jsx__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../widgets/topic-security.jsx */ "./src/widgets/topic-security.jsx");
/* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ../config.js */ "./src/config.js");
/* harmony import */ var _lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ../lib/blob-helpers.js */ "./src/lib/blob-helpers.js");
/* harmony import */ var _lib_utils_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ../lib/utils.js */ "./src/lib/utils.js");
@@ -4287,6 +4291,13 @@ const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({
"type": 0,
"value": "Edit permissions"
}]
},
qrcode: {
id: "scan_qr_code",
defaultMessage: [{
"type": 0,
"value": "Scan QR Code"
}]
}
});
class InfoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component) {
@@ -4329,6 +4340,8 @@ class InfoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
this.handleUnarchive = this.handleUnarchive.bind(this);
this.handlePermissionsChanged = this.handlePermissionsChanged.bind(this);
this.handleLaunchPermissionsEditor = this.handleLaunchPermissionsEditor.bind(this);
this.handleCopyID = this.handleCopyID.bind(this);
this.handleShowQRCode = this.handleShowQRCode.bind(this);
this.handleShowAddMembers = this.handleShowAddMembers.bind(this);
this.handleMemberUpdateRequest = this.handleMemberUpdateRequest.bind(this);
this.handleMemberSelected = this.handleMemberSelected.bind(this);
@@ -4376,8 +4389,8 @@ class InfoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
newState.modeGiven2 = user2.acs.getGiven();
newState.modeWant2 = user2.acs.getWant();
} else {
newState.modeGiven2 = _config_js__WEBPACK_IMPORTED_MODULE_13__.NO_ACCESS_MODE;
newState.modeWant2 = _config_js__WEBPACK_IMPORTED_MODULE_13__.NO_ACCESS_MODE;
newState.modeGiven2 = _config_js__WEBPACK_IMPORTED_MODULE_14__.NO_ACCESS_MODE;
newState.modeWant2 = _config_js__WEBPACK_IMPORTED_MODULE_14__.NO_ACCESS_MODE;
}
} else {
topic.subscribers(sub => {
@@ -4403,11 +4416,11 @@ class InfoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
sharer: acs && acs.isSharer(),
deleter: acs && acs.isDeleter(),
muted: acs && acs.isMuted(),
fullName: (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_15__.clipStr)(topic.public && topic.public.fn, _config_js__WEBPACK_IMPORTED_MODULE_13__.MAX_TITLE_LENGTH),
description: (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_15__.clipStr)(topic.public && topic.public.note, _config_js__WEBPACK_IMPORTED_MODULE_13__.MAX_TOPIC_DESCRIPTION_LENGTH),
avatar: (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_14__.makeImageUrl)(topic.public ? topic.public.photo : null),
fullName: (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_16__.clipStr)(topic.public && topic.public.fn, _config_js__WEBPACK_IMPORTED_MODULE_14__.MAX_TITLE_LENGTH),
description: (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_16__.clipStr)(topic.public && topic.public.note, _config_js__WEBPACK_IMPORTED_MODULE_14__.MAX_TOPIC_DESCRIPTION_LENGTH),
avatar: (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_15__.makeImageUrl)(topic.public ? topic.public.photo : null),
trustedBadges: badges,
private: (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_15__.clipStr)(topic.private && topic.private.comment, _config_js__WEBPACK_IMPORTED_MODULE_13__.MAX_TITLE_LENGTH),
private: (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_16__.clipStr)(topic.private && topic.private.comment, _config_js__WEBPACK_IMPORTED_MODULE_14__.MAX_TITLE_LENGTH),
archived: topic.isArchived(),
address: topic.name,
groupTopic: topic.isGroupType(),
@@ -4452,7 +4465,7 @@ class InfoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
this.setState({
avatar: img
});
this.props.onTopicDescUpdate(this.props.topic, (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_15__.theCard)(null, img || tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.DEL_CHAR), null);
this.props.onTopicDescUpdate(this.props.topic, (0,_lib_utils_js__WEBPACK_IMPORTED_MODULE_16__.theCard)(null, img || tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.DEL_CHAR), null);
}
handleMuted(ignored, checked) {
this.setState({
@@ -4563,6 +4576,14 @@ class InfoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
});
this.props.onNavigate(`perm/${which}`);
}
handleCopyID(e) {
e.preventDefault();
navigator.clipboard.writeText(this.props.myUserId);
}
handleShowQRCode(e) {
e.preventDefault();
this.props.onNavigate('qrcode');
}
handleShowAddMembers(e) {
e.preventDefault();
this.props.onInitFind();
@@ -4665,7 +4686,7 @@ class InfoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
userAvatar: this.state.userPermissionsAvatar,
onSubmit: mode => this.handlePermissionsChanged(args[0], mode),
onCancel: this.handleBackNavigate
}) : view == 'general' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_topic_common_view_jsx__WEBPACK_IMPORTED_MODULE_11__["default"], {
}) : view == 'general' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_topic_common_view_jsx__WEBPACK_IMPORTED_MODULE_12__["default"], {
tinode: this.props.tinode,
topic: this.props.topic,
reqCredMethod: this.props.reqCredMethod,
@@ -4675,7 +4696,7 @@ class InfoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
onCredDelete: this.props.onCredDelete,
onUpdateTopicDesc: this.props.onTopicDescUpdateRequest,
onError: this.props.onError
}) : view == 'security' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_widgets_topic_security_jsx__WEBPACK_IMPORTED_MODULE_12__["default"], {
}) : view == 'security' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_widgets_topic_security_jsx__WEBPACK_IMPORTED_MODULE_13__["default"], {
topic: this.props.topic,
owner: this.state.owner,
admin: this.state.admin,
@@ -4698,6 +4719,9 @@ class InfoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
onReportTopic: this.props.onReportTopic,
onLaunchPermissionsEditor: this.handleLaunchPermissionsEditor,
onNavigate: this.props.onNavigate
}) : view == 'qrcode' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_widgets_show_qrcode_jsx__WEBPACK_IMPORTED_MODULE_11__["default"], {
uri: tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.URI_TOPIC_ID_PREFIX + this.props.tinode.myUserId,
onCancel: this.handleBackNavigate
}) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
id: "info-view-content",
className: "scrollable-panel"
@@ -4753,8 +4777,8 @@ class InfoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
}))), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "large ellipsized"
}, this.state.private)) : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "group"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
className: "panel-form-row"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
className: "small"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, {
id: "label_user_id",
@@ -4763,6 +4787,20 @@ class InfoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
"value": "ID:"
}]
})), "\xA0", react__WEBPACK_IMPORTED_MODULE_0___default().createElement("tt", null, this.state.address)), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
style: {
marginLeft: 'auto'
}
}, "\xA0", react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", {
href: "#",
onClick: this.handleCopyID
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
className: "material-icons"
}, "content_copy")), "\xA0 \xA0", react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", {
href: "#",
onClick: this.handleShowQRCode
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
className: "material-icons"
}, "qr_code")), "\xA0")), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "group"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_widgets_badge_list_jsx__WEBPACK_IMPORTED_MODULE_4__["default"], {
trustedBadges: this.state.trustedBadges
@@ -6729,6 +6767,7 @@ class NewTopicView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
onSubmit: this.handleNewGroupSubmit,
onError: this.props.onError
}) : this.state.tabSelected === 'byid' ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement(_widgets_new_topic_by_id_jsx__WEBPACK_IMPORTED_MODULE_4__["default"], {
myURI: tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.URI_TOPIC_ID_PREFIX + this.props.tinode.getCurrentUserID(),
onSubmit: this.handleGroupByID,
onError: this.props.onError
}) : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
@@ -14135,13 +14174,18 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
/* harmony export */ });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-intl */ "react-intl");
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var qrcodejs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! qrcodejs */ "qrcodejs");
/* harmony import */ var qrcodejs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(qrcodejs__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "react");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-intl */ "react-intl");
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../config */ "./src/config.js");
const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({
const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_2__.defineMessages)({
invalid_id: {
id: "error_invalid_id",
defaultMessage: [{
@@ -14150,9 +14194,10 @@ const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({
}]
}
});
class NewTopicById extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) {
class NewTopicById extends (react__WEBPACK_IMPORTED_MODULE_1___default().PureComponent) {
constructor(props) {
super(props);
this.qrCodeRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();
this.state = {
groupId: ''
};
@@ -14160,6 +14205,13 @@ class NewTopicById extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
this.handleKeyPress = this.handleKeyPress.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
componentDidMount() {
new (qrcodejs__WEBPACK_IMPORTED_MODULE_0___default())(this.qrCodeRef.current, {
text: this.props.myURI,
width: _config__WEBPACK_IMPORTED_MODULE_3__.QRCODE_SIZE,
height: _config__WEBPACK_IMPORTED_MODULE_3__.QRCODE_SIZE
});
}
handleChange(e) {
this.setState({
groupId: e.target.value
@@ -14174,7 +14226,7 @@ class NewTopicById extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
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 {
@@ -14183,40 +14235,47 @@ class NewTopicById extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCom
}
}
render() {
return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
return react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", {
className: "panel-form"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
}, react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", {
className: "panel-form-row"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, {
}, react__WEBPACK_IMPORTED_MODULE_1___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_2__.FormattedMessage, {
id: "group_user_id_prompt",
defaultMessage: [{
"type": 0,
"value": "Group or User ID"
}]
}, prompt => react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", {
}, prompt => react__WEBPACK_IMPORTED_MODULE_1___default().createElement("input", {
type: "text",
placeholder: prompt,
value: this.state.groupId,
onChange: this.handleChange,
onKeyPress: this.handleKeyPress,
onKeyDown: this.handleKeyPress,
required: true,
autoFocus: true
}))), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
}))), react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", {
className: "dialog-buttons"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", {
}, react__WEBPACK_IMPORTED_MODULE_1___default().createElement("button", {
className: "primary",
onClick: this.handleSubmit
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, {
}, react__WEBPACK_IMPORTED_MODULE_1___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_2__.FormattedMessage, {
id: "button_subscribe",
defaultMessage: [{
"type": 0,
"value": "Subscribe"
}]
}))));
}))), react__WEBPACK_IMPORTED_MODULE_1___default().createElement("br", null), react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", {
className: "panel-form-column"
}, react__WEBPACK_IMPORTED_MODULE_1___default().createElement("label", {
className: "small"
}, "Scan my ID:"), react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", {
className: "qr-code",
ref: this.qrCodeRef
})));
}
}
;
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((0,react_intl__WEBPACK_IMPORTED_MODULE_1__.injectIntl)(NewTopicById));
/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ((0,react_intl__WEBPACK_IMPORTED_MODULE_2__.injectIntl)(NewTopicById));
/***/ }),
@@ -15299,6 +15358,63 @@ class SendMessage extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComp
/***/ }),
/***/ "./src/widgets/show-qrcode.jsx":
/*!*************************************!*\
!*** ./src/widgets/show-qrcode.jsx ***!
\*************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ ShowQRCode)
/* harmony export */ });
/* harmony import */ var qrcodejs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! qrcodejs */ "qrcodejs");
/* harmony import */ var qrcodejs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(qrcodejs__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "react");
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-intl */ "react-intl");
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_2__);
/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../config */ "./src/config.js");
class ShowQRCode extends (react__WEBPACK_IMPORTED_MODULE_1___default().PureComponent) {
constructor(props) {
super(props);
this.qrCodeRef = react__WEBPACK_IMPORTED_MODULE_1___default().createRef();
}
componentDidMount() {
new (qrcodejs__WEBPACK_IMPORTED_MODULE_0___default())(this.qrCodeRef.current, {
text: this.props.uri,
width: _config__WEBPACK_IMPORTED_MODULE_3__.QRCODE_SIZE,
height: _config__WEBPACK_IMPORTED_MODULE_3__.QRCODE_SIZE
});
}
render() {
return react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", {
className: "panel-form-column"
}, react__WEBPACK_IMPORTED_MODULE_1___default().createElement("br", null), react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", {
className: "qr-code",
ref: this.qrCodeRef
}), react__WEBPACK_IMPORTED_MODULE_1___default().createElement("div", {
className: "dialog-buttons"
}, react__WEBPACK_IMPORTED_MODULE_1___default().createElement("button", {
className: "outline",
onClick: this.props.onCancel
}, react__WEBPACK_IMPORTED_MODULE_1___default().createElement(react_intl__WEBPACK_IMPORTED_MODULE_2__.FormattedMessage, {
id: "button_ok",
defaultMessage: [{
"type": 0,
"value": "OK"
}]
}))));
}
}
;
/***/ }),
/***/ "./src/widgets/side-navbar.jsx":
/*!*************************************!*\
!*** ./src/widgets/side-navbar.jsx ***!
@@ -16471,6 +16587,16 @@ if (false) {} else {
}
/***/ }),
/***/ "qrcodejs":
/*!*************************!*\
!*** external "QRCode" ***!
\*************************/
/***/ ((module) => {
module.exports = QRCode;
/***/ }),
/***/ "react":
+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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
View File
@@ -6188,6 +6188,7 @@ Tinode.MAX_SUBSCRIBER_COUNT = 'maxSubscriberCount';
Tinode.MAX_TAG_COUNT = 'maxTagCount';
Tinode.MAX_FILE_UPLOAD_SIZE = 'maxFileUploadSize';
Tinode.REQ_CRED_VALIDATORS = 'reqCred';
Tinode.URI_TOPIC_ID_PREFIX = 'tinode:topic/';
})();
/******/ return __webpack_exports__;
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
+1
View File
@@ -64,6 +64,7 @@ module.exports = (env, argv) => {
}),
],
externals: {
'qrcodejs': 'QRCode',
'react': 'React',
'react-dom': 'ReactDOM',
'react-intl': 'ReactIntl',