a lot of refactoring of topic-info

This commit is contained in:
or-else
2021-08-06 14:58:05 -07:00
parent 642821db9f
commit 6d4ff9d625
23 changed files with 832 additions and 386 deletions
+25 -4
View File
@@ -466,7 +466,7 @@
"defaultMessage": "Default access mode:",
"description": "Section title",
"missing": false,
"obsolete": false
"obsolete": true
},
"label_default_access_mode": {
"translation": "Standard Zugriffsmodus:",
@@ -1031,7 +1031,7 @@
"defaultMessage": "General",
"description": "Sidepanel title for TopicCommonView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_notifications": {
"translation": "Benachrichtigungen",
@@ -1045,7 +1045,7 @@
"defaultMessage": "Security",
"description": "Sidepanel title for AccSecurityView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_support": {
"translation": "Unterstützung",
@@ -1087,7 +1087,7 @@
"defaultMessage": "Drag to Adjust",
"description": "Sidepanel title for AvatarCropView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_login": {
"translation": "Anmelden",
@@ -1289,6 +1289,27 @@
"translation": "Sicherheit",
"defaultMessage": "Security",
"description": "Navigaton button for security panel.",
"missing": false,
"obsolete": false
},
"panel_title_acc_general": {
"translation": "",
"defaultMessage": "General",
"description": "Title for TopicCommonView.",
"missing": true,
"obsolete": false
},
"panel_title_acc_security": {
"translation": "",
"defaultMessage": "Security",
"description": "Title for TopicSecirityView and AccSecurityView.",
"missing": true,
"obsolete": false
},
"panel_title_crop": {
"translation": "",
"defaultMessage": "Drag to Adjust",
"description": "Title for AvatarCropView.",
"missing": true,
"obsolete": false
}
+25 -4
View File
@@ -466,7 +466,7 @@
"defaultMessage": "Default access mode:",
"description": "Section title",
"missing": false,
"obsolete": false
"obsolete": true
},
"label_default_access_mode": {
"translation": "Default access mode:",
@@ -1031,7 +1031,7 @@
"defaultMessage": "General",
"description": "Sidepanel title for TopicCommonView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_notifications": {
"translation": "Notifications",
@@ -1045,7 +1045,7 @@
"defaultMessage": "Security",
"description": "Sidepanel title for AccSecurityView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_support": {
"translation": "Support",
@@ -1087,7 +1087,7 @@
"defaultMessage": "Drag to Adjust",
"description": "Sidepanel title for AvatarCropView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_login": {
"translation": "Sign In",
@@ -1291,5 +1291,26 @@
"description": "Navigaton button for security panel.",
"missing": false,
"obsolete": false
},
"panel_title_acc_general": {
"translation": "General",
"defaultMessage": "General",
"description": "Title for TopicCommonView.",
"missing": false,
"obsolete": false
},
"panel_title_acc_security": {
"translation": "Security",
"defaultMessage": "Security",
"description": "Title for TopicSecirityView and AccSecurityView.",
"missing": false,
"obsolete": false
},
"panel_title_crop": {
"translation": "Drag to Adjust",
"defaultMessage": "Drag to Adjust",
"description": "Title for AvatarCropView.",
"missing": false,
"obsolete": false
}
}
+25 -4
View File
@@ -466,7 +466,7 @@
"defaultMessage": "Default access mode:",
"description": "Section title",
"missing": false,
"obsolete": false
"obsolete": true
},
"label_default_access_mode": {
"translation": "Modo de acceso predeterminado:",
@@ -1031,7 +1031,7 @@
"defaultMessage": "General",
"description": "Sidepanel title for TopicCommonView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_notifications": {
"translation": "Notificaciones",
@@ -1045,7 +1045,7 @@
"defaultMessage": "Security",
"description": "Sidepanel title for AccSecurityView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_support": {
"translation": "Soporte",
@@ -1087,7 +1087,7 @@
"defaultMessage": "Drag to Adjust",
"description": "Sidepanel title for AvatarCropView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_login": {
"translation": "Iniciar sesión",
@@ -1291,5 +1291,26 @@
"description": "Navigaton button for security panel.",
"missing": true,
"obsolete": false
},
"panel_title_acc_general": {
"translation": "",
"defaultMessage": "General",
"description": "Title for TopicCommonView.",
"missing": true,
"obsolete": false
},
"panel_title_acc_security": {
"translation": "",
"defaultMessage": "Security",
"description": "Title for TopicSecirityView and AccSecurityView.",
"missing": true,
"obsolete": false
},
"panel_title_crop": {
"translation": "",
"defaultMessage": "Drag to Adjust",
"description": "Title for AvatarCropView.",
"missing": true,
"obsolete": false
}
}
+12 -16
View File
@@ -267,10 +267,6 @@
"defaultMessage": "Content type:",
"description": "Label for file content type (mime)"
},
"label_default_access": {
"defaultMessage": "Default access mode:",
"description": "Section title"
},
"label_default_access_mode": {
"defaultMessage": "Default access mode:",
"description": "Label for default access mode"
@@ -501,6 +497,18 @@
"defaultMessage": "online now",
"description": "Indicator that the user or topic is currently online"
},
"panel_title_acc_general": {
"defaultMessage": "General",
"description": "Title for TopicCommonView."
},
"panel_title_acc_security": {
"defaultMessage": "Security",
"description": "Title for TopicSecirityView and AccSecurityView."
},
"panel_title_crop": {
"defaultMessage": "Drag to Adjust",
"description": "Title for AvatarCropView."
},
"password_prompt": {
"defaultMessage": "Password",
"description": "Placeholder/prompt for entering password"
@@ -593,18 +601,10 @@
"defaultMessage": "List like email:alice@example.com, tel:17025550003...",
"description": "Placeholder in contacts search field"
},
"sidepanel_title_acc_general": {
"defaultMessage": "General",
"description": "Sidepanel title for TopicCommonView."
},
"sidepanel_title_acc_notifications": {
"defaultMessage": "Notifications",
"description": "Sidepanel title for AccNotificationsView."
},
"sidepanel_title_acc_security": {
"defaultMessage": "Security",
"description": "Sidepanel title for AccSecurityView."
},
"sidepanel_title_acc_support": {
"defaultMessage": "Support",
"description": "Sidepanel title for AccSupportView."
@@ -625,10 +625,6 @@
"defaultMessage": "Confirm Credentials",
"description": "Sidepanel title for ValidationView."
},
"sidepanel_title_crop": {
"defaultMessage": "Drag to Adjust",
"description": "Sidepanel title for AvatarCropView."
},
"sidepanel_title_login": {
"defaultMessage": "Sign In",
"description": "Sidepanel title for LoginView."
+25 -4
View File
@@ -466,7 +466,7 @@
"defaultMessage": "Default access mode:",
"description": "Section title",
"missing": false,
"obsolete": false
"obsolete": true
},
"label_default_access_mode": {
"translation": "기본액세스모드: ",
@@ -1031,7 +1031,7 @@
"defaultMessage": "General",
"description": "Sidepanel title for TopicCommonView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_notifications": {
"translation": "알림",
@@ -1045,7 +1045,7 @@
"defaultMessage": "Security",
"description": "Sidepanel title for AccSecurityView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_support": {
"translation": "지원",
@@ -1087,7 +1087,7 @@
"defaultMessage": "Drag to Adjust",
"description": "Sidepanel title for AvatarCropView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_login": {
"translation": "로그인",
@@ -1301,5 +1301,26 @@
"description": "Navigaton button for security panel.",
"missing": true,
"obsolete": false
},
"panel_title_acc_general": {
"translation": "",
"defaultMessage": "General",
"description": "Title for TopicCommonView.",
"missing": true,
"obsolete": false
},
"panel_title_acc_security": {
"translation": "",
"defaultMessage": "Security",
"description": "Title for TopicSecirityView and AccSecurityView.",
"missing": true,
"obsolete": false
},
"panel_title_crop": {
"translation": "",
"defaultMessage": "Drag to Adjust",
"description": "Title for AvatarCropView.",
"missing": true,
"obsolete": false
}
}
+25 -4
View File
@@ -466,7 +466,7 @@
"defaultMessage": "Default access mode:",
"description": "Section title",
"missing": false,
"obsolete": false
"obsolete": true
},
"label_default_access_mode": {
"translation": "Default access mode:",
@@ -1031,7 +1031,7 @@
"defaultMessage": "General",
"description": "Sidepanel title for TopicCommonView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_notifications": {
"translation": "Notificări",
@@ -1045,7 +1045,7 @@
"defaultMessage": "Security",
"description": "Sidepanel title for AccSecurityView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_support": {
"translation": "Ajutor",
@@ -1087,7 +1087,7 @@
"defaultMessage": "Drag to Adjust",
"description": "Sidepanel title for AvatarCropView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_login": {
"translation": "Conectează-te",
@@ -1291,5 +1291,26 @@
"description": "Navigaton button for security panel.",
"missing": true,
"obsolete": false
},
"panel_title_acc_general": {
"translation": "",
"defaultMessage": "General",
"description": "Title for TopicCommonView.",
"missing": true,
"obsolete": false
},
"panel_title_acc_security": {
"translation": "",
"defaultMessage": "Security",
"description": "Title for TopicSecirityView and AccSecurityView.",
"missing": true,
"obsolete": false
},
"panel_title_crop": {
"translation": "",
"defaultMessage": "Drag to Adjust",
"description": "Title for AvatarCropView.",
"missing": true,
"obsolete": false
}
}
+25 -4
View File
@@ -466,7 +466,7 @@
"defaultMessage": "Default access mode:",
"description": "Section title",
"missing": false,
"obsolete": false
"obsolete": true
},
"label_default_access_mode": {
"translation": "Доступ по умолчанию:",
@@ -1031,7 +1031,7 @@
"defaultMessage": "General",
"description": "Sidepanel title for TopicCommonView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_notifications": {
"translation": "Уведомления",
@@ -1045,7 +1045,7 @@
"defaultMessage": "Security",
"description": "Sidepanel title for AccSecurityView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_support": {
"translation": "Поддержка",
@@ -1087,7 +1087,7 @@
"defaultMessage": "Drag to Adjust",
"description": "Sidepanel title for AvatarCropView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_login": {
"translation": "Авторизация",
@@ -1291,5 +1291,26 @@
"description": "Navigaton button for security panel.",
"missing": true,
"obsolete": false
},
"panel_title_acc_general": {
"translation": "",
"defaultMessage": "General",
"description": "Title for TopicCommonView.",
"missing": true,
"obsolete": false
},
"panel_title_acc_security": {
"translation": "",
"defaultMessage": "Security",
"description": "Title for TopicSecirityView and AccSecurityView.",
"missing": true,
"obsolete": false
},
"panel_title_crop": {
"translation": "",
"defaultMessage": "Drag to Adjust",
"description": "Title for AvatarCropView.",
"missing": true,
"obsolete": false
}
}
+26 -5
View File
@@ -462,7 +462,7 @@
"defaultMessage": "Default access mode:",
"description": "Section title",
"missing": false,
"obsolete": false
"obsolete": true
},
"label_default_access_mode": {
"translation": "預設存取模式:",
@@ -1026,7 +1026,7 @@
"defaultMessage": "General",
"description": "Sidepanel title for TopicCommonView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_notifications": {
"translation": "通知",
@@ -1040,7 +1040,7 @@
"defaultMessage": "Security",
"description": "Sidepanel title for AccSecurityView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_support": {
"translation": "支援",
@@ -1080,8 +1080,8 @@
"sidepanel_title_crop": {
"defaultMessage": "Drag to Adjust",
"description": "Sidepanel title for AvatarCropView.",
"missing": true,
"obsolete": false
"missing": false,
"obsolete": true
},
"sidepanel_title_login": {
"translation": "登入",
@@ -1290,5 +1290,26 @@
"description": "Navigaton button for security panel.",
"missing": true,
"obsolete": false
},
"panel_title_acc_general": {
"translation": "",
"defaultMessage": "General",
"description": "Title for TopicCommonView.",
"missing": true,
"obsolete": false
},
"panel_title_acc_security": {
"translation": "",
"defaultMessage": "Security",
"description": "Title for TopicSecirityView and AccSecurityView.",
"missing": true,
"obsolete": false
},
"panel_title_crop": {
"translation": "",
"defaultMessage": "Drag to Adjust",
"description": "Title for AvatarCropView.",
"missing": true,
"obsolete": false
}
}
+25 -4
View File
@@ -466,7 +466,7 @@
"defaultMessage": "Default access mode:",
"description": "Section title",
"missing": false,
"obsolete": false
"obsolete": true
},
"label_default_access_mode": {
"translation": "蓦然访问模式:",
@@ -1031,7 +1031,7 @@
"defaultMessage": "General",
"description": "Sidepanel title for TopicCommonView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_notifications": {
"translation": "通知",
@@ -1045,7 +1045,7 @@
"defaultMessage": "Security",
"description": "Sidepanel title for AccSecurityView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_acc_support": {
"translation": "支持",
@@ -1087,7 +1087,7 @@
"defaultMessage": "Drag to Adjust",
"description": "Sidepanel title for AvatarCropView.",
"missing": false,
"obsolete": false
"obsolete": true
},
"sidepanel_title_login": {
"translation": "登录",
@@ -1291,5 +1291,26 @@
"description": "Navigaton button for security panel.",
"missing": true,
"obsolete": false
},
"panel_title_acc_general": {
"translation": "",
"defaultMessage": "General",
"description": "Title for TopicCommonView.",
"missing": true,
"obsolete": false
},
"panel_title_acc_security": {
"translation": "",
"defaultMessage": "Security",
"description": "Title for TopicSecirityView and AccSecurityView.",
"missing": true,
"obsolete": false
},
"panel_title_crop": {
"translation": "",
"defaultMessage": "Drag to Adjust",
"description": "Title for AvatarCropView.",
"missing": true,
"obsolete": false
}
}
+6 -2
View File
@@ -9,7 +9,7 @@ export default class HashNavigation {
const params = {};
let path = [];
if (parts[0]) {
path = parts[0].substr(1).split('/');
path = parts[0].replace('#', '').split('/');
}
if (parts[1]) {
parts[1].split('&').forEach(function(part) {
@@ -60,7 +60,11 @@ export default class HashNavigation {
static setUrlInfoPanel(hash, infopanel) {
const parsed = this.parseUrlHash(hash);
parsed.params.info = infopanel;
if (infopanel) {
parsed.params.info = infopanel;
} else {
delete parsed.params.info;
}
return this.composeUrlHash(parsed.path, parsed.params);
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+43 -121
View File
@@ -4,6 +4,7 @@ import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import Tinode from 'tinode-sdk';
import TopicCommonView from './topic-common-view.jsx';
import TopicSecurityView from './topic-security-view.jsx';
import AvatarUpload from '../widgets/avatar-upload.jsx';
@@ -24,6 +25,26 @@ import { makeImageUrl } from '../lib/blob-helpers.js';
import { arrayEqual, theCard } from '../lib/utils.js';
const messages = defineMessages({
info: {
id: 'title_info',
description: 'Title for InfoView',
defaultMessage: 'Info'
},
general: {
id: 'panel_title_acc_general',
description: 'Title for TopicCommonView.',
defaultMessage: 'General'
},
security: {
id: 'panel_title_acc_security',
description: 'Title for TopicSecirityView and AccSecurityView.',
defaultMessage: 'Security'
},
crop: {
id: 'panel_title_crop',
description: 'Title for AvatarCropView.',
defaultMessage: 'Drag to Adjust'
},
requested: {
id: 'requested_permissions',
defaultMessage: 'Requested',
@@ -39,11 +60,6 @@ const messages = defineMessages({
defaultMessage: 'Edit permissions',
description: 'Menu item [Edit permissions]'
},
other_user: {
id: 'label_other_user',
defaultMessage: 'Other',
description: 'Label for the other user when the user is unnamed'
},
});
function _clip(str, length) {
@@ -77,20 +93,17 @@ class InfoView extends React.Component {
auth: null,
anon: null,
contactList: [],
tags: [],
trustedBadges: [],
showMemberPanel: false,
showPermissionEditorFor: undefined,
previousMetaDesc: undefined,
previousSubsUpdated: undefined,
previousTagsUpdated: undefined
};
this.resetSubs = this.resetSubs.bind(this);
this.resetDesc = this.resetDesc.bind(this);
this.onMetaDesc = this.onMetaDesc.bind(this);
this.onSubsUpdated = this.onSubsUpdated.bind(this);
this.onTagsUpdated = this.onTagsUpdated.bind(this);
this.handleFullNameUpdate = this.handleFullNameUpdate.bind(this);
this.handlePrivateUpdate = this.handlePrivateUpdate.bind(this);
this.handleImageChanged = this.handleImageChanged.bind(this);
@@ -102,8 +115,8 @@ class InfoView extends React.Component {
this.handleHideAddMembers = this.handleHideAddMembers.bind(this);
this.handleMemberUpdateRequest = this.handleMemberUpdateRequest.bind(this);
this.handleMemberSelected = this.handleMemberSelected.bind(this);
this.handleTagsUpdated = this.handleTagsUpdated.bind(this);
this.handleContextMenu = this.handleContextMenu.bind(this);
this.handleBackNavigate = this.handleBackNavigate.bind(this);
}
// No need to separately handle component mount.
@@ -119,13 +132,6 @@ class InfoView extends React.Component {
this.previousSubsUpdated = topic.onSubsUpdated;
topic.onSubsUpdated = this.onSubsUpdated;
if (topic.getType() == 'grp') {
this.previousTagsUpdated = topic.onTagsUpdated;
topic.onTagsUpdated = this.onTagsUpdated;
} else {
this.previousTagsUpdated = undefined;
}
}
if (this.state.topic != props.topic) {
@@ -143,7 +149,6 @@ class InfoView extends React.Component {
this.setState({topic: null});
topic.onMetaDesc = this.previousMetaDesc;
topic.onSubsUpdated = this.previousSubsUpdated;
topic.onTagsUpdated = this.previousTagsUpdated;
}
resetSubs(topic, props) {
@@ -233,14 +238,6 @@ class InfoView extends React.Component {
}
}
onTagsUpdated(tags) {
this.setState({tags: tags});
if (this.previousTagsUpdated && this.previousTagsUpdated != this.onTagsUpdated) {
this.previousTagsUpdated();
}
}
handleFullNameUpdate(fn) {
fn = fn.trim().substring(0, MAX_TITLE_LENGTH);
if (this.state.fullName !== fn) {
@@ -389,9 +386,11 @@ class InfoView extends React.Component {
this.setState({selectedContact: uid});
}
handleTagsUpdated(tags) {
if (!arrayEqual(this.state.tags.slice(0), tags.slice(0))) {
this.props.onTopicTagsUpdate(this.props.topic, tags);
handleBackNavigate() {
if (this.props.panel == 'info') {
this.props.onNavigate(null);
} else {
this.props.onNavigate('info');
}
}
@@ -423,16 +422,16 @@ class InfoView extends React.Component {
}
render() {
const view = this.props.panel || 'info';
const {formatMessage} = this.props.intl;
const panelTitle = formatMessage(messages[view] || messages['info']);
return (
<div id="info-view">
<div className="caption-panel" id="info-caption-panel">
<div className="panel-title" id="info-title">
<FormattedMessage id="title_info" defaultMessage="Info" description="Title for InfoView" />
</div>
<div className="panel-title" id="info-title">{panelTitle}</div>
<div>
<MenuCancel onCancel={this.props.onCancel} />
<MenuCancel onCancel={this.handleBackNavigate} />
</div>
</div>
{this.props.displayMobile ?
@@ -464,6 +463,18 @@ class InfoView extends React.Component {
onCancel={this.handleHidePermissionsEditor}
/>
:
this.props.panel == 'general' ?
<TopicCommonView
tinode={this.props.tinode}
topic={this.props.topic}
/>
:
this.props.panel == 'security' ?
<TopicSecurityView
tinode={this.props.tinode}
topic={this.props.topic}
/>
:
<div id="info-view-content" className="scrollable-panel">
<div className="panel-form-column">
<a href="#" className="flat-button float-right" onClick={(e) => {e.preventDefault(); this.props.onNavigate('general');}}>
@@ -528,96 +539,7 @@ class InfoView extends React.Component {
<i className="material-icons">security</i>&nbsp;<FormattedMessage id="button_security"
defaultMessage="Security" description="Navigaton button for security panel." />
</a>
{this.state.moreInfoExpanded ?
<div className="panel-form-column">
{this.state.groupTopic ?
<div className="panel-form-row">
<label>
<FormattedMessage id="label_your_permissions" defaultMessage="Your permissions:"
description="Label for current user permissions" />
</label>
<tt className="clickable"
onClick={this.handleLaunchPermissionsEditor.bind(this, 'want')}>
{this.state.access}
</tt>
</div>
:
<div>
<div>
<label className="small">
<FormattedMessage id="label_permissions" defaultMessage="Permissions:"
description="Section title" />
</label>
</div>
<div className="quoted">
<div>
<FormattedMessage id="label_you" defaultMessage="You:"
description="Label for the current user" /> &nbsp;<tt className="clickable"
onClick={this.handleLaunchPermissionsEditor.bind(this, 'want')}>
{this.state.access}
</tt></div>
<div>{this.state.fullName ? this.state.fullName : formatMessage(messages.other_user)}:
&nbsp;<tt className="clickable" onClick={this.handleLaunchPermissionsEditor.bind(this, 'given')}>
{this.state.modeGiven2}
</tt>
</div>
</div>
</div>
}
{this.state.sharer && (this.state.auth || this.state.anon) ?
<div>
<div>
<label className="small">
<FormattedMessage id="label_default_access" defaultMessage="Default access mode:"
description="Section title" />
</label>
</div>
<div className="quoted">
<div>Auth: {this.state.admin ?
<tt className="clickable"
onClick={this.handleLaunchPermissionsEditor.bind(this, 'auth')}>
{this.state.auth}
</tt>
:
<tt>{this.state.auth}</tt>
}
</div>
<div>Anon: {this.state.admin ?
<tt className="clickable"
onClick={this.handleLaunchPermissionsEditor.bind(this, 'anon')}>
{this.state.anon}
</tt>
:
<tt>{this.state.anon}</tt>
}
</div>
</div>
</div>
:
null
}
</div>
:
null
}
</div>
<div className="hr" />
{this.state.owner ?
<>
<FormattedMessage id="title_tag_manager" defaultMessage="Tags (user discovery)"
description="Section title for TagManager">{
(tags) => <TagManager
title={tags}
tags={this.state.tags}
activated={false}
tinode={this.props.tinode}
onSubmit={this.handleTagsUpdated} />
}</FormattedMessage>
<div className="hr" />
</>
:
null
}
{this.state.groupTopic && this.state.sharer ?
<>
<div className="hr" />
+6 -6
View File
@@ -41,18 +41,18 @@ const messages = defineMessages({
defaultMessage: 'Account Settings'
},
general: {
id: 'sidepanel_title_acc_general',
description: 'Sidepanel title for TopicCommonView.',
id: 'panel_title_acc_general',
description: 'Title for TopicCommonView.',
defaultMessage: 'General'
},
security: {
id: 'sidepanel_title_acc_security',
description: 'Sidepanel title for AccSecurityView.',
id: 'panel_title_acc_security',
description: 'Title for TopicSecirityView and AccSecurityView.',
defaultMessage: 'Security'
},
crop: {
id: 'sidepanel_title_crop',
description: 'Sidepanel title for AvatarCropView.',
id: 'panel_title_crop',
description: 'Title for AvatarCropView.',
defaultMessage: 'Drag to Adjust'
},
notif: {
-7
View File
@@ -133,7 +133,6 @@ class TinodeWeb extends React.Component {
this.handleHideContextMenu = this.handleHideContextMenu.bind(this);
this.handleShowAlert = this.handleShowAlert.bind(this);
this.handleShowInfoView = this.handleShowInfoView.bind(this);
this.handleHideInfoView = this.handleHideInfoView.bind(this);
this.handleMemberUpdateRequest = this.handleMemberUpdateRequest.bind(this);
this.handleValidateCredentialsRequest = this.handleValidateCredentialsRequest.bind(this);
this.handlePasswordResetRequest = this.handlePasswordResetRequest.bind(this);
@@ -1444,11 +1443,6 @@ class TinodeWeb extends React.Component {
this.setState({infoPanel: 'info'});
}
handleHideInfoView() {
HashNavigation.navigateTo(HashNavigation.removeUrlParam(window.location.hash, 'info'));
this.setState({infoPanel: undefined});
}
handleMemberUpdateRequest(topicName, added, removed) {
if (!topicName) {
return;
@@ -1669,7 +1663,6 @@ class TinodeWeb extends React.Component {
onNavigate={this.infoNavigator}
onTopicDescUpdate={this.handleTopicUpdateRequest}
onCancel={this.handleHideInfoView}
onShowAlert={this.handleShowAlert}
onChangePermissions={this.handleChangePermissions}
onMemberUpdateRequest={this.handleMemberUpdateRequest}
+56 -3
View File
@@ -26,23 +26,46 @@ export default class TopicCommonView extends React.Component {
owner: acs && acs.isOwner(),
credentials: topic.getCredentials() || [],
addCredActive: false,
addCredInvalid: false
addCredInvalid: false,
tags: [],
previousTagsUpdated: undefined
};
this.onTagsUpdated = this.onTagsUpdated.bind(this);
this.handleTagsUpdated = this.handleTagsUpdated.bind(this);
this.tnCredsUpdated = this.tnCredsUpdated.bind(this);
this.handleCredChange = this.handleCredChange.bind(this);
this.handleCredKeyDown = this.handleCredKeyDown.bind(this);
this.handleCredEntered = this.handleCredEntered.bind(this);
}
componentDidMount() {
const topic = this.props.tinode.getTopic(this.props.topic);
// No need to separately handle component mount.
componentDidUpdate(props) {
const topic = this.props.tinode.getTopic(props.topic);
if (!topic) {
return;
}
topic.onCredsUpdated = this.tnCredsUpdated;
if (topic.onTagsUpdated != this.onTagsUpdated) {
if (topic.getType() == 'grp') {
this.previousTagsUpdated = topic.onTagsUpdated;
topic.onTagsUpdated = this.onTagsUpdated;
} else {
this.previousTagsUpdated = undefined;
}
}
if (this.state.topic != props.topic) {
this.setState({topic: props.topic});
}
}
componentWillUnmount() {
const topic = this.props.tinode.getTopic(this.props.topic);
topic.onCredsUpdated = undefined;
topic.onTagsUpdated = this.previousTagsUpdated;
}
tnCredsUpdated(creds) {
@@ -88,6 +111,20 @@ export default class TopicCommonView extends React.Component {
}
}
onTagsUpdated(tags) {
this.setState({tags: tags});
if (this.previousTagsUpdated && this.previousTagsUpdated != this.onTagsUpdated) {
this.previousTagsUpdated();
}
}
handleTagsUpdated(tags) {
if (!arrayEqual(this.state.tags.slice(0), tags.slice(0))) {
this.props.onTopicTagsUpdate(this.props.topic, tags);
}
}
render() {
const credentials = [];
if (this.state.isMe) {
@@ -140,6 +177,22 @@ export default class TopicCommonView extends React.Component {
</>
: null
}
{this.state.owner ?
<>
<div className="hr" />
<FormattedMessage id="title_tag_manager" defaultMessage="Tags (user discovery)"
description="Section title for TagManager">{
(tags) => <TagManager
title={tags}
tags={this.state.tags}
activated={false}
tinode={this.props.tinode}
onSubmit={this.handleTagsUpdated} />
}</FormattedMessage>
</>
:
null
}
</div>
);
}
+267
View File
@@ -0,0 +1,267 @@
// Edit account parameters.
import React from 'react';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import InPlaceEdit from '../widgets/in-place-edit.jsx';
import PermissionsEditor from '../widgets/permissions-editor.jsx';
const messages = defineMessages({
clear_messages: {
id: 'action_clear_messages',
defaultMessage: 'Clear Messages',
description: 'Flat button [Clear Messages] (soft-delete messages)'
},
clear_messages_warning: {
id: 'clear_messages_warning',
defaultMessage: 'Are you sure you want to clear all messages? It cannot be undone.',
description: 'Alert dialog warning when deleting all messages.'
},
delete_messages: {
id: 'action_delete_messages',
defaultMessage: 'Clear Messages for All',
description: 'Flat button [Clear for All] (hard-delete all messages)'
},
delete_messages_warning: {
id: 'delete_messages_warning',
defaultMessage: 'Are you sure you want to delete all messages for everyone? It cannot be undone.',
description: 'Alert dialog warning when hard-deleting all messages.'
},
leave_chat: {
id: 'action_leave_chat',
defaultMessage: 'Leave Conversation',
description: 'Flat button [Leave Conversation]'
},
leave_chat_warning: {
id: 'leave_chat_warning',
defaultMessage: 'Are you sure you want to leave this conversation?',
description: 'Alert dialog warning when unsubscribing from a chat.'
},
block_contact: {
id: 'action_block_contact',
defaultMessage: "Block Contact",
description: "Flat button [Block Contact]"
},
block_contact_warning: {
id: 'block_contact_warning',
defaultMessage: 'Are you sure you want to block this contact?',
description: 'Alert dialog warning when blocking a contact.'
},
report_chat: {
id: 'action_report_chat',
defaultMessage: 'Report Conversation',
description: 'Flat button [Report Group]'
},
report_chat_warning: {
id: 'report_chat_warning',
defaultMessage: 'Are you sure you want to block and report this conversation?',
description: 'Alert dialog warning when reporting a conversation for abuse'
},
other_user: {
id: 'label_other_user',
defaultMessage: 'Other',
description: 'Label for the other user when the user is unnamed'
},
});
class TopicSecurityView extends React.Component {
constructor(props) {
super(props);
const topic = this.props.tinode.getTopic(this.props.topic);
if (!topic) {
return;
}
const defacs = topic.getDefaultAccess() || {};
const acs = topic.getAccessMode();
this.state = {
owner: acs && acs.isOwner(),
admin: acs && acs.isAdmin(),
sharer: acs && acs.isSharer(),
deleter: acs && acs.isDeleter(),
muted: acs && acs.isMuted(),
auth: defacs ? defacs.auth : null,
anon: defacs ? defacs.anon : null,
showPermissionEditorFor: undefined
};
this.handleLaunchPermissionsEditor = this.handleLaunchPermissionsEditor.bind(this);
this.handleHidePermissionsEditor = this.handleHidePermissionsEditor.bind(this);
this.handlePermissionsChanged = this.handlePermissionsChanged.bind(this);
this.handleDeleteMessages = this.handleDeleteMessages.bind(this);
this.handleLeave = this.handleLeave.bind(this);
this.handleBlock = this.handleBlock.bind(this);
this.handleReport = this.handleReport.bind(this);
}
handleLaunchPermissionsEditor(which) {
this.setState({
showPermissionEditorFor: which,
editedPermissions: this.state[which]
});
}
handleHidePermissionsEditor() {
this.setState({showPermissionEditorFor: undefined});
}
handlePermissionsChanged(perm) {
let defacs = {};
defacs[this.state.showPermissionEditorFor] = perm;
this.props.onUpdateAccountDesc('me', undefined, undefined, defacs);
let newState = {showPermissionEditorFor: undefined};
newState[this.state.showPermissionEditorFor] = perm;
this.setState(newState);
}
handleDeleteMessages(e) {
e.preventDefault();
const {formatMessage} = this.props.intl;
this.props.onShowAlert(
formatMessage(this.state.deleter ? messages.delete_messages : messages.clear_messages), // title
formatMessage(this.state.deleter ? messages.delete_messages_warning : messages.clear_messages_warning), // content
(() => { this.props.onDeleteMessages(this.props.topic); }), // onConfirm
null, // "OK"
true, // Show Reject button
null // "Cancel"
);
}
handleLeave(e) {
e.preventDefault();
const {formatMessage} = this.props.intl;
this.props.onShowAlert(
formatMessage(messages.leave_chat), // title
formatMessage(messages.leave_chat_warning), // content
(() => { this.props.onLeaveTopic(this.props.topic); }), // onConfirm
null, // "OK"
true, // Show Reject button
null // "Cancel"
);
}
handleBlock(e) {
e.preventDefault();
const {formatMessage} = this.props.intl;
this.props.onShowAlert(
formatMessage(messages.block_contact), // title
formatMessage(messages.block_contact_warning), // content
(() => { this.props.onBlockTopic(this.props.topic); }), // onConfirm
null, // "OK"
true, // Show Reject button
null // "Cancel"
);
}
handleReport(e) {
e.preventDefault();
const {formatMessage} = this.props.intl;
this.props.onShowAlert(
formatMessage(messages.report_chat), // title
formatMessage(messages.report_chat_warning), // content
(() => { this.props.onReportTopic(this.props.topic); }), // onConfirm
null, // "OK"
true, // Show Reject button
null // "Cancel"
);
}
render() {
const {formatMessage} = this.props.intl;
return (
this.state.showPermissionEditorFor ?
<PermissionsEditor
mode={this.state.editedPermissions}
skip="O"
onSubmit={this.handlePermissionsChanged}
onCancel={this.handleHidePermissionsEditor} />
:
<div className="scrollable-panel">
<div className="panel-form-column">
{!this.state.channel ?
<a href="#" className="flat-button" onClick={this.handleDeleteMessages}>
<i className="material-icons">delete_outline</i> &nbsp;{
formatMessage(this.state.deleter ? messages.delete_messages : messages.clear_messages)
}
</a>
:
null
}
<a href="#" className="danger flat-button" onClick={this.handleLeave}>
<i className="material-icons">exit_to_app</i> &nbsp;{formatMessage(messages.leave_chat)}
</a>
{!this.state.groupTopic ?
<a href="#" className="danger flat-button" onClick={this.handleBlock}>
<i className="material-icons">block</i> &nbsp;{formatMessage(messages.block_contact)}
</a>
:
null
}
{!this.state.owner ?
<a href="#" className="danger flat-button" onClick={this.handleReport}>
<i className="material-icons">report</i> &nbsp;{formatMessage(messages.report_chat)}
</a>
:
null
}
</div>
<div className="hr" />
<div className="panel-form-column">
{this.state.groupTopic ?
<div className="group">
<label>
<FormattedMessage id="label_your_permissions" defaultMessage="Your permissions:"
description="Label for current user permissions" />
</label>
<tt className="clickable"
onClick={this.handleLaunchPermissionsEditor.bind(this, 'want')}>
{this.state.access}
</tt>
</div>
:
<div className="group">
<div>
<label className="small">
<FormattedMessage id="label_permissions" defaultMessage="Permissions:"
description="Section title" />
</label>
</div>
<div className="quoted">
<div>
<FormattedMessage id="label_you" defaultMessage="You:"
description="Label for the current user" /> &nbsp;<tt className="clickable"
onClick={this.handleLaunchPermissionsEditor.bind(this, 'want')}>
{this.state.access}
</tt></div>
<div>{this.state.fullName ? this.state.fullName : formatMessage(messages.other_user)}:
&nbsp;<tt className="clickable" onClick={this.handleLaunchPermissionsEditor.bind(this, 'given')}>
{this.state.modeGiven2}
</tt>
</div>
</div>
</div>
}
<div className="group">
<div>
<label className="small">
<FormattedMessage id="label_default_access_mode" defaultMessage="Default access mode:"
description="Label for default access mode" />
</label>
</div>
<div className="quoted">
<div>Auth: <tt className="clickable"
onClick={this.handleLaunchPermissionsEditor.bind(this, 'auth')}>{this.state.auth}</tt></div>
<div>Anon: <tt className="clickable"
onClick={this.handleLaunchPermissionsEditor.bind(this, 'anon')}>{this.state.anon}</tt></div>
</div>
</div>
</div>
</div>
);
}
};
export default injectIntl(TopicSecurityView);
+18 -18
View File
@@ -21,24 +21,24 @@ export default class SideNavbar extends React.PureComponent {
avatar = this.props.tinode.authorizeURL(sanitizeImageUrl(this.props.avatar));
}
return (
<div id="side-caption-panel" className="caption-panel">
{this.props.onCancel ? <ButtonBack onBack={this.props.onCancel} /> : null}
{avatar ?
<div id="self-avatar" className="avatar-box">
<LetterTile
avatar={avatar}
topic={this.props.myUserId}
title={this.props.title} />
</div>
:
null}
<div id="sidepanel-title" className="panel-title">{this.props.title}<ContactBadges badges={icon_badges}/></div>
{this.props.state === 'login' ?
<MenuStart onSignUp={this.props.onSignUp} onSettings={this.props.onSettings} /> :
this.props.state === 'contacts' ?
<MenuContacts onNewTopic={this.props.onNewTopic} onSettings={this.props.onSettings} /> :
null}
</div>
<div id="side-caption-panel" className="caption-panel">
{this.props.onCancel ? <ButtonBack onBack={this.props.onCancel} /> : null}
{avatar ?
<div id="self-avatar" className="avatar-box">
<LetterTile
avatar={avatar}
topic={this.props.myUserId}
title={this.props.title} />
</div>
:
null}
<div id="sidepanel-title" className="panel-title">{this.props.title}<ContactBadges badges={icon_badges}/></div>
{this.props.state === 'login' ?
<MenuStart onSignUp={this.props.onSignUp} onSettings={this.props.onSettings} /> :
this.props.state === 'contacts' ?
<MenuContacts onNewTopic={this.props.onNewTopic} onSettings={this.props.onSettings} /> :
null}
</div>
);
}
};
+212 -169
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
+6 -6
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