refactoring for better topic and account editing
This commit is contained in:
+32
-18
@@ -20,6 +20,7 @@ html, body {
|
|||||||
|
|
||||||
tt {
|
tt {
|
||||||
font-family: 'Roboto Mono', Courier, monospace;
|
font-family: 'Roboto Mono', Courier, monospace;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
@@ -422,8 +423,8 @@ div.trusted-badge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.float-right {
|
.float-right {
|
||||||
margin-left: auto;
|
position: absolute;
|
||||||
float: right;
|
right: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hr {
|
.hr {
|
||||||
@@ -440,6 +441,12 @@ div.trusted-badge {
|
|||||||
height: 0.015rem;
|
height: 0.015rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ellipsized {
|
||||||
|
overflow-x: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
|
||||||
/* Element which can take focus but shows no outline */
|
/* Element which can take focus but shows no outline */
|
||||||
.group-focus {
|
.group-focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
@@ -617,7 +624,7 @@ div.trusted-badge {
|
|||||||
display: block;
|
display: block;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
overflow: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
/* END of InPlaceEdit styles */
|
/* END of InPlaceEdit styles */
|
||||||
|
|
||||||
@@ -842,7 +849,7 @@ i.search {
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow: hidden;
|
overflow-x: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-column.narrow {
|
.flex-column.narrow {
|
||||||
@@ -1021,12 +1028,14 @@ i.search {
|
|||||||
/* Various forms inside a panel (signup form, new topic form) */
|
/* Various forms inside a panel (signup form, new topic form) */
|
||||||
.panel-form {
|
.panel-form {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
position: relative;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.panel-form-row {
|
.panel-form-row {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
position: relative;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.5rem 0.75rem;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
@@ -1036,6 +1045,7 @@ i.search {
|
|||||||
|
|
||||||
.panel-form-column {
|
.panel-form-column {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
position: relative;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-grow: 0;
|
flex-grow: 0;
|
||||||
padding: 0.5rem 0.75rem;
|
padding: 0.5rem 0.75rem;
|
||||||
@@ -1054,15 +1064,19 @@ i.search {
|
|||||||
padding: 0!important;
|
padding: 0!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.panel-form-column > .group {
|
||||||
|
margin-top: 0.25rem;
|
||||||
|
margin-bottom: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
/* Styling of avatar upload control */
|
/* Styling of avatar upload control */
|
||||||
.avatar-upload {
|
.avatar-upload {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 8rem;
|
width: 10rem;
|
||||||
height: 8.5rem;
|
height: 10.5rem;
|
||||||
margin-left: 0.5rem;
|
|
||||||
font-size: 4.5rem;
|
font-size: 4.5rem;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
@@ -1086,14 +1100,14 @@ i.search {
|
|||||||
|
|
||||||
.avatar-upload .avatar-box {
|
.avatar-upload .avatar-box {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 8rem;
|
width: 10rem;
|
||||||
height: 8rem;
|
height: 10rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-upload .avatar-box > .material-icons {
|
.avatar-upload .avatar-box > .material-icons {
|
||||||
position: relative;
|
position: relative;
|
||||||
font-size: 4rem;
|
font-size: 4rem;
|
||||||
line-height: 8rem;
|
line-height: 10rem;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1112,17 +1126,17 @@ i.search {
|
|||||||
border: 1px dashed #999;
|
border: 1px dashed #999;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 8rem;
|
width: 10rem;
|
||||||
height: 8rem;
|
height: 10rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
color: #999;
|
color: #999;
|
||||||
line-height: 8rem;
|
line-height: 10rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.avatar-upload img.preview {
|
.avatar-upload img.preview {
|
||||||
width: 8rem;
|
width: 10rem;
|
||||||
height: 8rem;
|
height: 10rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
@@ -1136,8 +1150,8 @@ i.search {
|
|||||||
color: #666;
|
color: #666;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
width: 8rem;
|
width: 10rem;
|
||||||
height: 8rem;
|
height: 10rem;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
background: center no-repeat url("../img/broken_image.png");
|
background: center no-repeat url("../img/broken_image.png");
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@@ -1654,7 +1668,7 @@ img.inline-image::before {
|
|||||||
|
|
||||||
img.image-preview::before {
|
img.image-preview::before {
|
||||||
content: " ";
|
content: " ";
|
||||||
background-size: 8rem 8rem;
|
background-size: 10rem 10rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attachment styles */
|
/* Attachment styles */
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+8
-1
@@ -39,7 +39,7 @@
|
|||||||
"defaultMessage": "More",
|
"defaultMessage": "More",
|
||||||
"description": "Action for showing more content",
|
"description": "Action for showing more content",
|
||||||
"missing": false,
|
"missing": false,
|
||||||
"obsolete": false
|
"obsolete": true
|
||||||
},
|
},
|
||||||
"action_report_chat": {
|
"action_report_chat": {
|
||||||
"translation": "Unterhaltung melden",
|
"translation": "Unterhaltung melden",
|
||||||
@@ -1284,5 +1284,12 @@
|
|||||||
"description": "Label for editing topic description",
|
"description": "Label for editing topic description",
|
||||||
"missing": true,
|
"missing": true,
|
||||||
"obsolete": false
|
"obsolete": false
|
||||||
|
},
|
||||||
|
"button_security": {
|
||||||
|
"translation": "Sicherheit",
|
||||||
|
"defaultMessage": "Security",
|
||||||
|
"description": "Navigaton button for security panel.",
|
||||||
|
"missing": true,
|
||||||
|
"obsolete": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -39,7 +39,7 @@
|
|||||||
"defaultMessage": "More",
|
"defaultMessage": "More",
|
||||||
"description": "Action for showing more content",
|
"description": "Action for showing more content",
|
||||||
"missing": false,
|
"missing": false,
|
||||||
"obsolete": false
|
"obsolete": true
|
||||||
},
|
},
|
||||||
"action_report_chat": {
|
"action_report_chat": {
|
||||||
"translation": "Report Conversation",
|
"translation": "Report Conversation",
|
||||||
@@ -1284,5 +1284,12 @@
|
|||||||
"description": "Label for editing topic description",
|
"description": "Label for editing topic description",
|
||||||
"missing": false,
|
"missing": false,
|
||||||
"obsolete": false
|
"obsolete": false
|
||||||
|
},
|
||||||
|
"button_security": {
|
||||||
|
"translation": "Security",
|
||||||
|
"defaultMessage": "Security",
|
||||||
|
"description": "Navigaton button for security panel.",
|
||||||
|
"missing": false,
|
||||||
|
"obsolete": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -39,7 +39,7 @@
|
|||||||
"defaultMessage": "More",
|
"defaultMessage": "More",
|
||||||
"description": "Action for showing more content",
|
"description": "Action for showing more content",
|
||||||
"missing": false,
|
"missing": false,
|
||||||
"obsolete": false
|
"obsolete": true
|
||||||
},
|
},
|
||||||
"action_report_chat": {
|
"action_report_chat": {
|
||||||
"translation": "Reportar conversación",
|
"translation": "Reportar conversación",
|
||||||
@@ -1284,5 +1284,12 @@
|
|||||||
"description": "Label for editing topic description",
|
"description": "Label for editing topic description",
|
||||||
"missing": true,
|
"missing": true,
|
||||||
"obsolete": false
|
"obsolete": false
|
||||||
|
},
|
||||||
|
"button_security": {
|
||||||
|
"translation": "",
|
||||||
|
"defaultMessage": "Security",
|
||||||
|
"description": "Navigaton button for security panel.",
|
||||||
|
"missing": true,
|
||||||
|
"obsolete": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,6 @@
|
|||||||
"defaultMessage": "Leave Conversation",
|
"defaultMessage": "Leave Conversation",
|
||||||
"description": "Flat button [Leave Conversation]"
|
"description": "Flat button [Leave Conversation]"
|
||||||
},
|
},
|
||||||
"action_more": {
|
|
||||||
"defaultMessage": "More",
|
|
||||||
"description": "Action for showing more content"
|
|
||||||
},
|
|
||||||
"action_report_chat": {
|
"action_report_chat": {
|
||||||
"defaultMessage": "Report Conversation",
|
"defaultMessage": "Report Conversation",
|
||||||
"description": "Flat button [Report Group]"
|
"description": "Flat button [Report Group]"
|
||||||
@@ -99,6 +95,10 @@
|
|||||||
"defaultMessage": "Reset",
|
"defaultMessage": "Reset",
|
||||||
"description": "Button [Reset]"
|
"description": "Button [Reset]"
|
||||||
},
|
},
|
||||||
|
"button_security": {
|
||||||
|
"defaultMessage": "Security",
|
||||||
|
"description": "Navigaton button for security panel."
|
||||||
|
},
|
||||||
"button_send_request": {
|
"button_send_request": {
|
||||||
"defaultMessage": "Send request",
|
"defaultMessage": "Send request",
|
||||||
"description": "Button [Send request]"
|
"description": "Button [Send request]"
|
||||||
|
|||||||
+8
-1
@@ -39,7 +39,7 @@
|
|||||||
"defaultMessage": "More",
|
"defaultMessage": "More",
|
||||||
"description": "Action for showing more content",
|
"description": "Action for showing more content",
|
||||||
"missing": false,
|
"missing": false,
|
||||||
"obsolete": false
|
"obsolete": true
|
||||||
},
|
},
|
||||||
"action_report_chat": {
|
"action_report_chat": {
|
||||||
"translation": "대화기록",
|
"translation": "대화기록",
|
||||||
@@ -1294,5 +1294,12 @@
|
|||||||
"description": "Label for editing topic description",
|
"description": "Label for editing topic description",
|
||||||
"missing": true,
|
"missing": true,
|
||||||
"obsolete": false
|
"obsolete": false
|
||||||
|
},
|
||||||
|
"button_security": {
|
||||||
|
"translation": "",
|
||||||
|
"defaultMessage": "Security",
|
||||||
|
"description": "Navigaton button for security panel.",
|
||||||
|
"missing": true,
|
||||||
|
"obsolete": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -39,7 +39,7 @@
|
|||||||
"defaultMessage": "More",
|
"defaultMessage": "More",
|
||||||
"description": "Action for showing more content",
|
"description": "Action for showing more content",
|
||||||
"missing": false,
|
"missing": false,
|
||||||
"obsolete": false
|
"obsolete": true
|
||||||
},
|
},
|
||||||
"action_report_chat": {
|
"action_report_chat": {
|
||||||
"translation": "Raportează conversația",
|
"translation": "Raportează conversația",
|
||||||
@@ -1284,5 +1284,12 @@
|
|||||||
"description": "Label for editing topic description",
|
"description": "Label for editing topic description",
|
||||||
"missing": true,
|
"missing": true,
|
||||||
"obsolete": false
|
"obsolete": false
|
||||||
|
},
|
||||||
|
"button_security": {
|
||||||
|
"translation": "",
|
||||||
|
"defaultMessage": "Security",
|
||||||
|
"description": "Navigaton button for security panel.",
|
||||||
|
"missing": true,
|
||||||
|
"obsolete": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -39,7 +39,7 @@
|
|||||||
"defaultMessage": "More",
|
"defaultMessage": "More",
|
||||||
"description": "Action for showing more content",
|
"description": "Action for showing more content",
|
||||||
"missing": false,
|
"missing": false,
|
||||||
"obsolete": false
|
"obsolete": true
|
||||||
},
|
},
|
||||||
"action_report_chat": {
|
"action_report_chat": {
|
||||||
"translation": "Сообщить о нарушении",
|
"translation": "Сообщить о нарушении",
|
||||||
@@ -1284,5 +1284,12 @@
|
|||||||
"description": "Label for editing topic description",
|
"description": "Label for editing topic description",
|
||||||
"missing": true,
|
"missing": true,
|
||||||
"obsolete": false
|
"obsolete": false
|
||||||
|
},
|
||||||
|
"button_security": {
|
||||||
|
"translation": "",
|
||||||
|
"defaultMessage": "Security",
|
||||||
|
"description": "Navigaton button for security panel.",
|
||||||
|
"missing": true,
|
||||||
|
"obsolete": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -39,7 +39,7 @@
|
|||||||
"defaultMessage": "More",
|
"defaultMessage": "More",
|
||||||
"description": "Action for showing more content",
|
"description": "Action for showing more content",
|
||||||
"missing": false,
|
"missing": false,
|
||||||
"obsolete": false
|
"obsolete": true
|
||||||
},
|
},
|
||||||
"action_report_chat": {
|
"action_report_chat": {
|
||||||
"translation": "檢舉對話",
|
"translation": "檢舉對話",
|
||||||
@@ -1283,5 +1283,12 @@
|
|||||||
"description": "Label for editing topic description",
|
"description": "Label for editing topic description",
|
||||||
"missing": true,
|
"missing": true,
|
||||||
"obsolete": false
|
"obsolete": false
|
||||||
|
},
|
||||||
|
"button_security": {
|
||||||
|
"translation": "",
|
||||||
|
"defaultMessage": "Security",
|
||||||
|
"description": "Navigaton button for security panel.",
|
||||||
|
"missing": true,
|
||||||
|
"obsolete": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -39,7 +39,7 @@
|
|||||||
"defaultMessage": "More",
|
"defaultMessage": "More",
|
||||||
"description": "Action for showing more content",
|
"description": "Action for showing more content",
|
||||||
"missing": false,
|
"missing": false,
|
||||||
"obsolete": false
|
"obsolete": true
|
||||||
},
|
},
|
||||||
"action_report_chat": {
|
"action_report_chat": {
|
||||||
"translation": "检举垃圾邮件",
|
"translation": "检举垃圾邮件",
|
||||||
@@ -1284,5 +1284,12 @@
|
|||||||
"description": "Label for editing topic description",
|
"description": "Label for editing topic description",
|
||||||
"missing": true,
|
"missing": true,
|
||||||
"obsolete": false
|
"obsolete": false
|
||||||
|
},
|
||||||
|
"button_security": {
|
||||||
|
"translation": "",
|
||||||
|
"defaultMessage": "Security",
|
||||||
|
"description": "Navigaton button for security panel.",
|
||||||
|
"missing": true,
|
||||||
|
"obsolete": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export default class HashNavigation {
|
|||||||
}
|
}
|
||||||
if (parts[1]) {
|
if (parts[1]) {
|
||||||
parts[1].split('&').forEach(function(part) {
|
parts[1].split('&').forEach(function(part) {
|
||||||
let item = part.split('=');
|
const item = part.split('=');
|
||||||
if (item[0]) {
|
if (item[0]) {
|
||||||
params[decodeURIComponent(item[0])] = decodeURIComponent(item[1]);
|
params[decodeURIComponent(item[0])] = decodeURIComponent(item[1]);
|
||||||
}
|
}
|
||||||
@@ -58,6 +58,12 @@ export default class HashNavigation {
|
|||||||
return this.composeUrlHash(parsed.path, parsed.params);
|
return this.composeUrlHash(parsed.path, parsed.params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static setUrlInfoPanel(hash, infopanel) {
|
||||||
|
const parsed = this.parseUrlHash(hash);
|
||||||
|
parsed.params.info = infopanel;
|
||||||
|
return this.composeUrlHash(parsed.path, parsed.params);
|
||||||
|
}
|
||||||
|
|
||||||
static setUrlTopic(hash, topic) {
|
static setUrlTopic(hash, topic) {
|
||||||
const parsed = this.parseUrlHash(hash);
|
const parsed = this.parseUrlHash(hash);
|
||||||
parsed.path[1] = topic;
|
parsed.path[1] = topic;
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -6,6 +6,11 @@ import AvatarUpload from '../widgets/avatar-upload.jsx';
|
|||||||
import BadgeList from '../widgets/badge-list.jsx';
|
import BadgeList from '../widgets/badge-list.jsx';
|
||||||
|
|
||||||
import { makeImageUrl } from '../lib/blob-helpers.js';
|
import { makeImageUrl } from '../lib/blob-helpers.js';
|
||||||
|
import { MAX_TITLE_LENGTH, MAX_TOPIC_DESCRIPTION_LENGTH } from '../config.js';
|
||||||
|
|
||||||
|
function _clip(str, length) {
|
||||||
|
return str && str.substring(0, length);
|
||||||
|
}
|
||||||
|
|
||||||
export default class AccountSettingsView extends React.Component {
|
export default class AccountSettingsView extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -13,7 +18,8 @@ export default class AccountSettingsView extends React.Component {
|
|||||||
|
|
||||||
const me = this.props.tinode.getMeTopic();
|
const me = this.props.tinode.getMeTopic();
|
||||||
this.state = {
|
this.state = {
|
||||||
fullName: me.public ? me.public.fn : undefined,
|
fullName: _clip(me.public ? me.public.fn : undefined, MAX_TITLE_LENGTH),
|
||||||
|
description: _clip(me.public ? me.public.note : undefined, MAX_TOPIC_DESCRIPTION_LENGTH),
|
||||||
avatar: makeImageUrl(me.public ? me.public.photo : null)
|
avatar: makeImageUrl(me.public ? me.public.photo : null)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -21,44 +27,54 @@ export default class AccountSettingsView extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="scrollable-panel">
|
<div className="scrollable-panel">
|
||||||
<div className="panel-form-row">
|
<div className="panel-form-column">
|
||||||
<div className="panel-form-column">
|
<a href="#" className="flat-button float-right" onClick={(e) => {e.preventDefault(); this.props.onNavigate('general');}}>
|
||||||
|
<i className="material-icons">edit</i>
|
||||||
|
<FormattedMessage id="button_edit" defaultMessage="Edit" description="Call to action [Edit]" />
|
||||||
|
</a>
|
||||||
|
<center>
|
||||||
|
<AvatarUpload
|
||||||
|
tinode={this.props.tinode}
|
||||||
|
avatar={this.state.avatar}
|
||||||
|
readOnly={true}
|
||||||
|
uid={this.props.myUserId}
|
||||||
|
title={this.state.fullName} />
|
||||||
|
</center>
|
||||||
|
<div className="group">
|
||||||
<label className="small">
|
<label className="small">
|
||||||
<FormattedMessage id="label_your_name" defaultMessage="Your name"
|
<FormattedMessage id="label_your_name" defaultMessage="Your name"
|
||||||
description="Label for full name editing" />
|
description="Label for full name editing" />
|
||||||
</label>
|
</label>
|
||||||
<div className="large">{this.state.fullName}</div>
|
<div className="large ellipsized">{this.state.fullName}</div>
|
||||||
<div>
|
</div>
|
||||||
<label className="small"><FormattedMessage id="label_user_id" defaultMessage="ID:"
|
<div className="group">
|
||||||
description="Label for user address (ID)" /></label>
|
<label className="small"><FormattedMessage id="label_user_id" defaultMessage="ID:"
|
||||||
<tt style={{whiteSpace: 'nowrap'}}>{this.props.myUserId}</tt>
|
description="Label for user address (ID)" /></label>
|
||||||
</div>
|
<tt>{this.props.myUserId}</tt>
|
||||||
|
</div>
|
||||||
|
<div className="group">
|
||||||
<BadgeList trustedBadges={this.props.trustedBadges} />
|
<BadgeList trustedBadges={this.props.trustedBadges} />
|
||||||
</div>
|
</div>
|
||||||
<AvatarUpload
|
{this.state.description ?
|
||||||
tinode={this.props.tinode}
|
<div className="group">
|
||||||
avatar={this.state.avatar}
|
<label className="small">
|
||||||
readOnly={true}
|
<FormattedMessage id="label_description" defaultMessage="Description"
|
||||||
uid={this.props.myUserId}
|
description="Label for editing topic description" />
|
||||||
title={this.state.fullName} />
|
</label>
|
||||||
</div>
|
<div>{this.state.description}</div>
|
||||||
<div className="panel-form-row">
|
</div> : null}
|
||||||
<a href="#" className="flat-button" onClick={(e) => {e.preventDefault(); this.props.onBasicNavigate('general');}}>
|
|
||||||
<i className="material-icons">edit</i>
|
|
||||||
<FormattedMessage id="button_edit" defaultMessage="Edit" description="Call to action [Edit]" />
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="hr" />
|
<div className="hr" />
|
||||||
<div className="panel-form-column">
|
<div className="panel-form-column">
|
||||||
<a href="#" className="flat-button" onClick={(e) => {e.preventDefault(); this.props.onBasicNavigate('notif');}}>
|
<a href="#" className="flat-button" onClick={(e) => {e.preventDefault(); this.props.onNavigate('notif');}}>
|
||||||
<i className="material-icons">notifications</i> <FormattedMessage id="sidepanel_title_acc_notifications"
|
<i className="material-icons">notifications</i> <FormattedMessage id="sidepanel_title_acc_notifications"
|
||||||
defaultMessage="Notifications" description="Sidepanel title for AccNotificationsView." />
|
defaultMessage="Notifications" description="Sidepanel title for AccNotificationsView." />
|
||||||
</a>
|
</a>
|
||||||
<a href="#" className="flat-button" onClick={(e) => {e.preventDefault(); this.props.onBasicNavigate('security');}}>
|
<a href="#" className="flat-button" onClick={(e) => {e.preventDefault(); this.props.onNavigate('security');}}>
|
||||||
<i className="material-icons">security</i> <FormattedMessage id="sidepanel_title_acc_security"
|
<i className="material-icons">security</i> <FormattedMessage id="button_security"
|
||||||
defaultMessage="Security" description="Sidepanel title for AccSecurityView." />
|
defaultMessage="Security" description="Navigaton button for security panel." />
|
||||||
</a>
|
</a>
|
||||||
<a href="#" className="flat-button" onClick={(e) => {e.preventDefault(); this.props.onBasicNavigate('support');}}>
|
<a href="#" className="flat-button" onClick={(e) => {e.preventDefault(); this.props.onNavigate('support');}}>
|
||||||
<i className="material-icons">contact_support</i> <FormattedMessage id="sidepanel_title_acc_support"
|
<i className="material-icons">contact_support</i> <FormattedMessage id="sidepanel_title_acc_support"
|
||||||
defaultMessage="Support" description="Sidepanel title for AccSupportView." />
|
defaultMessage="Support" description="Sidepanel title for AccSupportView." />
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
+58
-181
@@ -4,6 +4,8 @@ import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
|||||||
|
|
||||||
import Tinode from 'tinode-sdk';
|
import Tinode from 'tinode-sdk';
|
||||||
|
|
||||||
|
import TopicSecurityView from './topic-security-view.jsx';
|
||||||
|
|
||||||
import AvatarUpload from '../widgets/avatar-upload.jsx';
|
import AvatarUpload from '../widgets/avatar-upload.jsx';
|
||||||
import BadgeList from '../widgets/badge-list.jsx';
|
import BadgeList from '../widgets/badge-list.jsx';
|
||||||
import CheckBox from '../widgets/checkbox.jsx';
|
import CheckBox from '../widgets/checkbox.jsx';
|
||||||
@@ -16,7 +18,7 @@ import MoreButton from '../widgets/more-button.jsx';
|
|||||||
import PermissionsEditor from '../widgets/permissions-editor.jsx';
|
import PermissionsEditor from '../widgets/permissions-editor.jsx';
|
||||||
import TagManager from '../widgets/tag-manager.jsx';
|
import TagManager from '../widgets/tag-manager.jsx';
|
||||||
|
|
||||||
import { MAX_TITLE_LENGTH, NO_ACCESS_MODE } from '../config.js';
|
import { MAX_TITLE_LENGTH, MAX_TOPIC_DESCRIPTION_LENGTH, NO_ACCESS_MODE } from '../config.js';
|
||||||
|
|
||||||
import { makeImageUrl } from '../lib/blob-helpers.js';
|
import { makeImageUrl } from '../lib/blob-helpers.js';
|
||||||
import { arrayEqual, theCard } from '../lib/utils.js';
|
import { arrayEqual, theCard } from '../lib/utils.js';
|
||||||
@@ -42,58 +44,12 @@ const messages = defineMessages({
|
|||||||
defaultMessage: 'Other',
|
defaultMessage: 'Other',
|
||||||
description: 'Label for the other user when the user is unnamed'
|
description: 'Label for the other user when the user is unnamed'
|
||||||
},
|
},
|
||||||
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'
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function _clip(str, length) {
|
||||||
|
return str && str.substring(0, length);
|
||||||
|
}
|
||||||
|
|
||||||
class InfoView extends React.Component {
|
class InfoView extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
@@ -109,6 +65,7 @@ class InfoView extends React.Component {
|
|||||||
groupTopic: undefined,
|
groupTopic: undefined,
|
||||||
channel: undefined,
|
channel: undefined,
|
||||||
fullName: undefined,
|
fullName: undefined,
|
||||||
|
description: undefined,
|
||||||
avatar: null,
|
avatar: null,
|
||||||
private: null,
|
private: null,
|
||||||
selectedContact: null,
|
selectedContact: null,
|
||||||
@@ -124,7 +81,6 @@ class InfoView extends React.Component {
|
|||||||
trustedBadges: [],
|
trustedBadges: [],
|
||||||
showMemberPanel: false,
|
showMemberPanel: false,
|
||||||
showPermissionEditorFor: undefined,
|
showPermissionEditorFor: undefined,
|
||||||
moreInfoExpanded: false,
|
|
||||||
previousMetaDesc: undefined,
|
previousMetaDesc: undefined,
|
||||||
previousSubsUpdated: undefined,
|
previousSubsUpdated: undefined,
|
||||||
previousTagsUpdated: undefined
|
previousTagsUpdated: undefined
|
||||||
@@ -145,12 +101,7 @@ class InfoView extends React.Component {
|
|||||||
this.handleShowAddMembers = this.handleShowAddMembers.bind(this);
|
this.handleShowAddMembers = this.handleShowAddMembers.bind(this);
|
||||||
this.handleHideAddMembers = this.handleHideAddMembers.bind(this);
|
this.handleHideAddMembers = this.handleHideAddMembers.bind(this);
|
||||||
this.handleMemberUpdateRequest = this.handleMemberUpdateRequest.bind(this);
|
this.handleMemberUpdateRequest = this.handleMemberUpdateRequest.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);
|
|
||||||
this.handleMemberSelected = this.handleMemberSelected.bind(this);
|
this.handleMemberSelected = this.handleMemberSelected.bind(this);
|
||||||
this.handleMoreInfo = this.handleMoreInfo.bind(this);
|
|
||||||
this.handleTagsUpdated = this.handleTagsUpdated.bind(this);
|
this.handleTagsUpdated = this.handleTagsUpdated.bind(this);
|
||||||
this.handleContextMenu = this.handleContextMenu.bind(this);
|
this.handleContextMenu = this.handleContextMenu.bind(this);
|
||||||
}
|
}
|
||||||
@@ -236,10 +187,11 @@ class InfoView extends React.Component {
|
|||||||
deleter: acs && acs.isDeleter(),
|
deleter: acs && acs.isDeleter(),
|
||||||
muted: acs && acs.isMuted(),
|
muted: acs && acs.isMuted(),
|
||||||
|
|
||||||
fullName: topic.public ? topic.public.fn : undefined,
|
fullName: _clip(topic.public ? topic.public.fn : undefined, MAX_TITLE_LENGTH),
|
||||||
|
description: _clip(topic.public ? topic.public.note : undefined, MAX_TOPIC_DESCRIPTION_LENGTH),
|
||||||
avatar: makeImageUrl(topic.public ? topic.public.photo : null),
|
avatar: makeImageUrl(topic.public ? topic.public.photo : null),
|
||||||
trustedBadges: badges,
|
trustedBadges: badges,
|
||||||
private: topic.private ? topic.private.comment : null,
|
private: _clip(topic.private ? topic.private.comment : null, MAX_TITLE_LENGTH),
|
||||||
address: topic.name,
|
address: topic.name,
|
||||||
groupTopic: topic.isGroupType(),
|
groupTopic: topic.isGroupType(),
|
||||||
channel: topic.isChannelType(),
|
channel: topic.isChannelType(),
|
||||||
@@ -433,66 +385,10 @@ class InfoView extends React.Component {
|
|||||||
this.setState({showMemberPanel: false});
|
this.setState({showMemberPanel: false});
|
||||||
}
|
}
|
||||||
|
|
||||||
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"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
handleMemberSelected(uid) {
|
handleMemberSelected(uid) {
|
||||||
this.setState({selectedContact: uid});
|
this.setState({selectedContact: uid});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMoreInfo(open) {
|
|
||||||
this.setState({moreInfoExpanded: open});
|
|
||||||
}
|
|
||||||
|
|
||||||
handleTagsUpdated(tags) {
|
handleTagsUpdated(tags) {
|
||||||
if (!arrayEqual(this.state.tags.slice(0), tags.slice(0))) {
|
if (!arrayEqual(this.state.tags.slice(0), tags.slice(0))) {
|
||||||
this.props.onTopicTagsUpdate(this.props.topic, tags);
|
this.props.onTopicTagsUpdate(this.props.topic, tags);
|
||||||
@@ -569,42 +465,52 @@ class InfoView extends React.Component {
|
|||||||
/>
|
/>
|
||||||
:
|
:
|
||||||
<div id="info-view-content" className="scrollable-panel">
|
<div id="info-view-content" className="scrollable-panel">
|
||||||
<div className="panel-form-row">
|
<div className="panel-form-column">
|
||||||
<div className="panel-form-column">
|
<a href="#" className="flat-button float-right" onClick={(e) => {e.preventDefault(); this.props.onNavigate('general');}}>
|
||||||
|
<i className="material-icons">edit</i>
|
||||||
|
<FormattedMessage id="button_edit" defaultMessage="Edit" description="Call to action [Edit]" />
|
||||||
|
</a>
|
||||||
|
<center>
|
||||||
|
<AvatarUpload
|
||||||
|
tinode={this.props.tinode}
|
||||||
|
avatar={this.state.avatar}
|
||||||
|
readOnly={true}
|
||||||
|
uid={this.props.topic}
|
||||||
|
title={this.state.fullName} />
|
||||||
|
</center>
|
||||||
|
<div className="group">
|
||||||
<div><label className="small">
|
<div><label className="small">
|
||||||
<FormattedMessage id="label_topic_name" defaultMessage="Name"
|
<FormattedMessage id="label_topic_name" defaultMessage="Name"
|
||||||
description="Label for editing topic name" />
|
description="Label for editing topic name" />
|
||||||
</label></div>
|
</label></div>
|
||||||
<div className="large">{this.state.fullName}</div>
|
<div className="large ellipsized">{this.state.fullName}</div>
|
||||||
{this.state.private ?
|
</div>
|
||||||
<>
|
{this.state.private ?
|
||||||
<div><label className="small">
|
<div className="group">
|
||||||
<FormattedMessage id="label_private" defaultMessage="Private comment"
|
<div><label className="small">
|
||||||
description="Label for editing 'private'" />
|
<FormattedMessage id="label_private" defaultMessage="Private comment"
|
||||||
</label></div>
|
description="Label for editing 'private'" />
|
||||||
<div className="large">{this.state.private}</div>
|
</label></div>
|
||||||
</>
|
<div className="large ellipsized">{this.state.private}</div>
|
||||||
: null
|
|
||||||
}
|
|
||||||
<div>
|
|
||||||
<label className="small"><FormattedMessage id="label_user_id" defaultMessage="ID:"
|
|
||||||
description="Label for user address (ID)" /></label>
|
|
||||||
<tt>{this.props.myUserId}</tt>
|
|
||||||
</div>
|
</div>
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
<div className="group">
|
||||||
|
<label className="small"><FormattedMessage id="label_user_id" defaultMessage="ID:"
|
||||||
|
description="Label for user address (ID)" /></label>
|
||||||
|
<tt>{this.state.address}</tt>
|
||||||
|
</div>
|
||||||
|
<div className="group">
|
||||||
<BadgeList trustedBadges={this.state.trustedBadges} />
|
<BadgeList trustedBadges={this.state.trustedBadges} />
|
||||||
</div>
|
</div>
|
||||||
<AvatarUpload
|
{this.state.description ?
|
||||||
tinode={this.props.tinode}
|
<div className="group">
|
||||||
avatar={this.state.avatar}
|
<label className="small">
|
||||||
readOnly={true}
|
<FormattedMessage id="label_description" defaultMessage="Description"
|
||||||
uid={this.props.topic}
|
description="Label for editing topic description" />
|
||||||
title={this.state.fullName} />
|
</label>
|
||||||
</div>
|
<div>{this.state.description}</div>
|
||||||
<div className="panel-form-row">
|
</div> : null}
|
||||||
<a href="#" className="flat-button" onClick={(e) => {e.preventDefault(); this.props.onBasicNavigate('general');}}>
|
|
||||||
<i className="material-icons">edit</i>
|
|
||||||
<FormattedMessage id="button_edit" defaultMessage="Edit" description="Call to action [Edit]" />
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="hr" />
|
<div className="hr" />
|
||||||
<div className="panel-form-column">
|
<div className="panel-form-column">
|
||||||
@@ -613,16 +519,15 @@ class InfoView extends React.Component {
|
|||||||
<FormattedMessage id="label_muting_topic" defaultMessage="Muted:"
|
<FormattedMessage id="label_muting_topic" defaultMessage="Muted:"
|
||||||
description="Label for Muting/unmuting the topic" />
|
description="Label for Muting/unmuting the topic" />
|
||||||
</label>
|
</label>
|
||||||
<CheckBox name="P" checked={this.state.muted}
|
<CheckBox name="P" checked={this.state.muted} onChange={this.handleMuted} />
|
||||||
onChange={this.handleMuted} />
|
|
||||||
</div>
|
</div>
|
||||||
<FormattedMessage id="action_more" defaultMessage="More"
|
</div>
|
||||||
description="Action for showing more content">{
|
<div className="hr" />
|
||||||
(more) => <MoreButton
|
<div className="panel-form-column">
|
||||||
title={more}
|
<a href="#" className="flat-button" onClick={(e) => {e.preventDefault(); this.props.onNavigate('security');}}>
|
||||||
open={this.state.moreInfoExpanded}
|
<i className="material-icons">security</i> <FormattedMessage id="button_security"
|
||||||
onToggle={this.handleMoreInfo} />
|
defaultMessage="Security" description="Navigaton button for security panel." />
|
||||||
}</FormattedMessage>
|
</a>
|
||||||
{this.state.moreInfoExpanded ?
|
{this.state.moreInfoExpanded ?
|
||||||
<div className="panel-form-column">
|
<div className="panel-form-column">
|
||||||
{this.state.groupTopic ?
|
{this.state.groupTopic ?
|
||||||
@@ -713,34 +618,6 @@ class InfoView extends React.Component {
|
|||||||
:
|
:
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
<div className="panel-form-column">
|
|
||||||
{!this.state.channel ?
|
|
||||||
<a href="#" className="flat-button" onClick={this.handleDeleteMessages}>
|
|
||||||
<i className="material-icons">delete_outline</i> {
|
|
||||||
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> {formatMessage(messages.leave_chat)}
|
|
||||||
</a>
|
|
||||||
{!this.state.groupTopic ?
|
|
||||||
<a href="#" className="danger flat-button" onClick={this.handleBlock}>
|
|
||||||
<i className="material-icons">block</i> {formatMessage(messages.block_contact)}
|
|
||||||
</a>
|
|
||||||
:
|
|
||||||
null
|
|
||||||
}
|
|
||||||
{!this.state.owner ?
|
|
||||||
<a href="#" className="danger flat-button" onClick={this.handleReport}>
|
|
||||||
<i className="material-icons">report</i> {formatMessage(messages.report_chat)}
|
|
||||||
</a>
|
|
||||||
:
|
|
||||||
null
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
{this.state.groupTopic && this.state.sharer ?
|
{this.state.groupTopic && this.state.sharer ?
|
||||||
<>
|
<>
|
||||||
<div className="hr" />
|
<div className="hr" />
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ class SidepanelView extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleNewTopic() {
|
handleNewTopic() {
|
||||||
this.props.onBasicNavigate('newtpk');
|
this.props.onNavigate('newtpk');
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
@@ -173,14 +173,13 @@ class SidepanelView extends React.Component {
|
|||||||
tinode={this.props.tinode}
|
tinode={this.props.tinode}
|
||||||
myUserId={this.props.myUserId}
|
myUserId={this.props.myUserId}
|
||||||
trustedBadges={this.props.trustedBadges}
|
trustedBadges={this.props.trustedBadges}
|
||||||
onBasicNavigate={this.props.onBasicNavigate} /> :
|
onNavigate={this.props.onNavigate} /> :
|
||||||
|
|
||||||
(view === 'general' || view === 'crop') ?
|
(view === 'general' || view === 'crop') ?
|
||||||
<TopicCommonView
|
<TopicCommonView
|
||||||
topic="me"
|
topic="me"
|
||||||
tinode={this.props.tinode}
|
tinode={this.props.tinode}
|
||||||
myUserId={this.props.myUserId}
|
myUserId={this.props.myUserId}
|
||||||
onBasicNavigate={this.props.onBasicNavigate}
|
|
||||||
onUpdateTopicDesc={this.props.onUpdateAccountDesc}
|
onUpdateTopicDesc={this.props.onUpdateAccountDesc}
|
||||||
onUpdateTags={this.props.onUpdateAccountTags}
|
onUpdateTags={this.props.onUpdateAccountTags}
|
||||||
onCredAdd={this.props.onCredAdd}
|
onCredAdd={this.props.onCredAdd}
|
||||||
|
|||||||
+18
-11
@@ -187,7 +187,7 @@ class TinodeWeb extends React.Component {
|
|||||||
newTopicParams: null,
|
newTopicParams: null,
|
||||||
loginDisabled: false,
|
loginDisabled: false,
|
||||||
displayMobile: (window.innerWidth <= MEDIA_BREAKPOINT),
|
displayMobile: (window.innerWidth <= MEDIA_BREAKPOINT),
|
||||||
showInfoPanel: false,
|
infoPanel: undefined,
|
||||||
mobilePanel: 'sidepanel',
|
mobilePanel: 'sidepanel',
|
||||||
|
|
||||||
contextMenuVisible: false,
|
contextMenuVisible: false,
|
||||||
@@ -425,7 +425,7 @@ class TinodeWeb extends React.Component {
|
|||||||
|
|
||||||
// Additional parameters of panels.
|
// Additional parameters of panels.
|
||||||
this.setState({
|
this.setState({
|
||||||
showInfoPanel: hash.params.info,
|
infoPanel: hash.params.info,
|
||||||
newTopicTabSelected: hash.params.tab
|
newTopicTabSelected: hash.params.tab
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -862,7 +862,7 @@ class TinodeWeb extends React.Component {
|
|||||||
errorText: '',
|
errorText: '',
|
||||||
errorLevel: null,
|
errorLevel: null,
|
||||||
mobilePanel: 'topic-view',
|
mobilePanel: 'topic-view',
|
||||||
showInfoPanel: false
|
infoPanel: undefined
|
||||||
});
|
});
|
||||||
// Different contact selected.
|
// Different contact selected.
|
||||||
if (this.state.topicSelected != topicName) {
|
if (this.state.topicSelected != topicName) {
|
||||||
@@ -880,7 +880,7 @@ class TinodeWeb extends React.Component {
|
|||||||
mobilePanel: 'sidepanel',
|
mobilePanel: 'sidepanel',
|
||||||
topicSelectedOnline: false,
|
topicSelectedOnline: false,
|
||||||
topicSelectedAcs: null,
|
topicSelectedAcs: null,
|
||||||
showInfoPanel: false
|
infoPanel: undefined
|
||||||
});
|
});
|
||||||
|
|
||||||
HashNavigation.navigateTo(HashNavigation.setUrlTopic('', null));
|
HashNavigation.navigateTo(HashNavigation.setUrlTopic('', null));
|
||||||
@@ -1164,11 +1164,16 @@ class TinodeWeb extends React.Component {
|
|||||||
this.setState({errorText: '', errorLevel: null});
|
this.setState({errorText: '', errorLevel: null});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basic nagigator by hash value. No need to bind to this.
|
// Sidepanel navigator. No need to bind to 'this'.
|
||||||
basicNavigator(hash) {
|
basicNavigator(hash) {
|
||||||
HashNavigation.navigateTo(HashNavigation.setUrlSidePanel(window.location.hash, hash));
|
HashNavigation.navigateTo(HashNavigation.setUrlSidePanel(window.location.hash, hash));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Topic info navigator. No need to bind to 'this'.
|
||||||
|
infoNavigator(hash) {
|
||||||
|
HashNavigation.navigateTo(HashNavigation.setUrlInfoPanel(window.location.hash, hash));
|
||||||
|
}
|
||||||
|
|
||||||
// Request to start a topic, new or selected from search results, or "by ID".
|
// Request to start a topic, new or selected from search results, or "by ID".
|
||||||
handleStartTopicRequest(topicName, pub, priv, tags, isChannel) {
|
handleStartTopicRequest(topicName, pub, priv, tags, isChannel) {
|
||||||
// Check if topic is indeed new. If not, launch it.
|
// Check if topic is indeed new. If not, launch it.
|
||||||
@@ -1435,13 +1440,13 @@ class TinodeWeb extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleShowInfoView() {
|
handleShowInfoView() {
|
||||||
HashNavigation.navigateTo(HashNavigation.addUrlParam(window.location.hash, 'info', true));
|
HashNavigation.navigateTo(HashNavigation.addUrlParam(window.location.hash, 'info', 'info'));
|
||||||
this.setState({showInfoPanel: true});
|
this.setState({infoPanel: 'info'});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleHideInfoView() {
|
handleHideInfoView() {
|
||||||
HashNavigation.navigateTo(HashNavigation.removeUrlParam(window.location.hash, 'info'));
|
HashNavigation.navigateTo(HashNavigation.removeUrlParam(window.location.hash, 'info'));
|
||||||
this.setState({showInfoPanel: false});
|
this.setState({infoPanel: undefined});
|
||||||
}
|
}
|
||||||
|
|
||||||
handleMemberUpdateRequest(topicName, added, removed) {
|
handleMemberUpdateRequest(topicName, added, removed) {
|
||||||
@@ -1582,7 +1587,7 @@ class TinodeWeb extends React.Component {
|
|||||||
onGlobalSettings={this.handleGlobalSettings}
|
onGlobalSettings={this.handleGlobalSettings}
|
||||||
onSignUp={this.handleNewAccount}
|
onSignUp={this.handleNewAccount}
|
||||||
onSettings={this.handleSettings}
|
onSettings={this.handleSettings}
|
||||||
onBasicNavigate={this.basicNavigator}
|
onNavigate={this.basicNavigator}
|
||||||
onLoginRequest={this.handleLoginRequest}
|
onLoginRequest={this.handleLoginRequest}
|
||||||
onPersistenceChange={this.handlePersistenceChange}
|
onPersistenceChange={this.handlePersistenceChange}
|
||||||
onCreateAccount={this.handleNewAccountRequest}
|
onCreateAccount={this.handleNewAccountRequest}
|
||||||
@@ -1624,7 +1629,7 @@ class TinodeWeb extends React.Component {
|
|||||||
viewportWidth={this.state.viewportWidth}
|
viewportWidth={this.state.viewportWidth}
|
||||||
viewportHeight={this.state.viewportHeight}
|
viewportHeight={this.state.viewportHeight}
|
||||||
hideSelf={this.state.displayMobile &&
|
hideSelf={this.state.displayMobile &&
|
||||||
(this.state.mobilePanel !== 'topic-view' || this.state.showInfoPanel)}
|
(this.state.mobilePanel !== 'topic-view' || this.state.infoPanel)}
|
||||||
topic={this.state.topicSelected}
|
topic={this.state.topicSelected}
|
||||||
myUserId={this.state.myUserId}
|
myUserId={this.state.myUserId}
|
||||||
serverVersion={this.state.serverVersion}
|
serverVersion={this.state.serverVersion}
|
||||||
@@ -1647,7 +1652,7 @@ class TinodeWeb extends React.Component {
|
|||||||
onNewChat={this.handleNewChatInvitation}
|
onNewChat={this.handleNewChatInvitation}
|
||||||
sendMessage={this.handleSendMessage} />
|
sendMessage={this.handleSendMessage} />
|
||||||
|
|
||||||
{this.state.showInfoPanel ?
|
{this.state.infoPanel ?
|
||||||
<InfoView
|
<InfoView
|
||||||
tinode={this.tinode}
|
tinode={this.tinode}
|
||||||
connected={this.state.connected}
|
connected={this.state.connected}
|
||||||
@@ -1655,12 +1660,14 @@ class TinodeWeb extends React.Component {
|
|||||||
topic={this.state.topicSelected}
|
topic={this.state.topicSelected}
|
||||||
searchableContacts={this.state.searchableContacts}
|
searchableContacts={this.state.searchableContacts}
|
||||||
myUserId={this.state.myUserId}
|
myUserId={this.state.myUserId}
|
||||||
|
panel={this.state.infoPanel}
|
||||||
|
|
||||||
errorText={this.state.errorText}
|
errorText={this.state.errorText}
|
||||||
errorLevel={this.state.errorLevel}
|
errorLevel={this.state.errorLevel}
|
||||||
errorAction={this.state.errorAction}
|
errorAction={this.state.errorAction}
|
||||||
errorActionText={this.state.errorActionText}
|
errorActionText={this.state.errorActionText}
|
||||||
|
|
||||||
|
onNavigate={this.infoNavigator}
|
||||||
onTopicDescUpdate={this.handleTopicUpdateRequest}
|
onTopicDescUpdate={this.handleTopicUpdateRequest}
|
||||||
onCancel={this.handleHideInfoView}
|
onCancel={this.handleHideInfoView}
|
||||||
onShowAlert={this.handleShowAlert}
|
onShowAlert={this.handleShowAlert}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export default class TopicCommonView extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleCredEntered(e) {
|
handleCredEntered(e) {
|
||||||
let value = this.state.newCred.trim();
|
const value = this.state.newCred.trim();
|
||||||
if (!value) {
|
if (!value) {
|
||||||
this.setState({addCredActive: false, addCredInvalid: false});
|
this.setState({addCredActive: false, addCredInvalid: false});
|
||||||
return;
|
return;
|
||||||
@@ -92,14 +92,17 @@ export default class TopicCommonView extends React.Component {
|
|||||||
const credentials = [];
|
const credentials = [];
|
||||||
if (this.state.isMe) {
|
if (this.state.isMe) {
|
||||||
this.state.credentials.map((cred) => {
|
this.state.credentials.map((cred) => {
|
||||||
credentials.push(<div key={cred.meth + ":" + cred.val + ":" + cred.done}>{cred.meth}: <tt>{cred.val}</tt>
|
credentials.push(
|
||||||
<span > {!cred.done ?
|
<div key={cred.meth + ":" + cred.val + ":" + cred.done}>{cred.meth}: <tt>{cred.val}</tt>
|
||||||
<a href="#" onClick={(e) => {e.preventDefault(); this.props.onCredConfirm(cred.meth, cred.val);}}>
|
<span> {!cred.done ?
|
||||||
|
<a href="#" onClick={(e) => {e.preventDefault(); this.props.onCredConfirm(cred.meth, cred.val);}}>
|
||||||
<FormattedMessage id="validate_credential_action" defaultMessage="confirm"
|
<FormattedMessage id="validate_credential_action" defaultMessage="confirm"
|
||||||
description="Validate credentail call to action" />
|
description="Validate credentail call to action" />
|
||||||
</a>
|
</a>
|
||||||
: null} <a href="#" onClick={(e) => {e.preventDefault(); this.props.onCredDelete(cred.meth, cred.val);}}><i
|
: null} <a href="#" onClick={(e) => {e.preventDefault(); this.props.onCredDelete(cred.meth, cred.val);}}><i
|
||||||
className="material-icons gray">delete_outline</i></a></span></div>);
|
className="material-icons gray">delete_outline</i></a></span>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import React from 'react';
|
|||||||
import { injectIntl, defineMessages } from 'react-intl';
|
import { injectIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
import { REM_SIZE } from '../config.js';
|
import { REM_SIZE } from '../config.js';
|
||||||
import HashNavigation from '../lib/navigation.js';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
info: {
|
info: {
|
||||||
|
|||||||
@@ -173,37 +173,57 @@ export default class TopicDescEdit extends React.Component {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="panel-form-column">
|
<div className="panel-form-column">
|
||||||
<div className="panel-form-row">
|
<center>
|
||||||
<div className="panel-form-column">
|
<AvatarUpload
|
||||||
{this.state.isMe ? <>
|
tinode={this.props.tinode}
|
||||||
<label className="small">
|
avatar={this.state.avatar}
|
||||||
<FormattedMessage id="label_your_name" defaultMessage="Your name"
|
readOnly={!editable}
|
||||||
description="Label for full name editing" />
|
uid={this.props.topic}
|
||||||
</label>
|
title={this.state.fullName}
|
||||||
<div><FormattedMessage id="full_name_prompt" defaultMessage="Full name, e.g. John Doe"
|
onImageUpdated={this.handleImageUpdated}
|
||||||
|
onError={this.props.onError} />
|
||||||
|
</center>
|
||||||
|
{this.state.isMe ?
|
||||||
|
<div className="group">
|
||||||
|
<label className="small">
|
||||||
|
<FormattedMessage id="label_your_name" defaultMessage="Your name"
|
||||||
|
description="Label for full name editing" />
|
||||||
|
</label>
|
||||||
|
<div>
|
||||||
|
<FormattedMessage id="full_name_prompt" defaultMessage="Full name, e.g. John Doe"
|
||||||
description="Input placeholder for person's full name">{
|
description="Input placeholder for person's full name">{
|
||||||
(full_name_placeholder) => <InPlaceEdit
|
(full_name_placeholder) => <InPlaceEdit
|
||||||
placeholder={full_name_placeholder}
|
placeholder={full_name_placeholder}
|
||||||
value={this.state.fullName}
|
value={this.state.fullName}
|
||||||
required={true}
|
required={true}
|
||||||
onFinished={this.handleFullNameUpdate} />
|
onFinished={this.handleFullNameUpdate} />
|
||||||
}</FormattedMessage></div>
|
}</FormattedMessage>
|
||||||
</> : <>
|
</div>
|
||||||
|
</div>
|
||||||
|
:
|
||||||
|
<>
|
||||||
|
<div className="group">
|
||||||
<div><label className="small">
|
<div><label className="small">
|
||||||
<FormattedMessage id="label_topic_name" defaultMessage="Name"
|
<FormattedMessage id="label_topic_name" defaultMessage="Name"
|
||||||
description="Label for editing topic name" />
|
description="Label for editing topic name" />
|
||||||
</label></div>
|
</label></div>
|
||||||
<div><InPlaceEdit
|
<div>
|
||||||
|
<InPlaceEdit
|
||||||
placeholder={this.state.groupTopic ? "Group name" : <i>Unknown</i>}
|
placeholder={this.state.groupTopic ? "Group name" : <i>Unknown</i>}
|
||||||
readOnly={!this.state.owner}
|
readOnly={!this.state.owner}
|
||||||
value={this.state.fullName}
|
value={this.state.fullName}
|
||||||
required={true}
|
required={true}
|
||||||
onFinished={this.handleFullNameUpdate} /></div>
|
onFinished={this.handleFullNameUpdate} />
|
||||||
<div><label className="small">
|
</div>
|
||||||
<FormattedMessage id="label_private" defaultMessage="Private comment"
|
</div>
|
||||||
description="Label for editing 'private'" />
|
<div className="group">
|
||||||
</label></div>
|
<div>
|
||||||
|
<label className="small">
|
||||||
|
<FormattedMessage id="label_private" defaultMessage="Private comment"
|
||||||
|
description="Label for editing 'private'" />
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<FormattedMessage id="private_editing_placeholder"
|
<FormattedMessage id="private_editing_placeholder"
|
||||||
defaultMessage="Visible to you only"
|
defaultMessage="Visible to you only"
|
||||||
@@ -214,18 +234,10 @@ export default class TopicDescEdit extends React.Component {
|
|||||||
onFinished={this.handlePrivateUpdate} />
|
onFinished={this.handlePrivateUpdate} />
|
||||||
}</FormattedMessage>
|
}</FormattedMessage>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
<AvatarUpload
|
</>
|
||||||
tinode={this.props.tinode}
|
}
|
||||||
avatar={this.state.avatar}
|
<div className="group">
|
||||||
readOnly={!editable}
|
|
||||||
uid={this.props.topic}
|
|
||||||
title={this.state.fullName}
|
|
||||||
onImageUpdated={this.handleImageUpdated}
|
|
||||||
onError={this.props.onError} />
|
|
||||||
</div>
|
|
||||||
<div><label className="small">
|
<div><label className="small">
|
||||||
<FormattedMessage id="label_description" defaultMessage="Description"
|
<FormattedMessage id="label_description" defaultMessage="Description"
|
||||||
description="Label for editing topic description" />
|
description="Label for editing topic description" />
|
||||||
@@ -243,21 +255,22 @@ export default class TopicDescEdit extends React.Component {
|
|||||||
}</FormattedMessage>
|
}</FormattedMessage>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{editable ?
|
</div>
|
||||||
<>
|
{editable ?
|
||||||
<div className="hr" />
|
<>
|
||||||
<FormattedMessage id="title_tag_manager" defaultMessage="Tags (user discovery)"
|
<div className="hr" />
|
||||||
description="Section title for TagManager">{
|
<FormattedMessage id="title_tag_manager" defaultMessage="Tags (user discovery)"
|
||||||
|
description="Section title for TagManager">{
|
||||||
(title_tag_manager) => <TagManager
|
(title_tag_manager) => <TagManager
|
||||||
title={title_tag_manager}
|
title={title_tag_manager}
|
||||||
activated={false}
|
activated={false}
|
||||||
tags={this.state.tags}
|
tags={this.state.tags}
|
||||||
tinode={this.props.tinode}
|
tinode={this.props.tinode}
|
||||||
onSubmit={this.handleTagsUpdated} />
|
onSubmit={this.handleTagsUpdated} />
|
||||||
}</FormattedMessage>
|
}</FormattedMessage>
|
||||||
</>
|
</>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+464
-306
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user