merge next

This commit is contained in:
or-else
2023-06-10 12:14:59 -07:00
81 changed files with 28106 additions and 24984 deletions
+2444 -1655
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1,7 +1,7 @@
{
"name": "tinode-webapp",
"description": "Tinode messenger for the web",
"version": "0.23.0-rc1",
"version": "0.23.0-rc2",
"repository": {
"type": "git",
"url": "https://github.com/tinode/webapp.git"
@@ -84,8 +84,8 @@
"babel-plugin-formatjs": "^10.4.0",
"browserslist": "^4.21.5",
"copy-webpack-plugin": "^11.0.0",
"cssnano": "^5.1.15",
"glob": "^9.3.0",
"cssnano": "^6.0.1",
"glob": "^10.2.7",
"postcss": "^8.4.21",
"postcss-cli": "^10.1.0",
"webpack": "^5.76.1",
+1 -1
View File
@@ -15,7 +15,7 @@ const OUTPUT_PATTERN = './src/i18n.min/%s.json';
const args = process.argv.slice(2);
function getLocaleFromFileName(filename) {
const parts = filename.split('/');
const parts = filename.split(path.sep);
return parts[parts.length - 1].split('.json')[0];
}
+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
+8 -1
View File
@@ -1420,7 +1420,7 @@
"cred_confirmed_successfully": {
"translation": "Erfolgreich bestätigt",
"defaultMessage": "Confirmed successfully",
"description": "Message explaining that the credential was successfully validated.",
"description": "Notification message that the credential was successfully validated.",
"missing": false,
"obsolete": false
},
@@ -1654,5 +1654,12 @@
"description": "Conference call label",
"missing": true,
"obsolete": false
},
"password_reset_success": {
"translation": "Passwort erfolgreich zurückgesetzt",
"defaultMessage": "Password reset successfully",
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
}
}
+8 -1
View File
@@ -1420,7 +1420,7 @@
"cred_confirmed_successfully": {
"translation": "Confirmed successfully",
"defaultMessage": "Confirmed successfully",
"description": "Message explaining that the credential was successfully validated.",
"description": "Notification message that the credential was successfully validated.",
"missing": false,
"obsolete": false
},
@@ -1654,5 +1654,12 @@
"description": "Conference call label",
"missing": false,
"obsolete": false
},
"password_reset_success": {
"translation": "Password reset successfully",
"defaultMessage": "Password reset successfully",
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
}
}
+8 -1
View File
@@ -1420,7 +1420,7 @@
"cred_confirmed_successfully": {
"translation": "Confirmado con éxito",
"defaultMessage": "Confirmed successfully",
"description": "Message explaining that the credential was successfully validated.",
"description": "Notification message that the credential was successfully validated.",
"missing": false,
"obsolete": false
},
@@ -1654,5 +1654,12 @@
"description": "Conference call label",
"missing": true,
"obsolete": false
},
"password_reset_success": {
"translation": "Restablecimiento de contraseña con éxito",
"defaultMessage": "Password reset successfully",
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
}
}
+5 -1
View File
@@ -213,7 +213,7 @@
},
"cred_confirmed_successfully": {
"defaultMessage": "Confirmed successfully",
"description": "Message explaining that the credential was successfully validated."
"description": "Notification message that the credential was successfully validated."
},
"credential_email_prompt": {
"defaultMessage": "Your registration email",
@@ -708,6 +708,10 @@
"defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions has been sent"
},
"password_reset_success": {
"defaultMessage": "Password reset successfully",
"description": "Notification message that the password was successfully reset."
},
"password_unchanged_prompt": {
"defaultMessage": "Unchanged",
"description": "Message in editor while password is unchanged"
+8 -1
View File
@@ -1420,7 +1420,7 @@
"cred_confirmed_successfully": {
"translation": "Confirmé avec succès",
"defaultMessage": "Confirmed successfully",
"description": "Message explaining that the credential was successfully validated.",
"description": "Notification message that the credential was successfully validated.",
"missing": false,
"obsolete": false
},
@@ -1654,5 +1654,12 @@
"description": "Conference call label",
"missing": true,
"obsolete": false
},
"password_reset_success": {
"translation": "Mot de passe réinitialisé avec succès",
"defaultMessage": "Password reset successfully",
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
}
}
+8 -1
View File
@@ -1420,7 +1420,7 @@
"cred_confirmed_successfully": {
"translation": "성공적으로 확인됨",
"defaultMessage": "Confirmed successfully",
"description": "Message explaining that the credential was successfully validated.",
"description": "Notification message that the credential was successfully validated.",
"missing": false,
"obsolete": false
},
@@ -1654,5 +1654,12 @@
"description": "Conference call label",
"missing": true,
"obsolete": false
},
"password_reset_success": {
"translation": "비밀번호 재설정 성공",
"defaultMessage": "Password reset successfully",
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
}
}
+8 -1
View File
@@ -1420,7 +1420,7 @@
"cred_confirmed_successfully": {
"translation": "Confirmat cu succes",
"defaultMessage": "Confirmed successfully",
"description": "Message explaining that the credential was successfully validated.",
"description": "Notification message that the credential was successfully validated.",
"missing": false,
"obsolete": false
},
@@ -1654,5 +1654,12 @@
"description": "Conference call label",
"missing": true,
"obsolete": false
},
"password_reset_success": {
"translation": "Resetarea parolei cu succes",
"defaultMessage": "Password reset successfully",
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
}
}
+8 -1
View File
@@ -1420,7 +1420,7 @@
"cred_confirmed_successfully": {
"translation": "Подтверждено успешно",
"defaultMessage": "Confirmed successfully",
"description": "Message explaining that the credential was successfully validated.",
"description": "Notification message that the credential was successfully validated.",
"missing": false,
"obsolete": false
},
@@ -1654,5 +1654,12 @@
"description": "Conference call label",
"missing": true,
"obsolete": false
},
"password_reset_success": {
"translation": "Пароль успешно изменен",
"defaultMessage": "Password reset successfully",
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
}
}
+8 -1
View File
@@ -1420,7 +1420,7 @@
"cred_confirmed_successfully": {
"translation": "確認成功",
"defaultMessage": "Confirmed successfully",
"description": "Message explaining that the credential was successfully validated.",
"description": "Notification message that the credential was successfully validated.",
"missing": false,
"obsolete": false
},
@@ -1654,5 +1654,12 @@
"description": "Conference call label",
"missing": true,
"obsolete": false
},
"password_reset_success": {
"translation": "密碼重置成功",
"defaultMessage": "Password reset successfully",
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
}
}
+8 -1
View File
@@ -1420,7 +1420,7 @@
"cred_confirmed_successfully": {
"translation": "确认成功",
"defaultMessage": "Confirmed successfully",
"description": "Message explaining that the credential was successfully validated.",
"description": "Notification message that the credential was successfully validated.",
"missing": false,
"obsolete": false
},
@@ -1654,5 +1654,12 @@
"description": "Conference call label",
"missing": true,
"obsolete": false
},
"password_reset_success": {
"translation": "密码重置成功",
"defaultMessage": "Password reset successfully",
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
}
}
+2 -2
View File
@@ -210,7 +210,7 @@ function handleImageData(el, data, attr) {
return el;
}
// Additional processing of image data.
// Additional processing of attached video data.
function handleVideoData(el, data, attr) {
if (!data) {
attr.src = 'img/broken_video.png';
@@ -241,7 +241,7 @@ function handleVideoData(el, data, attr) {
}
el = InlineVideo;
} else {
// Use custom element instead of <img>.
// Use custom element instead of <img> or <video>.
el = UploadingImage;
}
+4 -2
View File
@@ -4,7 +4,7 @@ export default class HashNavigation {
// Parse hash as in http://www.example.com/path#hash as if it were
// path and arguments.
static parseUrlHash(hash) {
// Split path from args, path -> parts[0], args->path[1]
// Split 'path/?args' into 'path/' and 'args', path -> parts[0], args->path[1].
const parts = hash.split('?', 2);
const params = {};
let path = [];
@@ -32,7 +32,9 @@ export default class HashNavigation {
const args = [];
for (const key in params) {
if (params.hasOwnProperty(key)) {
args.push(key + '=' + encodeURIComponent(params[key]));
if (params[key] !== undefined) {
args.push(key + '=' + encodeURIComponent(params[key]));
}
}
}
if (args.length > 0) {
+1 -1
View File
@@ -1,3 +1,3 @@
// This is a generated file. Don't edit.
export const PACKAGE_VERSION = "0.23.0-rc1";
export const PACKAGE_VERSION = "0.23.0-rc2";
+15 -7
View File
@@ -46,12 +46,21 @@ export default class AccountSettingsView extends React.Component {
val={this.state.credEdit.val}
done={this.state.credEdit.done}
onShowCountrySelector={this.props.onShowCountrySelector}
onSubmit={this.props.onCredAdd}
onCredAdd={this.props.onCredAdd}
onCredConfirm={this.props.onCredConfirm}
onCancel={_ => this.setState({credEdit: undefined})}
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 = [];
this.state.credentials.forEach((cred, idx) => {
if (!['email', 'tel'].includes(cred.meth)) {
@@ -68,15 +77,14 @@ export default class AccountSettingsView extends React.Component {
credentials.push(
<div className="group quoted" key={idx}>
<tt className="clickable" onClick={e => {e.preventDefault(); this.setState({credEdit: cred});}}>{val}</tt>
<span> {
cred.done ? null :
<>
<i className="material-icons">pending</i>&nbsp;
<span> {cred.done ? null : <i className="material-icons">pending</i>}&nbsp;
{!cred.done || validated[cred.meth] > 1 || this.props.reqCredMethod != cred.meth ?
<a href="#" onClick={e => {e.preventDefault(); this.props.onCredDelete(cred.meth, cred.val);}}>
<i className="material-icons">delete</i>
</a>
</>
}</span>
:
null}
</span>
</div>);
});
if (credentials.length > 0) {
+20 -8
View File
@@ -186,16 +186,23 @@ class MessagesView extends React.Component {
getVisibleMessageRange(holderRect) {
let min = Number.MAX_SAFE_INTEGER, max = -1;
this.chatMessageRefs.forEach((ref, seq) => {
let visibilityStatus = false;
this.chatMessageRefs.every((ref, seq) => {
if (ref.current) {
const { top, bottom, height } = ref.current.getBoundingClientRect();
const visible = top <= holderRect.top ? holderRect.top - top <= height : bottom - holderRect.bottom <= height;
if (visible) {
visibilityStatus = true;
min = Math.min(min, seq);
max = Math.max(max, seq);
} else if (visibilityStatus) {
// The remaining elements are no longer visible, no need to iterate them.
return false;
}
}
return true;
});
return max >= min ? {min: min, max: max} : {min: 0, max: 0};
}
@@ -274,12 +281,12 @@ class MessagesView extends React.Component {
}
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.
const newTopic = (this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic);
if (topic.isP2PType() && newTopic && !IMMEDIATE_P2P_SUBSCRIPTION) {
topic.getMeta(topic.startMetaQuery().withDesc().build());
} else {
} else if (this.props.myUserId) {
this.subscribe(topic);
}
} else if (topic.isSubscribed() && this.state.isReader && !prevState.isReader) {
@@ -321,7 +328,8 @@ class MessagesView extends React.Component {
showGoToLastButton: false,
dragging: false,
pins: [],
selectedPin: 0
selectedPin: 0,
subsVersion: 0
};
} else if (nextProps.topic != prevState.topic) {
const topic = nextProps.tinode.getTopic(nextProps.topic);
@@ -478,7 +486,6 @@ class MessagesView extends React.Component {
// Is this a new topic?
const newTopic = (this.props.newTopicParams && this.props.newTopicParams._topicName == this.props.topic);
// Don't request the tags. They are useless unless the user
// is the owner and is editing the topic.
let getQuery = topic.startMetaQuery().withLaterDesc().withLaterSub().withAux();
@@ -503,6 +510,9 @@ class MessagesView extends React.Component {
if (this.state.topic != ctrl.topic) {
this.setState({topic: ctrl.topic});
}
if (this.state.deleted) {
this.setState({deleted: false});
}
this.props.onNewTopicCreated(this.props.topic, ctrl.topic);
// 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.
@@ -576,13 +586,14 @@ class MessagesView extends React.Component {
showGoToLastButton: (pos > SHOW_GO_TO_LAST_DIST) && (pos < this.state.scrollPosition),
});
if (this.state.fetchingMessages) {
if (this.state.fetchingMessages || this.processingScrollEvent) {
return;
}
if (event.target.scrollTop <= FETCH_PAGE_TRIGGER) {
const topic = this.props.tinode.getTopic(this.state.topic);
if (topic && topic.isSubscribed()) {
this.processingScrollEvent = true;
const {min, max} = this.getVisibleMessageRange(event.target.getBoundingClientRect());
const gaps = topic.msgHasMoreMessages(min, max, false);
if (gaps.length > 0) {
@@ -594,6 +605,7 @@ class MessagesView extends React.Component {
}
}
}
this.processingScrollEvent = false;
}
/* Mount drag and drop events */
@@ -705,12 +717,12 @@ class MessagesView extends React.Component {
if (this.state.topic) {
const subs = [];
const topic = this.props.tinode.getTopic(this.state.topic);
topic.subscribers((sub) => {
topic.subscribers(sub => {
if (sub.online && sub.user != this.props.myUserId) {
subs.push(sub);
}
});
const newState = {onlineSubs: subs};
const newState = {onlineSubs: subs, subsVersion: this.state.subsVersion + 1};
const peer = topic.p2pPeerDesc();
if (peer) {
Object.assign(newState, {
+21 -5
View File
@@ -48,7 +48,23 @@ class PasswordResetView extends React.PureComponent {
componentDidMount() {
const parsed = HashNavigation.parseUrlHash(window.location.hash);
this.setState({token: parsed.params.token, scheme: parsed.params.scheme});
const newState = {
token: parsed.params.token,
scheme: parsed.params.scheme,
code: parsed.params.code || ''
}
this.savedCred = parsed.params.cred;
if (this.props.reqCredMethod && parsed.params.cred) {
newState[this.props.reqCredMethod] = this.savedCred;
}
this.setState(newState);
}
componentDidUpdate(prevProps, prevState) {
if (prevProps.reqCredMethod != this.props.reqCredMethod && this.props.reqCredMethod) {
this.setState({[this.props.reqCredMethod]: this.savedCred || ''});
}
}
handleSubmit(e) {
@@ -57,12 +73,12 @@ class PasswordResetView extends React.PureComponent {
// Reset using token.
this.props.onReset(this.state.password.trim(), {
scheme: 'token',
token: this.state.token
secret: this.state.token
});
} else if (this.state.code && this.props.reqCredMethod) {
// Reset using security code.
// The secret is structured as <code>:<cred_method>:<cred_value>, "123456:email:alice@example.com".
const cred = this.state.email.trim() || this.state.tel.trim();
const cred = this.props.reqCredMethod == 'email' ? this.state.email.trim() : this.state.tel.trim();
this.props.onReset(this.state.password.trim(), {
scheme: 'code',
secret: btoa(`${this.state.code}:${this.props.reqCredMethod}:${cred}`)
@@ -102,7 +118,7 @@ class PasswordResetView extends React.PureComponent {
}
render() {
const showCredentialInput = !(this.state.token && this.state.scheme);
const showCredentialInput = !((this.state.token || (this.state.code && this.props.reqCredMethod)) && this.state.scheme);
const showPasswordInput = !showCredentialInput || this.state.haveCode || this.state.sent;
const passwordInput = (<>
@@ -193,7 +209,7 @@ class PasswordResetView extends React.PureComponent {
{this.state.haveCode || this.state.sent ? codeInput : null}
{showPasswordInput ? passwordInput : null}
<div className="dialog-buttons">
{this.state.haveCode || this.state.sent ? null :
{this.state.haveCode || this.state.sent || this.state.token || this.state.code ? null :
<a href="#" onClick={this.handleShowCodeField} style={{marginRight: 'auto'}}>
<FormattedMessage id="password_i_have_code" defaultMessage="I have 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}
myUserId={this.props.myUserId}
trustedBadges={this.props.trustedBadges}
reqCredMethod={this.props.reqCredMethod}
onShowCountrySelector={this.props.onShowCountrySelector}
onNavigate={this.props.onNavigate}
onCredAdd={this.props.onCredAdd}
+16 -6
View File
@@ -83,7 +83,12 @@ const messages = defineMessages({
cred_confirmed_successfully: {
id: 'cred_confirmed_successfully',
defaultMessage: 'Confirmed successfully',
description: 'Message explaining that the credential was successfully validated.'
description: 'Notification message that the credential was successfully validated.'
},
password_reset_success: {
id: 'password_reset_success',
defaultMessage: 'Password reset successfully',
description: 'Notification message that the password was successfully reset.'
}
});
@@ -763,6 +768,7 @@ class TinodeWeb extends React.Component {
parsed.path[0] = 'cred';
parsed.params['method'] = params.cred[0];
parsed.params['token'] = params.token;
parsed.params['code'] = params.code;
HashNavigation.navigateTo(HashNavigation.composeUrlHash(parsed.path, parsed.params));
}
@@ -848,7 +854,7 @@ class TinodeWeb extends React.Component {
}
} else if (what == 'read') {
this.resetContactList();
} else if (what == 'msg') {
} else if (what == 'msg' && cont) {
// Check if the topic is archived. If so, don't play a sound.
const topic = this.tinode.getTopic(cont.topic);
const archived = topic && topic.isArchived();
@@ -887,7 +893,7 @@ class TinodeWeb extends React.Component {
} else {
// TODO(gene): handle other types of notifications:
// * 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 +1025,7 @@ class TinodeWeb extends React.Component {
} else {
// Currently selected contact deleted
this.setState({
topicSelected: null,
errorText: '',
errorLevel: null,
mobilePanel: 'sidepanel',
@@ -1287,7 +1294,7 @@ class TinodeWeb extends React.Component {
}
handleCredConfirm(method, response) {
TinodeWeb.navigateToCredentialsView({cred: [method]});
TinodeWeb.navigateToCredentialsView({cred: [method], code: response});
}
// User clicked Cancel button in Setting or Sign Up panel.
@@ -1709,6 +1716,7 @@ class TinodeWeb extends React.Component {
if (this.tinode.isAuthenticated()) {
// Adding new email or phone number in account setting.
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'));
} else {
// Credential validation on signup.
@@ -1734,9 +1742,11 @@ class TinodeWeb extends React.Component {
} else {
this.tinode.connect()
.then(_ => this.tinode.updateAccountBasic(null, null, newPassword, {scheme: tempAuth.scheme, secret: secret}))
.then(_ => HashNavigation.navigateTo(''))
.then(_ => {
this.handleError(this.props.intl.formatMessage(messages.password_reset_success), 'info');
HashNavigation.navigateTo('');
})
.catch(err => {
// Socket error
this.handleError(err.message, 'err');
});
}
+1 -1
View File
@@ -100,7 +100,7 @@ class ValidationView extends React.PureComponent {
(numbers_only) => <input type="text" id="enter-confirmation-code"
placeholder={numbers_only}
value={this.state.code} onChange={this.handleCodeChange}
onKeyPress={this.handleKeyPress} required />
onKeyDown={this.handleKeyPress} required />
}</FormattedMessage>
</div>
<div className="dialog-buttons">
+18 -17
View File
@@ -58,8 +58,11 @@ class CredentialEdit extends React.PureComponent {
handleSubmit(e) {
e.preventDefault();
const value = this.props.method == 'email' ? this.state.email : this.state.tel;
if (value) {
this.props.onSubmit(this.props.method, value);
if (this.state.code) {
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});
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');
@@ -68,8 +71,8 @@ class CredentialEdit extends React.PureComponent {
render() {
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 = (
<><div className="panel-form-row">
@@ -140,21 +143,19 @@ class CredentialEdit extends React.PureComponent {
);
return (<form className="panel-form-column" onSubmit={this.handleSubmit}>
{readyForCode ? null :
this.props.method == 'email' ?
changeEmail
: this.props.method == 'tel' ?
changePhone
: null}
{readyForCode ?
(this.props.method == 'email' ? newEmailLabel : this.props.method == 'tel' ? newPhoneLabel : null)
:
(this.props.method == 'email' ? changeEmail : this.props.method == 'tel' ? changePhone : null)
}
<div className="panel-form-row">
<tt className="quoted">{currentValue}</tt>
<tt className="quoted">{formattedValue}</tt>
</div>
{readyForCode ? null :
this.props.method == 'email' ?
newEmailInput
: this.props.method == 'tel' ?
newPhoneInput
: null}
{readyForCode ?
null
:
(this.props.method == 'email' ? newEmailInput : this.props.method == 'tel' ? newPhoneInput : null)
}
{readyForCode ? codeInput : null}
<div className="dialog-buttons">
<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.action ?
<>
&#32;<a href="#"
&nbsp;&#32;<a href="#"
style={{ whiteSpace: 'nowrap' }}
onClick={(e) => {e.preventDefault(); this.props.action();}}>
{this.props.actionText}
+3 -3
View File
@@ -8,7 +8,7 @@ export default class VisiblePassword extends React.PureComponent {
this.inputRef = React.createRef();
this.state = {
value: this.props.value,
value: this.props.value || '',
visible: false
};
@@ -39,7 +39,7 @@ export default class VisiblePassword extends React.PureComponent {
handleKeyDown(e) {
if (e.keyCode == 27) {
// Escape pressed
this.setState({value: this.props.value, visible: false});
this.setState({value: this.props.value || '', visible: false});
if (this.props.onFinished) {
this.props.onFinished();
}
@@ -68,7 +68,7 @@ export default class VisiblePassword extends React.PureComponent {
return (
<div tabIndex="-1" className="group-focus" onBlur={this.handleEditingFinished}>
<input className="with-visibility"
type={this.state.visible ? "text" : "password"}
type={this.state.visible ? 'text' : 'password'}
value={this.state.value}
placeholder={this.props.placeholder}
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
+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
@@ -1 +1 @@
{"version":3,"file":"290.prod.js","mappings":"2MASA,MAAMA,UAA6BC,IAAAA,cACjCC,YAAYC,GACVC,MAAMD,GAENE,KAAKC,UAAY,GACjB,MAAM,kBAAEC,GAAsBJ,EAAMK,KACpCC,EAAAA,SAAuBC,IACPA,EAAGC,KAAKC,MAAM,KACtBC,SAAQC,IACZT,KAAKC,UAAUS,KAAK,CAClBJ,KAAMG,EAAKE,OACXC,KAAMP,EAAGO,KACTC,MAAMC,EAAAA,EAAAA,IAAUT,EAAGO,MACnBG,KAAMb,EAAkBG,EAAGO,KAAM,CAACI,KAAM,YACxC,GACF,IAGJhB,KAAKC,UAAUgB,MAAK,CAACC,EAAGC,IAAMD,EAAEH,KAAKK,cAAcD,EAAEJ,OACvD,CAEAM,oBACMrB,KAAKsB,aACPtB,KAAKsB,YAAYC,eAAe,CAACC,MAAO,SAAUC,OAAQ,WAE9D,CAEAC,SACE,MAAMzB,EAAY,GACZ0B,EAAW3B,KAAKF,MAAM6B,UAAY,KAYxC,OAXA3B,KAAKC,UAAUO,SAAQ,CAACoB,EAAGC,KACzB,MAAMC,EAASF,EAAEhB,MAAQe,EAAW,YAAc,GAClD1B,EAAUS,KAAKd,IAAAA,cAAA,MAAImC,UAAWD,EAAOE,IAAKH,EACxCI,IAAKA,IAAYL,EAAEhB,MAAQe,IAAW3B,KAAKsB,YAAcW,EAAG,EAC5DC,QAASC,GAAKnC,KAAKF,MAAMsC,SAASR,EAAEhB,KAAMgB,EAAEtB,OAC5CV,IAAAA,cAAA,QAAMmC,UAAU,gBAAgBH,EAAEf,MAClCjB,IAAAA,cAAA,QAAMmC,UAAU,WAAU,IAAOH,EAAEb,MACnCnB,IAAAA,cAAA,QAAMmC,UAAU,aAAY,KAAQH,EAAEtB,OAClC,IAINV,IAAAA,cAAA,OAAKmC,UAAU,mBAAmBD,MAAO,CAACO,OAAQ,UAChDzC,IAAAA,cAAA,MAAImC,UAAU,0BACX9B,GAIT,EAGF,SAAeqC,EAAAA,EAAAA,YAAW3C,E","sources":["webpack://tinode-webapp/./src/widgets/phone-country-selector.jsx"],"sourcesContent":["// Selector for country dialing code.\n\nimport React from 'react';\nimport { injectIntl } from 'react-intl';\n\nimport * as dcodes from '../dcodes.json';\n\nimport { flagEmoji } from '../lib/strformat';\n\nclass PhoneCountrySelector extends React.PureComponent {\n constructor(props) {\n super(props);\n\n this.countries = [];\n const { formatDisplayName } = props.intl;\n dcodes.default.forEach(dc => {\n const parts = dc.dial.split(',');\n parts.forEach(part => {\n this.countries.push({\n dial: part.trim(),\n code: dc.code,\n flag: flagEmoji(dc.code),\n name: formatDisplayName(dc.code, {type: 'region'})\n });\n });\n });\n\n this.countries.sort((a, b) => a.name.localeCompare(b.name));\n }\n\n componentDidMount() {\n if (this.selectedRef) {\n this.selectedRef.scrollIntoView({block: 'center', inline: 'nearest'});\n }\n }\n\n render() {\n const countries = [];\n const selected = this.props.selected || 'US';\n this.countries.forEach((c, idx) => {\n const style = (c.code == selected ? 'selected ' : '');\n countries.push(<li className={style} key={idx}\n ref={ref => {if (c.code == selected) {this.selectedRef = ref}}}\n onClick={_ => this.props.onSubmit(c.code, c.dial)}>\n <span className=\"country-flag\">{c.flag}</span>\n <span className=\"country\">&nbsp;{c.name}</span>\n <span className=\"dial-code\">&nbsp;+{c.dial}</span>\n </li>);\n });\n\n return (\n <div className=\"scrollable-panel\" style={{height: '30rem'}}>\n <ul className=\"phone-country-selector\">\n {countries}\n </ul>\n </div>\n );\n }\n}\n\nexport default injectIntl(PhoneCountrySelector);\n"],"names":["PhoneCountrySelector","React","constructor","props","super","this","countries","formatDisplayName","intl","dcodes","dc","dial","split","forEach","part","push","trim","code","flag","flagEmoji","name","type","sort","a","b","localeCompare","componentDidMount","selectedRef","scrollIntoView","block","inline","render","selected","c","idx","style","className","key","ref","onClick","_","onSubmit","height","injectIntl"],"sourceRoot":""}
{"version":3,"file":"290.prod.js","mappings":"2MASA,MAAMA,UAA6BC,IAAAA,cACjCC,YAAYC,GACVC,MAAMD,GAENE,KAAKC,UAAY,GACjB,MAAM,kBAAEC,GAAsBJ,EAAMK,KACpCC,EAAeC,SAAQC,IACPA,EAAGC,KAAKC,MAAM,KACtBH,SAAQI,IACZT,KAAKC,UAAUS,KAAK,CAClBH,KAAME,EAAKE,OACXC,KAAMN,EAAGM,KACTC,MAAMC,EAAAA,EAAAA,IAAUR,EAAGM,MACnBG,KAAMb,EAAkBI,EAAGM,KAAM,CAACI,KAAM,YACxC,GACF,IAGJhB,KAAKC,UAAUgB,MAAK,CAACC,EAAGC,IAAMD,EAAEH,KAAKK,cAAcD,EAAEJ,OACvD,CAEAM,oBACMrB,KAAKsB,aACPtB,KAAKsB,YAAYC,eAAe,CAACC,MAAO,SAAUC,OAAQ,WAE9D,CAEAC,SACE,MAAMzB,EAAY,GACZ0B,EAAW3B,KAAKF,MAAM6B,UAAY,KAYxC,OAXA3B,KAAKC,UAAUI,SAAQ,CAACuB,EAAGC,KACzB,MAAMC,EAASF,EAAEhB,MAAQe,EAAW,YAAc,GAClD1B,EAAUS,KAAKd,IAAAA,cAAA,MAAImC,UAAWD,EAAOE,IAAKH,EACxCI,IAAKA,IAAYL,EAAEhB,MAAQe,IAAW3B,KAAKsB,YAAcW,EAAG,EAC5DC,QAASC,GAAKnC,KAAKF,MAAMsC,SAASR,EAAEhB,KAAMgB,EAAErB,OAC5CX,IAAAA,cAAA,QAAMmC,UAAU,gBAAgBH,EAAEf,MAClCjB,IAAAA,cAAA,QAAMmC,UAAU,WAAU,IAAOH,EAAEb,MACnCnB,IAAAA,cAAA,QAAMmC,UAAU,aAAY,KAAQH,EAAErB,OAClC,IAINX,IAAAA,cAAA,OAAKmC,UAAU,mBAAmBD,MAAO,CAACO,OAAQ,UAChDzC,IAAAA,cAAA,MAAImC,UAAU,0BACX9B,GAIT,EAGF,SAAeqC,EAAAA,EAAAA,YAAW3C,E","sources":["webpack://tinode-webapp/./src/widgets/phone-country-selector.jsx"],"sourcesContent":["// Selector for country dialing code.\n\nimport React from 'react';\nimport { injectIntl } from 'react-intl';\n\nimport * as dcodes from '../dcodes.json';\n\nimport { flagEmoji } from '../lib/strformat';\n\nclass PhoneCountrySelector extends React.PureComponent {\n constructor(props) {\n super(props);\n\n this.countries = [];\n const { formatDisplayName } = props.intl;\n dcodes.default.forEach(dc => {\n const parts = dc.dial.split(',');\n parts.forEach(part => {\n this.countries.push({\n dial: part.trim(),\n code: dc.code,\n flag: flagEmoji(dc.code),\n name: formatDisplayName(dc.code, {type: 'region'})\n });\n });\n });\n\n this.countries.sort((a, b) => a.name.localeCompare(b.name));\n }\n\n componentDidMount() {\n if (this.selectedRef) {\n this.selectedRef.scrollIntoView({block: 'center', inline: 'nearest'});\n }\n }\n\n render() {\n const countries = [];\n const selected = this.props.selected || 'US';\n this.countries.forEach((c, idx) => {\n const style = (c.code == selected ? 'selected ' : '');\n countries.push(<li className={style} key={idx}\n ref={ref => {if (c.code == selected) {this.selectedRef = ref}}}\n onClick={_ => this.props.onSubmit(c.code, c.dial)}>\n <span className=\"country-flag\">{c.flag}</span>\n <span className=\"country\">&nbsp;{c.name}</span>\n <span className=\"dial-code\">&nbsp;+{c.dial}</span>\n </li>);\n });\n\n return (\n <div className=\"scrollable-panel\" style={{height: '30rem'}}>\n <ul className=\"phone-country-selector\">\n {countries}\n </ul>\n </div>\n );\n }\n}\n\nexport default injectIntl(PhoneCountrySelector);\n"],"names":["PhoneCountrySelector","React","constructor","props","super","this","countries","formatDisplayName","intl","dcodes","forEach","dc","dial","split","part","push","trim","code","flag","flagEmoji","name","type","sort","a","b","localeCompare","componentDidMount","selectedRef","scrollIntoView","block","inline","render","selected","c","idx","style","className","key","ref","onClick","_","onSubmit","height","injectIntl"],"sourceRoot":""}
+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
+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
+24876 -23054
View File
File diff suppressed because it is too large Load Diff
+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
+20 -9
View File
@@ -61,13 +61,20 @@ class AccountSettingsView extends (react__WEBPACK_IMPORTED_MODULE_0___default().
val: this.state.credEdit.val,
done: this.state.credEdit.done,
onShowCountrySelector: this.props.onShowCountrySelector,
onSubmit: this.props.onCredAdd,
onCredAdd: this.props.onCredAdd,
onCredConfirm: this.props.onCredConfirm,
onCancel: _ => this.setState({
credEdit: undefined
}),
onError: this.props.onError
});
}
const validated = {};
this.state.credentials.forEach(cred => {
if (cred.done) {
validated[cred.meth] = (validated[cred.meth] || 0) + 1;
}
});
const credentials = [];
this.state.credentials.forEach((cred, idx) => {
if (!['email', 'tel'].includes(cred.meth)) {
@@ -89,9 +96,9 @@ class AccountSettingsView extends (react__WEBPACK_IMPORTED_MODULE_0___default().
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"
}, "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: "#",
onClick: e => {
e.preventDefault();
@@ -99,7 +106,7 @@ class AccountSettingsView extends (react__WEBPACK_IMPORTED_MODULE_0___default().
}
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("i", {
className: "material-icons"
}, "delete"))))));
}, "delete")) : null)));
});
if (credentials.length > 0) {
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) {
e.preventDefault();
const value = this.props.method == 'email' ? this.state.email : this.state.tel;
if (value) {
this.props.onSubmit(this.props.method, value);
if (this.state.code) {
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
});
@@ -324,7 +334,8 @@ class CredentialEdit extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureC
}
render() {
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", {
className: "panel-form-row"
}, 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", {
className: "panel-form-column",
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"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("tt", {
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"
}, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("button", {
className: "secondary",
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+20 -7
View File
@@ -61,20 +61,33 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
}
componentDidMount() {
const parsed = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_4__["default"].parseUrlHash(window.location.hash);
this.setState({
const newState = {
token: parsed.params.token,
scheme: parsed.params.scheme
});
scheme: parsed.params.scheme,
code: parsed.params.code || ''
};
this.savedCred = parsed.params.cred;
if (this.props.reqCredMethod && parsed.params.cred) {
newState[this.props.reqCredMethod] = this.savedCred;
}
this.setState(newState);
}
componentDidUpdate(prevProps, prevState) {
if (prevProps.reqCredMethod != this.props.reqCredMethod && this.props.reqCredMethod) {
this.setState({
[this.props.reqCredMethod]: this.savedCred || ''
});
}
}
handleSubmit(e) {
e.preventDefault();
if (this.state.token) {
this.props.onReset(this.state.password.trim(), {
scheme: 'token',
token: this.state.token
secret: this.state.token
});
} else if (this.state.code && this.props.reqCredMethod) {
const cred = this.state.email.trim() || this.state.tel.trim();
const cred = this.props.reqCredMethod == 'email' ? this.state.email.trim() : this.state.tel.trim();
this.props.onReset(this.state.password.trim(), {
scheme: 'code',
secret: btoa(`${this.state.code}:${this.props.reqCredMethod}:${cred}`)
@@ -119,7 +132,7 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
});
}
render() {
const showCredentialInput = !(this.state.token && this.state.scheme);
const showCredentialInput = !((this.state.token || this.state.code && this.props.reqCredMethod) && this.state.scheme);
const showPasswordInput = !showCredentialInput || this.state.haveCode || this.state.sent;
const passwordInput = react__WEBPACK_IMPORTED_MODULE_0___default().createElement((react__WEBPACK_IMPORTED_MODULE_0___default().Fragment), null, react__WEBPACK_IMPORTED_MODULE_0___default().createElement("label", {
className: "small gray",
@@ -222,7 +235,7 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
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", {
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 || this.state.code ? null : react__WEBPACK_IMPORTED_MODULE_0___default().createElement("a", {
href: "#",
onClick: this.handleShowCodeField,
style: {
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
{"version":3,"file":"src_widgets_phone-country-selector_jsx.dev.js","mappings":";;;;;;;;;;;;;;;;;;;AAE0B;AACc;AAEC;AAEI;AAE7C,MAAMI,oBAAoB,SAASJ,4DAAmB,CAAC;EACrDM,WAAWA,CAACC,KAAK,EAAE;IACjB,KAAK,CAACA,KAAK,CAAC;IAEZ,IAAI,CAACC,SAAS,GAAG,EAAE;IACnB,MAAM;MAAEC;IAAkB,CAAC,GAAGF,KAAK,CAACG,IAAI;IACxCR,iDAAsB,CAACW,EAAE,IAAI;MAC3B,MAAMC,KAAK,GAAGD,EAAE,CAACE,IAAI,CAACC,KAAK,CAAC,GAAG,CAAC;MAChCF,KAAK,CAACF,OAAO,CAACK,IAAI,IAAI;QACpB,IAAI,CAACT,SAAS,CAACU,IAAI,CAAC;UAClBH,IAAI,EAAEE,IAAI,CAACE,IAAI,EAAE;UACjBC,IAAI,EAAEP,EAAE,CAACO,IAAI;UACbC,IAAI,EAAElB,yDAAS,CAACU,EAAE,CAACO,IAAI,CAAC;UACxBE,IAAI,EAAEb,iBAAiB,CAACI,EAAE,CAACO,IAAI,EAAE;YAACG,IAAI,EAAE;UAAQ,CAAC;QACnD,CAAC,CAAC;MACJ,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,IAAI,CAACf,SAAS,CAACgB,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAKD,CAAC,CAACH,IAAI,CAACK,aAAa,CAACD,CAAC,CAACJ,IAAI,CAAC,CAAC;EAC7D;EAEAM,iBAAiBA,CAAA,EAAG;IAClB,IAAI,IAAI,CAACC,WAAW,EAAE;MACpB,IAAI,CAACA,WAAW,CAACC,cAAc,CAAC;QAACC,KAAK,EAAE,QAAQ;QAAEC,MAAM,EAAE;MAAS,CAAC,CAAC;IACvE;EACF;EAEAC,MAAMA,CAAA,EAAG;IACP,MAAMzB,SAAS,GAAG,EAAE;IACpB,MAAM0B,QAAQ,GAAG,IAAI,CAAC3B,KAAK,CAAC2B,QAAQ,IAAI,IAAI;IAC5C,IAAI,CAAC1B,SAAS,CAACI,OAAO,CAAC,CAACuB,CAAC,EAAEC,GAAG,KAAK;MACjC,MAAMC,KAAK,GAAIF,CAAC,CAACf,IAAI,IAAIc,QAAQ,GAAG,WAAW,GAAG,EAAG;MACrD1B,SAAS,CAACU,IAAI,CAAClB,0DAAA;QAAIuC,SAAS,EAAEF,KAAM;QAACG,GAAG,EAAEJ,GAAI;QAC5CK,GAAG,EAAEA,GAAG,IAAI;UAAC,IAAIN,CAAC,CAACf,IAAI,IAAIc,QAAQ,EAAE;YAAC,IAAI,CAACL,WAAW,GAAGY,GAAG;UAAA;QAAC,CAAE;QAC/DC,OAAO,EAAEC,CAAC,IAAI,IAAI,CAACpC,KAAK,CAACqC,QAAQ,CAACT,CAAC,CAACf,IAAI,EAAEe,CAAC,CAACpB,IAAI;MAAE,GAClDf,0DAAA;QAAMuC,SAAS,EAAC;MAAc,GAAEJ,CAAC,CAACd,IAAI,CAAQ,EAC9CrB,0DAAA;QAAMuC,SAAS,EAAC;MAAS,GAAC,MAAM,EAACJ,CAAC,CAACb,IAAI,CAAQ,EAC/CtB,0DAAA;QAAMuC,SAAS,EAAC;MAAW,GAAC,OAAO,EAACJ,CAAC,CAACpB,IAAI,CAAQ,CAC/C,CAAC;IACR,CAAC,CAAC;IAEF,OACEf,0DAAA;MAAKuC,SAAS,EAAC,kBAAkB;MAACF,KAAK,EAAE;QAACQ,MAAM,EAAE;MAAO;IAAE,GACzD7C,0DAAA;MAAIuC,SAAS,EAAC;IAAwB,GACnC/B,SAAS,CACP,CACD;EAEV;AACF;AAEA,iEAAeP,sDAAU,CAACG,oBAAoB,CAAC","sources":["webpack://tinode-webapp/./src/widgets/phone-country-selector.jsx"],"sourcesContent":["// Selector for country dialing code.\n\nimport React from 'react';\nimport { injectIntl } from 'react-intl';\n\nimport * as dcodes from '../dcodes.json';\n\nimport { flagEmoji } from '../lib/strformat';\n\nclass PhoneCountrySelector extends React.PureComponent {\n constructor(props) {\n super(props);\n\n this.countries = [];\n const { formatDisplayName } = props.intl;\n dcodes.default.forEach(dc => {\n const parts = dc.dial.split(',');\n parts.forEach(part => {\n this.countries.push({\n dial: part.trim(),\n code: dc.code,\n flag: flagEmoji(dc.code),\n name: formatDisplayName(dc.code, {type: 'region'})\n });\n });\n });\n\n this.countries.sort((a, b) => a.name.localeCompare(b.name));\n }\n\n componentDidMount() {\n if (this.selectedRef) {\n this.selectedRef.scrollIntoView({block: 'center', inline: 'nearest'});\n }\n }\n\n render() {\n const countries = [];\n const selected = this.props.selected || 'US';\n this.countries.forEach((c, idx) => {\n const style = (c.code == selected ? 'selected ' : '');\n countries.push(<li className={style} key={idx}\n ref={ref => {if (c.code == selected) {this.selectedRef = ref}}}\n onClick={_ => this.props.onSubmit(c.code, c.dial)}>\n <span className=\"country-flag\">{c.flag}</span>\n <span className=\"country\">&nbsp;{c.name}</span>\n <span className=\"dial-code\">&nbsp;+{c.dial}</span>\n </li>);\n });\n\n return (\n <div className=\"scrollable-panel\" style={{height: '30rem'}}>\n <ul className=\"phone-country-selector\">\n {countries}\n </ul>\n </div>\n );\n }\n}\n\nexport default injectIntl(PhoneCountrySelector);\n"],"names":["React","injectIntl","dcodes","flagEmoji","PhoneCountrySelector","PureComponent","constructor","props","countries","formatDisplayName","intl","default","forEach","dc","parts","dial","split","part","push","trim","code","flag","name","type","sort","a","b","localeCompare","componentDidMount","selectedRef","scrollIntoView","block","inline","render","selected","c","idx","style","createElement","className","key","ref","onClick","_","onSubmit","height"],"sourceRoot":""}
{"version":3,"file":"src_widgets_phone-country-selector_jsx.dev.js","mappings":";;;;;;;;;;;;;;;;;;;AAE0B;AACc;AAEC;AAEI;AAE7C,MAAMI,oBAAoB,SAASJ,4DAAmB,CAAC;EACrDM,WAAWA,CAACC,KAAK,EAAE;IACjB,KAAK,CAACA,KAAK,CAAC;IAEZ,IAAI,CAACC,SAAS,GAAG,EAAE;IACnB,MAAM;MAAEC;IAAkB,CAAC,GAAGF,KAAK,CAACG,IAAI;IACxCR,yCAAc,CAACU,OAAO,CAACC,EAAE,IAAI;MAC3B,MAAMC,KAAK,GAAGD,EAAE,CAACE,IAAI,CAACC,KAAK,CAAC,GAAG,CAAC;MAChCF,KAAK,CAACF,OAAO,CAACK,IAAI,IAAI;QACpB,IAAI,CAACT,SAAS,CAACU,IAAI,CAAC;UAClBH,IAAI,EAAEE,IAAI,CAACE,IAAI,CAAC,CAAC;UACjBC,IAAI,EAAEP,EAAE,CAACO,IAAI;UACbC,IAAI,EAAElB,yDAAS,CAACU,EAAE,CAACO,IAAI,CAAC;UACxBE,IAAI,EAAEb,iBAAiB,CAACI,EAAE,CAACO,IAAI,EAAE;YAACG,IAAI,EAAE;UAAQ,CAAC;QACnD,CAAC,CAAC;MACJ,CAAC,CAAC;IACJ,CAAC,CAAC;IAEF,IAAI,CAACf,SAAS,CAACgB,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC,KAAKD,CAAC,CAACH,IAAI,CAACK,aAAa,CAACD,CAAC,CAACJ,IAAI,CAAC,CAAC;EAC7D;EAEAM,iBAAiBA,CAAA,EAAG;IAClB,IAAI,IAAI,CAACC,WAAW,EAAE;MACpB,IAAI,CAACA,WAAW,CAACC,cAAc,CAAC;QAACC,KAAK,EAAE,QAAQ;QAAEC,MAAM,EAAE;MAAS,CAAC,CAAC;IACvE;EACF;EAEAC,MAAMA,CAAA,EAAG;IACP,MAAMzB,SAAS,GAAG,EAAE;IACpB,MAAM0B,QAAQ,GAAG,IAAI,CAAC3B,KAAK,CAAC2B,QAAQ,IAAI,IAAI;IAC5C,IAAI,CAAC1B,SAAS,CAACI,OAAO,CAAC,CAACuB,CAAC,EAAEC,GAAG,KAAK;MACjC,MAAMC,KAAK,GAAIF,CAAC,CAACf,IAAI,IAAIc,QAAQ,GAAG,WAAW,GAAG,EAAG;MACrD1B,SAAS,CAACU,IAAI,CAAClB,0DAAA;QAAIuC,SAAS,EAAEF,KAAM;QAACG,GAAG,EAAEJ,GAAI;QAC5CK,GAAG,EAAEA,GAAG,IAAI;UAAC,IAAIN,CAAC,CAACf,IAAI,IAAIc,QAAQ,EAAE;YAAC,IAAI,CAACL,WAAW,GAAGY,GAAG;UAAA;QAAC,CAAE;QAC/DC,OAAO,EAAEC,CAAC,IAAI,IAAI,CAACpC,KAAK,CAACqC,QAAQ,CAACT,CAAC,CAACf,IAAI,EAAEe,CAAC,CAACpB,IAAI;MAAE,GAClDf,0DAAA;QAAMuC,SAAS,EAAC;MAAc,GAAEJ,CAAC,CAACd,IAAW,CAAC,EAC9CrB,0DAAA;QAAMuC,SAAS,EAAC;MAAS,GAAC,MAAM,EAACJ,CAAC,CAACb,IAAW,CAAC,EAC/CtB,0DAAA;QAAMuC,SAAS,EAAC;MAAW,GAAC,OAAO,EAACJ,CAAC,CAACpB,IAAW,CAC/C,CAAC,CAAC;IACR,CAAC,CAAC;IAEF,OACEf,0DAAA;MAAKuC,SAAS,EAAC,kBAAkB;MAACF,KAAK,EAAE;QAACQ,MAAM,EAAE;MAAO;IAAE,GACzD7C,0DAAA;MAAIuC,SAAS,EAAC;IAAwB,GACnC/B,SACC,CACD,CAAC;EAEV;AACF;AAEA,iEAAeP,sDAAU,CAACG,oBAAoB,CAAC","sources":["webpack://tinode-webapp/./src/widgets/phone-country-selector.jsx"],"sourcesContent":["// Selector for country dialing code.\n\nimport React from 'react';\nimport { injectIntl } from 'react-intl';\n\nimport * as dcodes from '../dcodes.json';\n\nimport { flagEmoji } from '../lib/strformat';\n\nclass PhoneCountrySelector extends React.PureComponent {\n constructor(props) {\n super(props);\n\n this.countries = [];\n const { formatDisplayName } = props.intl;\n dcodes.default.forEach(dc => {\n const parts = dc.dial.split(',');\n parts.forEach(part => {\n this.countries.push({\n dial: part.trim(),\n code: dc.code,\n flag: flagEmoji(dc.code),\n name: formatDisplayName(dc.code, {type: 'region'})\n });\n });\n });\n\n this.countries.sort((a, b) => a.name.localeCompare(b.name));\n }\n\n componentDidMount() {\n if (this.selectedRef) {\n this.selectedRef.scrollIntoView({block: 'center', inline: 'nearest'});\n }\n }\n\n render() {\n const countries = [];\n const selected = this.props.selected || 'US';\n this.countries.forEach((c, idx) => {\n const style = (c.code == selected ? 'selected ' : '');\n countries.push(<li className={style} key={idx}\n ref={ref => {if (c.code == selected) {this.selectedRef = ref}}}\n onClick={_ => this.props.onSubmit(c.code, c.dial)}>\n <span className=\"country-flag\">{c.flag}</span>\n <span className=\"country\">&nbsp;{c.name}</span>\n <span className=\"dial-code\">&nbsp;+{c.dial}</span>\n </li>);\n });\n\n return (\n <div className=\"scrollable-panel\" style={{height: '30rem'}}>\n <ul className=\"phone-country-selector\">\n {countries}\n </ul>\n </div>\n );\n }\n}\n\nexport default injectIntl(PhoneCountrySelector);\n"],"names":["React","injectIntl","dcodes","flagEmoji","PhoneCountrySelector","PureComponent","constructor","props","countries","formatDisplayName","intl","default","forEach","dc","parts","dial","split","part","push","trim","code","flag","name","type","sort","a","b","localeCompare","componentDidMount","selectedRef","scrollIntoView","block","inline","render","selected","c","idx","style","createElement","className","key","ref","onClick","_","onSubmit","height"],"sourceRoot":""}
+92 -71
View File
@@ -378,34 +378,34 @@ class CommError extends Error {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "DEFAULT_MESSAGES_PAGE": () => (/* binding */ DEFAULT_MESSAGES_PAGE),
/* harmony export */ "DEL_CHAR": () => (/* binding */ DEL_CHAR),
/* harmony export */ "EXPIRE_PROMISES_PERIOD": () => (/* binding */ EXPIRE_PROMISES_PERIOD),
/* harmony export */ "EXPIRE_PROMISES_TIMEOUT": () => (/* binding */ EXPIRE_PROMISES_TIMEOUT),
/* harmony export */ "LIBRARY": () => (/* binding */ LIBRARY),
/* harmony export */ "LOCAL_SEQID": () => (/* binding */ LOCAL_SEQID),
/* harmony export */ "MAX_PINNED_COUNT": () => (/* binding */ MAX_PINNED_COUNT),
/* harmony export */ "MESSAGE_STATUS_FAILED": () => (/* binding */ MESSAGE_STATUS_FAILED),
/* harmony export */ "MESSAGE_STATUS_FATAL": () => (/* binding */ MESSAGE_STATUS_FATAL),
/* harmony export */ "MESSAGE_STATUS_NONE": () => (/* binding */ MESSAGE_STATUS_NONE),
/* harmony export */ "MESSAGE_STATUS_QUEUED": () => (/* binding */ MESSAGE_STATUS_QUEUED),
/* harmony export */ "MESSAGE_STATUS_READ": () => (/* binding */ MESSAGE_STATUS_READ),
/* harmony export */ "MESSAGE_STATUS_RECEIVED": () => (/* binding */ MESSAGE_STATUS_RECEIVED),
/* harmony export */ "MESSAGE_STATUS_SENDING": () => (/* binding */ MESSAGE_STATUS_SENDING),
/* harmony export */ "MESSAGE_STATUS_SENT": () => (/* binding */ MESSAGE_STATUS_SENT),
/* harmony export */ "MESSAGE_STATUS_TO_ME": () => (/* binding */ MESSAGE_STATUS_TO_ME),
/* harmony export */ "PROTOCOL_VERSION": () => (/* binding */ PROTOCOL_VERSION),
/* harmony export */ "RECV_TIMEOUT": () => (/* binding */ RECV_TIMEOUT),
/* harmony export */ "TOPIC_CHAN": () => (/* binding */ TOPIC_CHAN),
/* harmony export */ "TOPIC_FND": () => (/* binding */ TOPIC_FND),
/* harmony export */ "TOPIC_GRP": () => (/* binding */ TOPIC_GRP),
/* harmony export */ "TOPIC_ME": () => (/* binding */ TOPIC_ME),
/* harmony export */ "TOPIC_NEW": () => (/* binding */ TOPIC_NEW),
/* harmony export */ "TOPIC_NEW_CHAN": () => (/* binding */ TOPIC_NEW_CHAN),
/* harmony export */ "TOPIC_P2P": () => (/* binding */ TOPIC_P2P),
/* harmony export */ "TOPIC_SYS": () => (/* binding */ TOPIC_SYS),
/* harmony export */ "USER_NEW": () => (/* binding */ USER_NEW),
/* harmony export */ "VERSION": () => (/* binding */ VERSION)
/* harmony export */ DEFAULT_MESSAGES_PAGE: () => (/* binding */ DEFAULT_MESSAGES_PAGE),
/* harmony export */ DEL_CHAR: () => (/* binding */ DEL_CHAR),
/* harmony export */ EXPIRE_PROMISES_PERIOD: () => (/* binding */ EXPIRE_PROMISES_PERIOD),
/* harmony export */ EXPIRE_PROMISES_TIMEOUT: () => (/* binding */ EXPIRE_PROMISES_TIMEOUT),
/* harmony export */ LIBRARY: () => (/* binding */ LIBRARY),
/* harmony export */ LOCAL_SEQID: () => (/* binding */ LOCAL_SEQID),
/* harmony export */ MAX_PINNED_COUNT: () => (/* binding */ MAX_PINNED_COUNT),
/* harmony export */ MESSAGE_STATUS_FAILED: () => (/* binding */ MESSAGE_STATUS_FAILED),
/* harmony export */ MESSAGE_STATUS_FATAL: () => (/* binding */ MESSAGE_STATUS_FATAL),
/* harmony export */ MESSAGE_STATUS_NONE: () => (/* binding */ MESSAGE_STATUS_NONE),
/* harmony export */ MESSAGE_STATUS_QUEUED: () => (/* binding */ MESSAGE_STATUS_QUEUED),
/* harmony export */ MESSAGE_STATUS_READ: () => (/* binding */ MESSAGE_STATUS_READ),
/* harmony export */ MESSAGE_STATUS_RECEIVED: () => (/* binding */ MESSAGE_STATUS_RECEIVED),
/* harmony export */ MESSAGE_STATUS_SENDING: () => (/* binding */ MESSAGE_STATUS_SENDING),
/* harmony export */ MESSAGE_STATUS_SENT: () => (/* binding */ MESSAGE_STATUS_SENT),
/* harmony export */ MESSAGE_STATUS_TO_ME: () => (/* binding */ MESSAGE_STATUS_TO_ME),
/* harmony export */ PROTOCOL_VERSION: () => (/* binding */ PROTOCOL_VERSION),
/* harmony export */ RECV_TIMEOUT: () => (/* binding */ RECV_TIMEOUT),
/* harmony export */ TOPIC_CHAN: () => (/* binding */ TOPIC_CHAN),
/* harmony export */ TOPIC_FND: () => (/* binding */ TOPIC_FND),
/* harmony export */ TOPIC_GRP: () => (/* binding */ TOPIC_GRP),
/* harmony export */ TOPIC_ME: () => (/* binding */ TOPIC_ME),
/* harmony export */ TOPIC_NEW: () => (/* binding */ TOPIC_NEW),
/* harmony export */ TOPIC_NEW_CHAN: () => (/* binding */ TOPIC_NEW_CHAN),
/* harmony export */ TOPIC_P2P: () => (/* binding */ TOPIC_P2P),
/* harmony export */ TOPIC_SYS: () => (/* binding */ TOPIC_SYS),
/* harmony export */ USER_NEW: () => (/* binding */ USER_NEW),
/* harmony export */ VERSION: () => (/* binding */ VERSION)
/* harmony export */ });
/* harmony import */ var _version_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../version.js */ "./version.js");
@@ -792,7 +792,7 @@ class DB {
#onError = _ => {};
#logger = _ => {};
db = null;
disabled = false;
disabled = true;
constructor(onError, logger) {
this.#onError = onError || this.#onError;
this.#logger = logger || this.#logger;
@@ -906,7 +906,7 @@ class DB {
};
});
}
markTopicAsDeleted(name) {
markTopicAsDeleted(name, deleted) {
if (!this.isReady()) {
return this.disabled ? Promise.resolve() : Promise.reject(new Error("not initialized"));
}
@@ -922,8 +922,10 @@ class DB {
const req = trx.objectStore('topic').get(name);
req.onsuccess = event => {
const topic = event.target.result;
topic._deleted = true;
trx.objectStore('topic').put(topic);
if (topic && topic._deleted != deleted) {
topic._deleted = deleted;
trx.objectStore('topic').put(topic);
}
trx.commit();
};
});
@@ -3049,7 +3051,7 @@ class TopicFnd extends _topic_js__WEBPACK_IMPORTED_MODULE_1__["default"] {
constructor(callbacks) {
super(_config_js__WEBPACK_IMPORTED_MODULE_0__.TOPIC_FND, callbacks);
}
_processMetaSub(subs) {
_processMetaSubs(subs) {
let updateCount = Object.getOwnPropertyNames(this._contacts).length;
this._contacts = {};
for (let idx in subs) {
@@ -3374,7 +3376,7 @@ class TopicMe extends _topic_js__WEBPACK_IMPORTED_MODULE_2__["default"] {
this.onMetaDesc(this);
}
}
_processMetaSub(subs) {
_processMetaSubs(subs) {
let updateCount = 0;
subs.forEach(sub => {
const topicName = sub.topic;
@@ -3491,12 +3493,14 @@ class TopicMe extends _topic_js__WEBPACK_IMPORTED_MODULE_2__["default"] {
this.getMeta(this.startMetaQuery().withLaterOneSub(pres.src).build());
break;
case 'acs':
if (cont.acs) {
cont.acs.updateAll(pres.dacs);
} else {
cont.acs = new _access_mode_js__WEBPACK_IMPORTED_MODULE_0__["default"]().updateAll(pres.dacs);
if (!pres.tgt) {
if (cont.acs) {
cont.acs.updateAll(pres.dacs);
} else {
cont.acs = new _access_mode_js__WEBPACK_IMPORTED_MODULE_0__["default"]().updateAll(pres.dacs);
}
cont.touched = new Date();
}
cont.touched = new Date();
break;
case 'ua':
cont.seen = {
@@ -3515,10 +3519,11 @@ class TopicMe extends _topic_js__WEBPACK_IMPORTED_MODULE_2__["default"] {
cont.unread = cont.seq - cont.read;
break;
case 'gone':
this._tinode.cacheRemTopic(pres.src);
if (!cont._deleted) {
cont._deleted = true;
cont._attached = false;
this._tinode._db.markTopicAsDeleted(pres.src);
this._tinode._db.markTopicAsDeleted(pres.src, true);
} else {
this._tinode._db.remTopic(pres.src);
}
@@ -3548,7 +3553,13 @@ class TopicMe extends _topic_js__WEBPACK_IMPORTED_MODULE_2__["default"] {
}
} else if (pres.what == 'tags') {
this.getMeta(this.startMetaQuery().withTags().build());
} else if (pres.what == 'msg') {
this.getMeta(this.startMetaQuery().withOneSub(undefined, pres.src).build());
const dummy = this._tinode.getTopic(pres.src);
dummy._deleted = false;
this._tinode._db.updTopic(dummy);
}
this._refreshContact(pres.what, cont);
}
if (this.onPres) {
this.onPres(pres);
@@ -3627,13 +3638,13 @@ class MetaGetBuilder {
this.what = {};
}
#get_desc_ims() {
return this.topic.updated;
return this.topic._deleted ? undefined : this.topic.updated;
}
#get_subs_ims() {
if (this.topic.isP2PType()) {
return this.#get_desc_ims();
}
return this.topic._lastSubsUpdate;
return this.topic._deleted ? undefined : this.topic._lastSubsUpdate;
}
withData(since, before, limit) {
this.what['data'] = {
@@ -3858,9 +3869,6 @@ class Topic {
if (this._attached) {
return Promise.resolve(this);
}
if (this._deleted) {
return Promise.reject(new Error("Conversation deleted"));
}
return this._tinode.subscribe(this.name || _config_js__WEBPACK_IMPORTED_MODULE_3__.TOPIC_NEW, getParams, setParams).then(ctrl => {
if (ctrl.code >= 300) {
return ctrl;
@@ -4067,7 +4075,7 @@ class Topic {
}
}
params.sub._noForwarding = true;
this._processMetaSub([params.sub]);
this._processMetaSubs([params.sub]);
}
if (params.desc) {
if (ctrl.params && ctrl.params.acs) {
@@ -4248,7 +4256,7 @@ class Topic {
}
if (update) {
this._tinode.note(this.name, what, seq);
this._updateReadRecv(what, seq);
this._updateMyReadRecv(what, seq);
if (this.acs != null && !this.acs.isMuted()) {
const me = this._tinode.getMeTopic();
me._refreshContact(what, this);
@@ -4284,7 +4292,7 @@ class Topic {
}
return this._tinode.videoCall(this.name, seq, evt, payload);
}
_updateReadRecv(what, seq, ts) {
_updateMyReadRecv(what, seq, ts) {
let oldVal,
doUpdate = false;
seq = seq | 0;
@@ -4455,6 +4463,9 @@ class Topic {
}
msgHasMoreMessages(min, max, newer) {
const gaps = [];
if (min >= max) {
return gaps;
}
let maxSeq = 0;
let gap;
this._messages.forEach((msg, prev) => {
@@ -4666,7 +4677,15 @@ class Topic {
this.onData(data);
}
const what = outgoing ? 'read' : 'msg';
this._updateReadRecv(what, data.seq, data.ts);
this._updateMyReadRecv(what, data.seq, data.ts);
if (!outgoing && data.from) {
this._routeInfo({
what: 'read',
from: data.from,
seq: data.seq,
_noForwarding: true
});
}
this._tinode.getMeTopic()._refreshContact(what, this);
}
_routeMeta(meta) {
@@ -4674,7 +4693,7 @@ class Topic {
this._processMetaDesc(meta.desc);
}
if (meta.sub && meta.sub.length > 0) {
this._processMetaSub(meta.sub);
this._processMetaSubs(meta.sub);
}
if (meta.del) {
this._processDelMessages(meta.del.clear, meta.del.delseq);
@@ -4712,7 +4731,7 @@ class Topic {
break;
case 'upd':
if (pres.src && !this._tinode.isTopicCached(pres.src)) {
this.getMeta(this.startMetaQuery().withLaterOneSub(pres.src).build());
this.getMeta(this.startMetaQuery().withOneSub(undefined, pres.src).build());
}
break;
case 'aux':
@@ -4735,11 +4754,11 @@ class Topic {
user.acs = acs;
}
user.updated = new Date();
this._processMetaSub([user]);
this._processMetaSubs([user]);
}
} else {
user.acs.updateAll(pres.dacs);
this._processMetaSub([{
this._processMetaSubs([{
user: uid,
updated: new Date(),
acs: user.acs
@@ -4768,12 +4787,14 @@ class Topic {
if (msg) {
this.msgStatus(msg, true);
}
if (this._tinode.isMe(info.from)) {
this._updateReadRecv(info.what, info.seq);
if (this._tinode.isMe(info.from) && !info._noForwarding) {
this._updateMyReadRecv(info.what, info.seq);
}
this._tinode.getMeTopic()._refreshContact(info.what, this);
break;
case 'kp':
case 'kpa':
case 'kpv':
break;
case 'call':
break;
@@ -4804,7 +4825,7 @@ class Topic {
this.onMetaDesc(this);
}
}
_processMetaSub(subs) {
_processMetaSubs(subs) {
for (let idx in subs) {
const sub = subs[idx];
sub.online = !!sub.online;
@@ -4970,16 +4991,16 @@ class Topic {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "clipRange": () => (/* binding */ clipRange),
/* harmony export */ "isUrlRelative": () => (/* binding */ isUrlRelative),
/* harmony export */ "jsonParseHelper": () => (/* binding */ jsonParseHelper),
/* harmony export */ "listToRanges": () => (/* binding */ listToRanges),
/* harmony export */ "mergeObj": () => (/* binding */ mergeObj),
/* harmony export */ "mergeToCache": () => (/* binding */ mergeToCache),
/* harmony export */ "normalizeArray": () => (/* binding */ normalizeArray),
/* harmony export */ "normalizeRanges": () => (/* binding */ normalizeRanges),
/* harmony export */ "rfc3339DateString": () => (/* binding */ rfc3339DateString),
/* harmony export */ "simplify": () => (/* binding */ simplify)
/* harmony export */ clipRange: () => (/* binding */ clipRange),
/* harmony export */ isUrlRelative: () => (/* binding */ isUrlRelative),
/* harmony export */ jsonParseHelper: () => (/* binding */ jsonParseHelper),
/* harmony export */ listToRanges: () => (/* binding */ listToRanges),
/* harmony export */ mergeObj: () => (/* binding */ mergeObj),
/* harmony export */ mergeToCache: () => (/* binding */ mergeToCache),
/* harmony export */ normalizeArray: () => (/* binding */ normalizeArray),
/* harmony export */ normalizeRanges: () => (/* binding */ normalizeRanges),
/* harmony export */ rfc3339DateString: () => (/* binding */ rfc3339DateString),
/* harmony export */ simplify: () => (/* binding */ simplify)
/* harmony export */ });
/* harmony import */ var _access_mode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./access-mode.js */ "./src/access-mode.js");
/* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./config.js */ "./src/config.js");
@@ -5181,7 +5202,7 @@ function clipRange(src, clip) {
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "PACKAGE_VERSION": () => (/* binding */ PACKAGE_VERSION)
/* harmony export */ PACKAGE_VERSION: () => (/* binding */ PACKAGE_VERSION)
/* harmony export */ });
const PACKAGE_VERSION = "0.23.0-rc1";
@@ -5275,9 +5296,9 @@ var __webpack_exports__ = {};
\***********************/
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "AccessMode": () => (/* reexport safe */ _access_mode_js__WEBPACK_IMPORTED_MODULE_0__["default"]),
/* harmony export */ "Drafty": () => (/* reexport default from dynamic */ _drafty_js__WEBPACK_IMPORTED_MODULE_5___default.a),
/* harmony export */ "Tinode": () => (/* binding */ Tinode)
/* harmony export */ AccessMode: () => (/* reexport safe */ _access_mode_js__WEBPACK_IMPORTED_MODULE_0__["default"]),
/* harmony export */ Drafty: () => (/* reexport default from dynamic */ _drafty_js__WEBPACK_IMPORTED_MODULE_5___default.a),
/* harmony export */ Tinode: () => (/* binding */ Tinode)
/* harmony export */ });
/* harmony import */ var _access_mode_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./access-mode.js */ "./src/access-mode.js");
/* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./config.js */ "./src/config.js");
@@ -5712,7 +5733,7 @@ class Tinode {
} else if (pkt.ctrl.params.what == 'sub') {
const topic = this.#cacheGet('topic', pkt.ctrl.topic);
if (topic) {
topic._processMetaSub([]);
topic._processMetaSubs([]);
}
}
}
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
+1 -1
View File
@@ -1,3 +1,3 @@
// This is a generated file. Don't edit.
const PACKAGE_VERSION = "0.23.0-rc1";
const PACKAGE_VERSION = "0.23.0-rc2";