Merge branch 'next' into vc

This commit is contained in:
aforge
2023-05-10 16:36:33 -07:00
24 changed files with 119 additions and 79 deletions
+7 -7
View File
@@ -15,7 +15,7 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-intl": "^6.3.0", "react-intl": "^6.3.0",
"tinode-sdk": "^0.22.6", "tinode-sdk": "^0.22.7",
"webm-duration-fix": "^1.0.4" "webm-duration-fix": "^1.0.4"
}, },
"devDependencies": { "devDependencies": {
@@ -7709,9 +7709,9 @@
} }
}, },
"node_modules/postcss-load-config/node_modules/yaml": { "node_modules/postcss-load-config/node_modules/yaml": {
"version": "2.2.1", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.1.tgz", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.2.2.tgz",
"integrity": "sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==", "integrity": "sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==",
"dev": true, "dev": true,
"engines": { "engines": {
"node": ">= 14" "node": ">= 14"
@@ -9248,9 +9248,9 @@
"dev": true "dev": true
}, },
"node_modules/tinode-sdk": { "node_modules/tinode-sdk": {
"version": "0.22.6", "version": "0.22.7",
"resolved": "https://registry.npmjs.org/tinode-sdk/-/tinode-sdk-0.22.6.tgz", "resolved": "https://registry.npmjs.org/tinode-sdk/-/tinode-sdk-0.22.7.tgz",
"integrity": "sha512-JMBW7sLFhrX2Ohkv2unkI4FEgQJLBtV4necRnzK2+5Gsq1wCHqAqPZXVPqzdU2Jumapxh5mZ3QrGLStay7vs3w==" "integrity": "sha512-+tUmuvsQ0i3IIymk7sC2VyPHXuUTODUyA1C4GybYD2H8VlNc10zS6Zk8T3HiueaYutw9xk4j6E2qw7P9INGvcw=="
}, },
"node_modules/to-fast-properties": { "node_modules/to-fast-properties": {
"version": "2.0.0", "version": "2.0.0",
+3 -1
View File
@@ -32,7 +32,9 @@ export default class HashNavigation {
const args = []; const args = [];
for (const key in params) { for (const key in params) {
if (params.hasOwnProperty(key)) { if (params.hasOwnProperty(key)) {
args.push(key + '=' + encodeURIComponent(params[key])); if (params[key] !== undefined) {
args.push(key + '=' + encodeURIComponent(params[key]));
}
} }
} }
if (args.length > 0) { if (args.length > 0) {
+15 -7
View File
@@ -46,12 +46,21 @@ export default class AccountSettingsView extends React.Component {
val={this.state.credEdit.val} val={this.state.credEdit.val}
done={this.state.credEdit.done} done={this.state.credEdit.done}
onShowCountrySelector={this.props.onShowCountrySelector} onShowCountrySelector={this.props.onShowCountrySelector}
onSubmit={this.props.onCredAdd} onCredAdd={this.props.onCredAdd}
onCredConfirm={this.props.onCredConfirm}
onCancel={_ => this.setState({credEdit: undefined})} onCancel={_ => this.setState({credEdit: undefined})}
onError={this.props.onError} /> onError={this.props.onError} />
); );
} }
// Count how many times each method is validated.
const validated = {};
this.state.credentials.forEach(cred => {
if (cred.done) {
validated[cred.meth] = (validated[cred.meth] || 0) + 1;
}
});
const credentials = []; const credentials = [];
this.state.credentials.forEach((cred, idx) => { this.state.credentials.forEach((cred, idx) => {
if (!['email', 'tel'].includes(cred.meth)) { if (!['email', 'tel'].includes(cred.meth)) {
@@ -68,15 +77,14 @@ export default class AccountSettingsView extends React.Component {
credentials.push( credentials.push(
<div className="group quoted" key={idx}> <div className="group quoted" key={idx}>
<tt className="clickable" onClick={e => {e.preventDefault(); this.setState({credEdit: cred});}}>{val}</tt> <tt className="clickable" onClick={e => {e.preventDefault(); this.setState({credEdit: cred});}}>{val}</tt>
<span> { <span> {cred.done ? null : <i className="material-icons">pending</i>}&nbsp;
cred.done ? null : {!cred.done || validated[cred.meth] > 1 || this.props.reqCredMethod != cred.meth ?
<>
<i className="material-icons">pending</i>&nbsp;
<a href="#" onClick={e => {e.preventDefault(); this.props.onCredDelete(cred.meth, cred.val);}}> <a href="#" onClick={e => {e.preventDefault(); this.props.onCredDelete(cred.meth, cred.val);}}>
<i className="material-icons">delete</i> <i className="material-icons">delete</i>
</a> </a>
</> :
}</span> null}
</span>
</div>); </div>);
}); });
if (credentials.length > 0) { if (credentials.length > 0) {
+5 -3
View File
@@ -274,12 +274,12 @@ class MessagesView extends React.Component {
} }
if (topic) { if (topic) {
if ((this.state.topic != prevState.topic) || !prevProps.ready) { if ((this.state.topic != prevState.topic) || (this.props.myUserId && !prevProps.myUserId)) {
// Don't immediately subscribe to a new p2p topic, wait for the first message. // Don't immediately subscribe to a new p2p topic, wait for the first message.
const newTopic = (this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic); const newTopic = (this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic);
if (topic.isP2PType() && newTopic && !IMMEDIATE_P2P_SUBSCRIPTION) { if (topic.isP2PType() && newTopic && !IMMEDIATE_P2P_SUBSCRIPTION) {
topic.getMeta(topic.startMetaQuery().withDesc().build()); topic.getMeta(topic.startMetaQuery().withDesc().build());
} else { } else if (this.props.myUserId) {
this.subscribe(topic); this.subscribe(topic);
} }
} else if (topic.isSubscribed() && this.state.isReader && !prevState.isReader) { } else if (topic.isSubscribed() && this.state.isReader && !prevState.isReader) {
@@ -478,7 +478,6 @@ class MessagesView extends React.Component {
// Is this a new topic? // Is this a new topic?
const newTopic = (this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic); const newTopic = (this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic);
// Don't request the tags. They are useless unless the user // Don't request the tags. They are useless unless the user
// is the owner and is editing the topic. // is the owner and is editing the topic.
let getQuery = topic.startMetaQuery().withLaterDesc().withLaterSub().withAux(); let getQuery = topic.startMetaQuery().withLaterDesc().withLaterSub().withAux();
@@ -503,6 +502,9 @@ class MessagesView extends React.Component {
if (this.state.topic != ctrl.topic) { if (this.state.topic != ctrl.topic) {
this.setState({topic: ctrl.topic}); this.setState({topic: ctrl.topic});
} }
if (this.state.deleted) {
this.setState({deleted: false});
}
this.props.onNewTopicCreated(this.props.topic, ctrl.topic); this.props.onNewTopicCreated(this.props.topic, ctrl.topic);
// If there are unsent messages (except hard-failed and video call messages), // If there are unsent messages (except hard-failed and video call messages),
// try sending them now. Hard-failed and unsent video call messages will be dropped. // try sending them now. Hard-failed and unsent video call messages will be dropped.
+2 -2
View File
@@ -57,7 +57,7 @@ class PasswordResetView extends React.PureComponent {
// Reset using token. // Reset using token.
this.props.onReset(this.state.password.trim(), { this.props.onReset(this.state.password.trim(), {
scheme: 'token', scheme: 'token',
token: this.state.token secret: this.state.token
}); });
} else if (this.state.code && this.props.reqCredMethod) { } else if (this.state.code && this.props.reqCredMethod) {
// Reset using security code. // Reset using security code.
@@ -193,7 +193,7 @@ class PasswordResetView extends React.PureComponent {
{this.state.haveCode || this.state.sent ? codeInput : null} {this.state.haveCode || this.state.sent ? codeInput : null}
{showPasswordInput ? passwordInput : null} {showPasswordInput ? passwordInput : null}
<div className="dialog-buttons"> <div className="dialog-buttons">
{this.state.haveCode || this.state.sent ? null : {this.state.haveCode || this.state.sent || this.state.token ? null :
<a href="#" onClick={this.handleShowCodeField} style={{marginRight: 'auto'}}> <a href="#" onClick={this.handleShowCodeField} style={{marginRight: 'auto'}}>
<FormattedMessage id="password_i_have_code" defaultMessage="I have code" <FormattedMessage id="password_i_have_code" defaultMessage="I have code"
description="Call to open field to enter password reset code" /> description="Call to open field to enter password reset code" />
+1
View File
@@ -181,6 +181,7 @@ class SidepanelView extends React.PureComponent {
tinode={this.props.tinode} tinode={this.props.tinode}
myUserId={this.props.myUserId} myUserId={this.props.myUserId}
trustedBadges={this.props.trustedBadges} trustedBadges={this.props.trustedBadges}
reqCredMethod={this.props.reqCredMethod}
onShowCountrySelector={this.props.onShowCountrySelector} onShowCountrySelector={this.props.onShowCountrySelector}
onNavigate={this.props.onNavigate} onNavigate={this.props.onNavigate}
onCredAdd={this.props.onCredAdd} onCredAdd={this.props.onCredAdd}
+6 -3
View File
@@ -763,6 +763,7 @@ class TinodeWeb extends React.Component {
parsed.path[0] = 'cred'; parsed.path[0] = 'cred';
parsed.params['method'] = params.cred[0]; parsed.params['method'] = params.cred[0];
parsed.params['token'] = params.token; parsed.params['token'] = params.token;
parsed.params['code'] = params.code;
HashNavigation.navigateTo(HashNavigation.composeUrlHash(parsed.path, parsed.params)); HashNavigation.navigateTo(HashNavigation.composeUrlHash(parsed.path, parsed.params));
} }
@@ -848,7 +849,7 @@ class TinodeWeb extends React.Component {
} }
} else if (what == 'read') { } else if (what == 'read') {
this.resetContactList(); this.resetContactList();
} else if (what == 'msg') { } else if (what == 'msg' && cont) {
// Check if the topic is archived. If so, don't play a sound. // Check if the topic is archived. If so, don't play a sound.
const topic = this.tinode.getTopic(cont.topic); const topic = this.tinode.getTopic(cont.topic);
const archived = topic && topic.isArchived(); const archived = topic && topic.isArchived();
@@ -887,7 +888,7 @@ class TinodeWeb extends React.Component {
} else { } else {
// TODO(gene): handle other types of notifications: // TODO(gene): handle other types of notifications:
// * ua -- user agent changes (maybe display a pictogram for mobile/desktop). // * ua -- user agent changes (maybe display a pictogram for mobile/desktop).
console.info("Unsupported (yet) presence update:", what, "in", cont.topic); console.info("Unsupported (yet) presence update:", what, "in", (cont || {}).topic);
} }
} }
@@ -1019,6 +1020,7 @@ class TinodeWeb extends React.Component {
} else { } else {
// Currently selected contact deleted // Currently selected contact deleted
this.setState({ this.setState({
topicSelected: null,
errorText: '', errorText: '',
errorLevel: null, errorLevel: null,
mobilePanel: 'sidepanel', mobilePanel: 'sidepanel',
@@ -1287,7 +1289,7 @@ class TinodeWeb extends React.Component {
} }
handleCredConfirm(method, response) { handleCredConfirm(method, response) {
TinodeWeb.navigateToCredentialsView({cred: [method]}); TinodeWeb.navigateToCredentialsView({cred: [method], code: response});
} }
// User clicked Cancel button in Setting or Sign Up panel. // User clicked Cancel button in Setting or Sign Up panel.
@@ -1709,6 +1711,7 @@ class TinodeWeb extends React.Component {
if (this.tinode.isAuthenticated()) { if (this.tinode.isAuthenticated()) {
// Adding new email or phone number in account setting. // Adding new email or phone number in account setting.
this.tinode.getMeTopic().setMeta({cred: {meth: cred, resp: code}}) this.tinode.getMeTopic().setMeta({cred: {meth: cred, resp: code}})
.then(_ => HashNavigation.navigateTo(HashNavigation.setUrlSidePanel(window.location.hash, 'contacts')))
.catch(err => this.handleError(err.message, 'err')); .catch(err => this.handleError(err.message, 'err'));
} else { } else {
// Credential validation on signup. // Credential validation on signup.
+1 -1
View File
@@ -100,7 +100,7 @@ class ValidationView extends React.PureComponent {
(numbers_only) => <input type="text" id="enter-confirmation-code" (numbers_only) => <input type="text" id="enter-confirmation-code"
placeholder={numbers_only} placeholder={numbers_only}
value={this.state.code} onChange={this.handleCodeChange} value={this.state.code} onChange={this.handleCodeChange}
onKeyPress={this.handleKeyPress} required /> onKeyDown={this.handleKeyPress} required />
}</FormattedMessage> }</FormattedMessage>
</div> </div>
<div className="dialog-buttons"> <div className="dialog-buttons">
+18 -17
View File
@@ -58,8 +58,11 @@ class CredentialEdit extends React.PureComponent {
handleSubmit(e) { handleSubmit(e) {
e.preventDefault(); e.preventDefault();
const value = this.props.method == 'email' ? this.state.email : this.state.tel; const value = this.props.method == 'email' ? this.state.email : this.state.tel;
if (value) { if (this.state.code) {
this.props.onSubmit(this.props.method, value); this.props.onError(null);
this.props.onCredConfirm(this.props.method, this.state.code);
} else if (value) {
this.props.onCredAdd(this.props.method, value);
this.setState({sent: true}); this.setState({sent: true});
const msg = this.props.method == 'email' ? messages.password_reset_email_sent : messages.password_reset_sms_sent; const msg = this.props.method == 'email' ? messages.password_reset_email_sent : messages.password_reset_sms_sent;
this.props.onError(this.props.intl.formatMessage(msg), 'info'); this.props.onError(this.props.intl.formatMessage(msg), 'info');
@@ -68,8 +71,8 @@ class CredentialEdit extends React.PureComponent {
render() { render() {
const readyForCode = this.state.sent || !this.props.done; const readyForCode = this.state.sent || !this.props.done;
const currentValue = CredentialEdit.formatPhoneNumber(readyForCode ? const rawValue = readyForCode ? (this.state.tel || this.state.email) : this.props.val;
(this.state.tel || this.state.email) : this.props.val); const formattedValue = this.props.method == 'tel' ? CredentialEdit.formatPhoneNumber(rawValue) : rawValue;
const changeEmail = ( const changeEmail = (
<><div className="panel-form-row"> <><div className="panel-form-row">
@@ -140,21 +143,19 @@ class CredentialEdit extends React.PureComponent {
); );
return (<form className="panel-form-column" onSubmit={this.handleSubmit}> return (<form className="panel-form-column" onSubmit={this.handleSubmit}>
{readyForCode ? null : {readyForCode ?
this.props.method == 'email' ? (this.props.method == 'email' ? newEmailLabel : this.props.method == 'tel' ? newPhoneLabel : null)
changeEmail :
: this.props.method == 'tel' ? (this.props.method == 'email' ? changeEmail : this.props.method == 'tel' ? changePhone : null)
changePhone }
: null}
<div className="panel-form-row"> <div className="panel-form-row">
<tt className="quoted">{currentValue}</tt> <tt className="quoted">{formattedValue}</tt>
</div> </div>
{readyForCode ? null : {readyForCode ?
this.props.method == 'email' ? null
newEmailInput :
: this.props.method == 'tel' ? (this.props.method == 'email' ? newEmailInput : this.props.method == 'tel' ? newPhoneInput : null)
newPhoneInput }
: null}
{readyForCode ? codeInput : null} {readyForCode ? codeInput : null}
<div className="dialog-buttons"> <div className="dialog-buttons">
<button className="secondary" onClick={this.props.onCancel}> <button className="secondary" onClick={this.props.onCancel}>
+1 -1
View File
@@ -39,7 +39,7 @@ export default class ErrorPanel extends React.PureComponent {
{this.props.text} {this.props.text}
{this.props.action ? {this.props.action ?
<> <>
&#32;<a href="#" &nbsp;&#32;<a href="#"
style={{ whiteSpace: 'nowrap' }} style={{ whiteSpace: 'nowrap' }}
onClick={(e) => {e.preventDefault(); this.props.action();}}> onClick={(e) => {e.preventDefault(); this.props.action();}}>
{this.props.actionText} {this.props.actionText}
+2 -1
View File
@@ -5,6 +5,7 @@ import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import { import {
connect, connect,
LocalParticipant, LocalParticipant,
LocalVideoTrack,
MediaDeviceFailure, MediaDeviceFailure,
Participant, Participant,
ParticipantEvent, ParticipantEvent,
@@ -171,7 +172,7 @@ class VCPanel extends React.PureComponent {
handleLocalTrackPublished(pub) { handleLocalTrackPublished(pub) {
console.log('Local track published', pub); console.log('Local track published', pub);
const track = pub.track; const track = pub.track;
if (this.localRef.current) { if ((track instanceof LocalVideoTrack) && this.localRef.current) {
const elem = this.localRef.current; const elem = this.localRef.current;
track.attach(elem); track.attach(elem);
// flip. // flip.
+3 -3
View File
@@ -8,7 +8,7 @@ export default class VisiblePassword extends React.PureComponent {
this.inputRef = React.createRef(); this.inputRef = React.createRef();
this.state = { this.state = {
value: this.props.value, value: this.props.value || '',
visible: false visible: false
}; };
@@ -39,7 +39,7 @@ export default class VisiblePassword extends React.PureComponent {
handleKeyDown(e) { handleKeyDown(e) {
if (e.keyCode == 27) { if (e.keyCode == 27) {
// Escape pressed // Escape pressed
this.setState({value: this.props.value, visible: false}); this.setState({value: this.props.value || '', visible: false});
if (this.props.onFinished) { if (this.props.onFinished) {
this.props.onFinished(); this.props.onFinished();
} }
@@ -68,7 +68,7 @@ export default class VisiblePassword extends React.PureComponent {
return ( return (
<div tabIndex="-1" className="group-focus" onBlur={this.handleEditingFinished}> <div tabIndex="-1" className="group-focus" onBlur={this.handleEditingFinished}>
<input className="with-visibility" <input className="with-visibility"
type={this.state.visible ? "text" : "password"} type={this.state.visible ? 'text' : 'password'}
value={this.state.value} value={this.state.value}
placeholder={this.props.placeholder} placeholder={this.props.placeholder}
required={this.props.required ? 'required' : ''} required={this.props.required ? 'required' : ''}
+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
+24 -13
View File
@@ -3245,7 +3245,9 @@ class HashNavigation {
const args = []; const args = [];
for (const key in params) { for (const key in params) {
if (params.hasOwnProperty(key)) { if (params.hasOwnProperty(key)) {
args.push(key + '=' + encodeURIComponent(params[key])); if (params[key] !== undefined) {
args.push(key + '=' + encodeURIComponent(params[key]));
}
} }
} }
if (args.length > 0) { if (args.length > 0) {
@@ -5329,11 +5331,11 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
} }
} }
if (topic) { if (topic) {
if (this.state.topic != prevState.topic || !prevProps.ready) { if (this.state.topic != prevState.topic || this.props.myUserId && !prevProps.myUserId) {
const newTopic = this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic; const newTopic = this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic;
if (topic.isP2PType() && newTopic && !_config_js__WEBPACK_IMPORTED_MODULE_19__.IMMEDIATE_P2P_SUBSCRIPTION) { if (topic.isP2PType() && newTopic && !_config_js__WEBPACK_IMPORTED_MODULE_19__.IMMEDIATE_P2P_SUBSCRIPTION) {
topic.getMeta(topic.startMetaQuery().withDesc().build()); topic.getMeta(topic.startMetaQuery().withDesc().build());
} else { } else if (this.props.myUserId) {
this.subscribe(topic); this.subscribe(topic);
} }
} else if (topic.isSubscribed() && this.state.isReader && !prevState.isReader) { } else if (topic.isSubscribed() && this.state.isReader && !prevState.isReader) {
@@ -5529,6 +5531,11 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
topic: ctrl.topic topic: ctrl.topic
}); });
} }
if (this.state.deleted) {
this.setState({
deleted: false
});
}
this.props.onNewTopicCreated(this.props.topic, ctrl.topic); this.props.onNewTopicCreated(this.props.topic, ctrl.topic);
let discard = []; let discard = [];
topic.queuedMessages(pub => { topic.queuedMessages(pub => {
@@ -7216,6 +7223,7 @@ class SidepanelView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCo
tinode: this.props.tinode, tinode: this.props.tinode,
myUserId: this.props.myUserId, myUserId: this.props.myUserId,
trustedBadges: this.props.trustedBadges, trustedBadges: this.props.trustedBadges,
reqCredMethod: this.props.reqCredMethod,
onShowCountrySelector: this.props.onShowCountrySelector, onShowCountrySelector: this.props.onShowCountrySelector,
onNavigate: this.props.onNavigate, onNavigate: this.props.onNavigate,
onCredAdd: this.props.onCredAdd, onCredAdd: this.props.onCredAdd,
@@ -8031,6 +8039,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
parsed.path[0] = 'cred'; parsed.path[0] = 'cred';
parsed.params['method'] = params.cred[0]; parsed.params['method'] = params.cred[0];
parsed.params['token'] = params.token; parsed.params['token'] = params.token;
parsed.params['code'] = params.code;
_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].navigateTo(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].composeUrlHash(parsed.path, parsed.params)); _lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].navigateTo(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].composeUrlHash(parsed.path, parsed.params));
} }
handleLoginSuccessful() { handleLoginSuccessful() {
@@ -8104,7 +8113,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
} }
} else if (what == 'read') { } else if (what == 'read') {
this.resetContactList(); this.resetContactList();
} else if (what == 'msg') { } else if (what == 'msg' && cont) {
const topic = this.tinode.getTopic(cont.topic); const topic = this.tinode.getTopic(cont.topic);
const archived = topic && topic.isArchived(); const archived = topic && topic.isArchived();
if (cont.unread > 0 && this.state.messageSounds && !archived) { if (cont.unread > 0 && this.state.messageSounds && !archived) {
@@ -8125,7 +8134,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
}); });
} }
} else if (what == 'del') {} else if (what == 'upd' || what == 'call') {} else { } else if (what == 'del') {} else if (what == 'upd' || what == 'call') {} else {
console.info("Unsupported (yet) presence update:", what, "in", cont.topic); console.info("Unsupported (yet) presence update:", what, "in", (cont || {}).topic);
} }
} }
tnMeSubsUpdated(unused) { tnMeSubsUpdated(unused) {
@@ -8227,6 +8236,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
} }
} else { } else {
this.setState({ this.setState({
topicSelected: null,
errorText: '', errorText: '',
errorLevel: null, errorLevel: null,
mobilePanel: 'sidepanel', mobilePanel: 'sidepanel',
@@ -8474,7 +8484,8 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
} }
handleCredConfirm(method, response) { handleCredConfirm(method, response) {
TinodeWeb.navigateToCredentialsView({ TinodeWeb.navigateToCredentialsView({
cred: [method] cred: [method],
code: response
}); });
} }
handleSidepanelCancel() { handleSidepanelCancel() {
@@ -8851,7 +8862,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
meth: cred, meth: cred,
resp: code resp: code
} }
}).catch(err => this.handleError(err.message, 'err')); }).then(_ => _lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].navigateTo(_lib_navigation_js__WEBPACK_IMPORTED_MODULE_18__["default"].setUrlSidePanel(window.location.hash, 'contacts'))).catch(err => this.handleError(err.message, 'err'));
} else { } else {
this.setState({ this.setState({
credMethod: cred, credMethod: cred,
@@ -9468,7 +9479,7 @@ class ValidationView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
placeholder: numbers_only, placeholder: numbers_only,
value: this.state.code, value: this.state.code,
onChange: this.handleCodeChange, onChange: this.handleCodeChange,
onKeyPress: this.handleKeyPress, onKeyDown: this.handleKeyPress,
required: true required: true
}))), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }))), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "dialog-buttons" className: "dialog-buttons"
@@ -12994,7 +13005,7 @@ class ErrorPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureCompo
className: "icon" className: "icon"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", { }, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
className: "material-icons" className: "material-icons"
}, level)), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, this.props.text, this.props.action ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", { }, level)), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, this.props.text, this.props.action ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, "\xA0 ", react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", {
href: "#", href: "#",
style: { style: {
whiteSpace: 'nowrap' whiteSpace: 'nowrap'
@@ -16821,7 +16832,7 @@ class VCPanel extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponen
handleLocalTrackPublished(pub) { handleLocalTrackPublished(pub) {
console.log('Local track published', pub); console.log('Local track published', pub);
const track = pub.track; const track = pub.track;
if (this.localRef.current) { if (track instanceof livekit_client__WEBPACK_IMPORTED_MODULE_2__.LocalVideoTrack && this.localRef.current) {
const elem = this.localRef.current; const elem = this.localRef.current;
track.attach(elem); track.attach(elem);
elem.style.transform = 'scale(-1, 1)'; elem.style.transform = 'scale(-1, 1)';
@@ -17192,7 +17203,7 @@ class VisiblePassword extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pure
super(props); super(props);
this.inputRef = react__WEBPACK_IMPORTED_MODULE_0___default().createRef(); this.inputRef = react__WEBPACK_IMPORTED_MODULE_0___default().createRef();
this.state = { this.state = {
value: this.props.value, value: this.props.value || '',
visible: false visible: false
}; };
this.handleVisibility = this.handleVisibility.bind(this); this.handleVisibility = this.handleVisibility.bind(this);
@@ -17222,7 +17233,7 @@ class VisiblePassword extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pure
handleKeyDown(e) { handleKeyDown(e) {
if (e.keyCode == 27) { if (e.keyCode == 27) {
this.setState({ this.setState({
value: this.props.value, value: this.props.value || '',
visible: false visible: false
}); });
if (this.props.onFinished) { if (this.props.onFinished) {
@@ -17253,7 +17264,7 @@ class VisiblePassword extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pure
onBlur: this.handleEditingFinished onBlur: this.handleEditingFinished
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", { }, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("input", {
className: "with-visibility", className: "with-visibility",
type: this.state.visible ? "text" : "password", type: this.state.visible ? 'text' : 'password',
value: this.state.value, value: this.state.value,
placeholder: this.props.placeholder, placeholder: this.props.placeholder,
required: this.props.required ? 'required' : '', required: this.props.required ? 'required' : '',
+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
+20 -9
View File
@@ -61,13 +61,20 @@ class AccountSettingsView extends (react__WEBPACK_IMPORTED_MODULE_0___default().
val: this.state.credEdit.val, val: this.state.credEdit.val,
done: this.state.credEdit.done, done: this.state.credEdit.done,
onShowCountrySelector: this.props.onShowCountrySelector, onShowCountrySelector: this.props.onShowCountrySelector,
onSubmit: this.props.onCredAdd, onCredAdd: this.props.onCredAdd,
onCredConfirm: this.props.onCredConfirm,
onCancel: _ => this.setState({ onCancel: _ => this.setState({
credEdit: undefined credEdit: undefined
}), }),
onError: this.props.onError onError: this.props.onError
}); });
} }
const validated = {};
this.state.credentials.forEach(cred => {
if (cred.done) {
validated[cred.meth] = (validated[cred.meth] || 0) + 1;
}
});
const credentials = []; const credentials = [];
this.state.credentials.forEach((cred, idx) => { this.state.credentials.forEach((cred, idx) => {
if (!['email', 'tel'].includes(cred.meth)) { if (!['email', 'tel'].includes(cred.meth)) {
@@ -89,9 +96,9 @@ class AccountSettingsView extends (react__WEBPACK_IMPORTED_MODULE_0___default().
credEdit: cred credEdit: cred
}); });
} }
}, val), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, " ", cred.done ? null : react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", { }, val), react__WEBPACK_IMPORTED_MODULE_0___default().createElement("span", null, " ", cred.done ? null : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
className: "material-icons" className: "material-icons"
}, "pending"), "\xA0", react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", { }, "pending"), "\xA0", !cred.done || validated[cred.meth] > 1 || this.props.reqCredMethod != cred.meth ? react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", {
href: "#", href: "#",
onClick: e => { onClick: e => {
e.preventDefault(); e.preventDefault();
@@ -99,7 +106,7 @@ class AccountSettingsView extends (react__WEBPACK_IMPORTED_MODULE_0___default().
} }
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", { }, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
className: "material-icons" className: "material-icons"
}, "delete")))))); }, "delete")) : null)));
}); });
if (credentials.length > 0) { if (credentials.length > 0) {
credentials.unshift(react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", { credentials.unshift(react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
@@ -313,8 +320,11 @@ class CredentialEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
handleSubmit(e) { handleSubmit(e) {
e.preventDefault(); e.preventDefault();
const value = this.props.method == 'email' ? this.state.email : this.state.tel; const value = this.props.method == 'email' ? this.state.email : this.state.tel;
if (value) { if (this.state.code) {
this.props.onSubmit(this.props.method, value); this.props.onError(null);
this.props.onCredConfirm(this.props.method, this.state.code);
} else if (value) {
this.props.onCredAdd(this.props.method, value);
this.setState({ this.setState({
sent: true sent: true
}); });
@@ -324,7 +334,8 @@ class CredentialEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
} }
render() { render() {
const readyForCode = this.state.sent || !this.props.done; const readyForCode = this.state.sent || !this.props.done;
const currentValue = CredentialEdit.formatPhoneNumber(readyForCode ? this.state.tel || this.state.email : this.props.val); const rawValue = readyForCode ? this.state.tel || this.state.email : this.props.val;
const formattedValue = this.props.method == 'tel' ? CredentialEdit.formatPhoneNumber(rawValue) : rawValue;
const changeEmail = react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { const changeEmail = react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "panel-form-row" className: "panel-form-row"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", { }, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
@@ -441,11 +452,11 @@ class CredentialEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("form", { return react__WEBPACK_IMPORTED_MODULE_0___default().createElement("form", {
className: "panel-form-column", className: "panel-form-column",
onSubmit: this.handleSubmit onSubmit: this.handleSubmit
}, readyForCode ? null : this.props.method == 'email' ? changeEmail : this.props.method == 'tel' ? changePhone : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }, readyForCode ? this.props.method == 'email' ? newEmailLabel : this.props.method == 'tel' ? newPhoneLabel : null : this.props.method == 'email' ? changeEmail : this.props.method == 'tel' ? changePhone : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "panel-form-row" className: "panel-form-row"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("tt", { }, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("tt", {
className: "quoted" className: "quoted"
}, currentValue)), readyForCode ? null : this.props.method == 'email' ? newEmailInput : this.props.method == 'tel' ? newPhoneInput : null, readyForCode ? codeInput : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }, formattedValue)), readyForCode ? null : this.props.method == 'email' ? newEmailInput : this.props.method == 'tel' ? newPhoneInput : null, readyForCode ? codeInput : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "dialog-buttons" className: "dialog-buttons"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", { }, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", {
className: "secondary", className: "secondary",
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -71,7 +71,7 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
if (this.state.token) { if (this.state.token) {
this.props.onReset(this.state.password.trim(), { this.props.onReset(this.state.password.trim(), {
scheme: 'token', scheme: 'token',
token: this.state.token secret: this.state.token
}); });
} else if (this.state.code && this.props.reqCredMethod) { } else if (this.state.code && this.props.reqCredMethod) {
const cred = this.state.email.trim() || this.state.tel.trim(); const cred = this.state.email.trim() || this.state.tel.trim();
@@ -222,7 +222,7 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
onSubmit: this.handleSubmit onSubmit: this.handleSubmit
}, !this.state.sent && showCredentialInput ? credentialInput : null, this.state.haveCode || this.state.sent ? codeInput : null, showPasswordInput ? passwordInput : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", { }, !this.state.sent && showCredentialInput ? credentialInput : null, this.state.haveCode || this.state.sent ? codeInput : null, showPasswordInput ? passwordInput : null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("div", {
className: "dialog-buttons" className: "dialog-buttons"
}, this.state.haveCode || this.state.sent ? null : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", { }, this.state.haveCode || this.state.sent || this.state.token ? null : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", {
href: "#", href: "#",
onClick: this.handleShowCodeField, onClick: this.handleShowCodeField,
style: { style: {
File diff suppressed because one or more lines are too long