merge devel

This commit is contained in:
or-else
2023-06-09 17:16:22 -07:00
68 changed files with 1769 additions and 1273 deletions
+2 -2
View File
@@ -83,8 +83,8 @@
"babel-plugin-formatjs": "^10.4.0", "babel-plugin-formatjs": "^10.4.0",
"browserslist": "^4.21.5", "browserslist": "^4.21.5",
"copy-webpack-plugin": "^11.0.0", "copy-webpack-plugin": "^11.0.0",
"cssnano": "^5.1.15", "cssnano": "^6.0.1",
"glob": "^9.3.0", "glob": "^10.2.7",
"postcss": "^8.4.21", "postcss": "^8.4.21",
"postcss-cli": "^10.1.0", "postcss-cli": "^10.1.0",
"webpack": "^5.76.1", "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); const args = process.argv.slice(2);
function getLocaleFromFileName(filename) { function getLocaleFromFileName(filename) {
const parts = filename.split('/'); const parts = filename.split(path.sep);
return parts[parts.length - 1].split('.json')[0]; 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": { "cred_confirmed_successfully": {
"translation": "Erfolgreich bestätigt", "translation": "Erfolgreich bestätigt",
"defaultMessage": "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, "missing": false,
"obsolete": false "obsolete": false
}, },
@@ -1647,5 +1647,12 @@
"description": "Menu item [Unpin] for un-pinning the message.", "description": "Menu item [Unpin] for un-pinning the message.",
"missing": true, "missing": true,
"obsolete": false "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": { "cred_confirmed_successfully": {
"translation": "Confirmed successfully", "translation": "Confirmed successfully",
"defaultMessage": "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, "missing": false,
"obsolete": false "obsolete": false
}, },
@@ -1647,5 +1647,12 @@
"description": "Menu item [Unpin] for un-pinning the message.", "description": "Menu item [Unpin] for un-pinning the message.",
"missing": false, "missing": false,
"obsolete": 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": { "cred_confirmed_successfully": {
"translation": "Confirmado con éxito", "translation": "Confirmado con éxito",
"defaultMessage": "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, "missing": false,
"obsolete": false "obsolete": false
}, },
@@ -1647,5 +1647,12 @@
"description": "Error message when audio is not available", "description": "Error message when audio is not available",
"missing": false, "missing": false,
"obsolete": false "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
@@ -209,7 +209,7 @@
}, },
"cred_confirmed_successfully": { "cred_confirmed_successfully": {
"defaultMessage": "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": { "credential_email_prompt": {
"defaultMessage": "Your registration email", "defaultMessage": "Your registration email",
@@ -704,6 +704,10 @@
"defaultMessage": "A text message with security code has been sent.", "defaultMessage": "A text message with security code has been sent.",
"description": "Notification that the SMS with password reset instructions 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": { "password_unchanged_prompt": {
"defaultMessage": "Unchanged", "defaultMessage": "Unchanged",
"description": "Message in editor while password is unchanged" "description": "Message in editor while password is unchanged"
+8 -1
View File
@@ -1420,7 +1420,7 @@
"cred_confirmed_successfully": { "cred_confirmed_successfully": {
"translation": "Confirmé avec succès", "translation": "Confirmé avec succès",
"defaultMessage": "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, "missing": false,
"obsolete": false "obsolete": false
}, },
@@ -1647,5 +1647,12 @@
"description": "Error message when audio is not available", "description": "Error message when audio is not available",
"missing": false, "missing": false,
"obsolete": false "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": { "cred_confirmed_successfully": {
"translation": "성공적으로 확인됨", "translation": "성공적으로 확인됨",
"defaultMessage": "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, "missing": false,
"obsolete": false "obsolete": false
}, },
@@ -1647,5 +1647,12 @@
"description": "Error message when audio is not available", "description": "Error message when audio is not available",
"missing": false, "missing": false,
"obsolete": false "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": { "cred_confirmed_successfully": {
"translation": "Confirmat cu succes", "translation": "Confirmat cu succes",
"defaultMessage": "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, "missing": false,
"obsolete": false "obsolete": false
}, },
@@ -1647,5 +1647,12 @@
"description": "Error message when audio is not available", "description": "Error message when audio is not available",
"missing": false, "missing": false,
"obsolete": false "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": { "cred_confirmed_successfully": {
"translation": "Подтверждено успешно", "translation": "Подтверждено успешно",
"defaultMessage": "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, "missing": false,
"obsolete": false "obsolete": false
}, },
@@ -1647,5 +1647,12 @@
"description": "Error message when audio is not available", "description": "Error message when audio is not available",
"missing": false, "missing": false,
"obsolete": false "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": { "cred_confirmed_successfully": {
"translation": "確認成功", "translation": "確認成功",
"defaultMessage": "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, "missing": false,
"obsolete": false "obsolete": false
}, },
@@ -1647,5 +1647,12 @@
"description": "Error message when audio is not available", "description": "Error message when audio is not available",
"missing": false, "missing": false,
"obsolete": false "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": { "cred_confirmed_successfully": {
"translation": "确认成功", "translation": "确认成功",
"defaultMessage": "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, "missing": false,
"obsolete": false "obsolete": false
}, },
@@ -1647,5 +1647,12 @@
"description": "Error message when audio is not available", "description": "Error message when audio is not available",
"missing": false, "missing": false,
"obsolete": false "obsolete": false
},
"password_reset_success": {
"translation": "密码重置成功",
"defaultMessage": "Password reset successfully",
"description": "Notification message that the password was successfully reset.",
"missing": false,
"obsolete": false
} }
} }
+1 -1
View File
@@ -4,7 +4,7 @@ export default class HashNavigation {
// Parse hash as in http://www.example.com/path#hash as if it were // Parse hash as in http://www.example.com/path#hash as if it were
// path and arguments. // path and arguments.
static parseUrlHash(hash) { 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 parts = hash.split('?', 2);
const params = {}; const params = {};
let path = []; let path = [];
+4 -3
View File
@@ -327,7 +327,8 @@ class MessagesView extends React.Component {
showGoToLastButton: false, showGoToLastButton: false,
dragging: false, dragging: false,
pins: [], pins: [],
selectedPin: 0 selectedPin: 0,
subsVersion: 0
}; };
} else if (nextProps.topic != prevState.topic) { } else if (nextProps.topic != prevState.topic) {
const topic = nextProps.tinode.getTopic(nextProps.topic); const topic = nextProps.tinode.getTopic(nextProps.topic);
@@ -715,12 +716,12 @@ class MessagesView extends React.Component {
if (this.state.topic) { if (this.state.topic) {
const subs = []; const subs = [];
const topic = this.props.tinode.getTopic(this.state.topic); const topic = this.props.tinode.getTopic(this.state.topic);
topic.subscribers((sub) => { topic.subscribers(sub => {
if (sub.online && sub.user != this.props.myUserId) { if (sub.online && sub.user != this.props.myUserId) {
subs.push(sub); subs.push(sub);
} }
}); });
const newState = {onlineSubs: subs}; const newState = {onlineSubs: subs, subsVersion: this.state.subsVersion + 1};
const peer = topic.p2pPeerDesc(); const peer = topic.p2pPeerDesc();
if (peer) { if (peer) {
Object.assign(newState, { Object.assign(newState, {
+20 -4
View File
@@ -48,7 +48,23 @@ class PasswordResetView extends React.PureComponent {
componentDidMount() { componentDidMount() {
const parsed = HashNavigation.parseUrlHash(window.location.hash); 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) { handleSubmit(e) {
@@ -62,7 +78,7 @@ class PasswordResetView extends React.PureComponent {
} else if (this.state.code && this.props.reqCredMethod) { } else if (this.state.code && this.props.reqCredMethod) {
// Reset using security code. // Reset using security code.
// The secret is structured as <code>:<cred_method>:<cred_value>, "123456:email:alice@example.com". // 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(), { this.props.onReset(this.state.password.trim(), {
scheme: 'code', scheme: 'code',
secret: btoa(`${this.state.code}:${this.props.reqCredMethod}:${cred}`) secret: btoa(`${this.state.code}:${this.props.reqCredMethod}:${cred}`)
@@ -102,7 +118,7 @@ class PasswordResetView extends React.PureComponent {
} }
render() { 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 showPasswordInput = !showCredentialInput || this.state.haveCode || this.state.sent;
const passwordInput = (<> const passwordInput = (<>
@@ -193,7 +209,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 || this.state.token ? null : {this.state.haveCode || this.state.sent || this.state.token || this.state.code ? 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" />
+10 -3
View File
@@ -83,7 +83,12 @@ const messages = defineMessages({
cred_confirmed_successfully: { cred_confirmed_successfully: {
id: 'cred_confirmed_successfully', id: 'cred_confirmed_successfully',
defaultMessage: '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.'
} }
}); });
@@ -1733,9 +1738,11 @@ class TinodeWeb extends React.Component {
} else { } else {
this.tinode.connect() this.tinode.connect()
.then(_ => this.tinode.updateAccountBasic(null, null, newPassword, {scheme: tempAuth.scheme, secret: secret})) .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 => { .catch(err => {
// Socket error
this.handleError(err.message, 'err'); this.handleError(err.message, 'err');
}); });
} }
+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
+932 -294
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
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+19 -6
View File
@@ -61,10 +61,23 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
} }
componentDidMount() { componentDidMount() {
const parsed = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_4__["default"].parseUrlHash(window.location.hash); const parsed = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_4__["default"].parseUrlHash(window.location.hash);
this.setState({ const newState = {
token: parsed.params.token, 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) { handleSubmit(e) {
e.preventDefault(); e.preventDefault();
@@ -74,7 +87,7 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
secret: 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.props.reqCredMethod == 'email' ? this.state.email.trim() : this.state.tel.trim();
this.props.onReset(this.state.password.trim(), { this.props.onReset(this.state.password.trim(), {
scheme: 'code', scheme: 'code',
secret: btoa(`${this.state.code}:${this.props.reqCredMethod}:${cred}`) secret: btoa(`${this.state.code}:${this.props.reqCredMethod}:${cred}`)
@@ -119,7 +132,7 @@ class PasswordResetView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Pu
}); });
} }
render() { 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 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", { 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", className: "small gray",
@@ -222,7 +235,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 || this.state.token ? 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: "#", href: "#",
onClick: this.handleShowCodeField, onClick: this.handleShowCodeField,
style: { 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":""}
+484 -837
View File
File diff suppressed because it is too large Load Diff
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