add alert for destructable actions

This commit is contained in:
or-else
2019-09-24 17:12:38 +03:00
parent f3420dc66f
commit f9a29ed3ef
21 changed files with 723 additions and 301 deletions
+80 -38
View File
@@ -9,9 +9,9 @@
/* Basic elements defined */
html, body {
height:100%;
width:100%;
font-size: 10pt;
height: 100%;
width: 100%;
font-size: 10pt; /* 13.33 px/rem */
color: #666;
overflow: hidden;
background-color: silver;
@@ -82,9 +82,9 @@ img.avatar {
button {
display: inline-block;
font-family: inherit;
font-size: 1.1rem;
height: 2.2em;
line-height: 2.2em;
font-size: 1.05rem;
height: 2.2rem;
line-height: 2.2rem;
font-weight: normal;
text-align: center;
vertical-align: middle;
@@ -92,11 +92,13 @@ button {
cursor: pointer;
border: 1px solid transparent;
white-space: nowrap;
padding-left: 2rem;
padding-right: 2rem;
border-radius: 2px;
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.25);
padding-left: 1.2rem;
padding-right: 1.2rem;
border-radius: 4px;
box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.25);
text-transform: uppercase;
min-width: 5rem;
margin: 0 0.35rem 0 0.35rem;
}
button[disabled],
@@ -148,7 +150,7 @@ button.blue {
color: white;
}
button.blue:focus, button.blue:hover, button.blue:active {
background-color: #1976d2;
background-color: #2962ff;
}
button.white {
@@ -159,6 +161,16 @@ button.white:focus, button.white:hover, button.blue:active {
background-color: #e3f2fd;
}
button.outline {
background-color: transparent;
color: #2196f3; /* blue 500 */
border: 1px solid silver;
box-shadow: none;
}
button.outline:focus, button.outline:hover, button.outline:active {
background-color: #e8eaf6; /* indigo 50 */
}
textarea, input {
font-family: inherit;
font-size: 1.1rem;
@@ -303,6 +315,40 @@ li.right:hover .menuTrigger {
/* END popup/dropdown menu */
/* Begin Alert: modal window with message and buttons. */
div.alert-container {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
position: absolute;
-x-backdrop-filter: blur(4px);
background: rgba(0,0,0,0.33);
z-index: 3;
}
div.alert {
background-color: white;
box-shadow: 0 1px 6px rgba(0, 0, 0, .45);
padding: 1rem;
border-radius: 4px;
margin: auto 2rem auto 2rem;
width: content;
min-width: 16rem;
max-width: 24rem;
}
div.alert .title {
color: #2196f3;
font-size: 1.2rem;
font-weight: 500;
width: 100%;
padding: 0 0 0.35rem 0;
}
div.alert .content {
padding: 0.5rem 0 0.5rem 0;
}
/* END Alert */
/* Generic text colors */
.blue {
color: #2196f3; /* blue 500 */
@@ -354,7 +400,7 @@ li.right:hover .menuTrigger {
}
/* Top-level application layout style: sidepanel + main view */
#noscript-alertbox {
#noscript-message {
position: relative;
display: flex;
flex-direction: column;
@@ -659,57 +705,57 @@ i.search {
}
/* Area which displays an error message */
.alert-box {
.info-box {
position: relative;
display: none;
overflow: hidden;
padding: 1rem 1.5rem 1rem 0.5rem;
}
.alert-box .cancel {
.info-box .cancel {
position: absolute;
right: 0.25rem;
top: 0.5rem;
}
.alert-box.error {
.info-box.error {
display: flex;
background-color: #ffcdd2;
border-bottom: 1px solid #ffbfc8;
color: #b71c1c;
}
.alert-box.warning {
.info-box.warning {
display: flex;
background-color: #fff9c4;
border-bottom: 1px solid #fff59d;
color: #6d4c41;
}
.alert-box.info {
.info-box.info {
display: flex;
background-color: #e1f5fe;
border-bottom: 1px solid #b3e5fc;
color: #0288d1;
}
.alert-box .cancel .material-icons {
.info-box .cancel .material-icons {
font-size: 1rem;
color: #757575;
}
.alert-box.error .cancel .material-icons {
.info-box.error .cancel .material-icons {
color: #b71c1c;
}
.alert-box .icon {
.info-box .icon {
display: block;
margin-right: 0.5rem;
}
.alert-box .icon .material-icons {
.info-box .icon .material-icons {
font-size: 1.5rem;
}
.alert-box.warning .icon .material-icons {
.info-box.warning .icon .material-icons {
color: #fbc02d;
}
.alert-box.error .icon .material-icons {
.info-box.error .icon .material-icons {
color: #ef5350;
}
.alert-box.info .icon .material-icons {
.info-box.info .icon .material-icons {
color: #0288d1;
}
/* List of contacts */
@@ -876,7 +922,6 @@ i.search {
.panel-form-row {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 0.5rem 0.75rem;
line-height: 1.5;
@@ -897,13 +942,12 @@ i.search {
the top level panel */
.panel-form-row > .panel-form-column,
.panel-form-column > .panel-form-column {
padding: 0!important;
flex-grow: 1;
padding: 0!important;
flex-grow: 1;
}
.panel-form-column > .panel-form-row,
.panel-form-row > .panel-form-row
{
padding: 0!important;
.panel-form-row > .panel-form-row {
padding: 0!important;
}
/* Styling of avatar upload control */
@@ -1560,15 +1604,13 @@ ul.tabbar li.active > a:after {
/* Badge with a label, like [you], [muted], etc */
.badge {
font-family: 'Roboto Mono', Courier, monospace, sans-serif;
font-size: 0.75rem;
border: 1px solid #666;
background-color: #eee;
font-size: 0.8rem;
border: 1px solid silver;
background-color: #e8e8e8;
color: #666;
padding: 0 0.15rem 0 0.15rem;
margin-left: 0.1rem;
margin-right: 0.1rem;
margin-bottom: 0.1rem;
border-radius: 0.15rem;
padding: 0.05rem 0.25rem 0.05rem 0.25rem;
margin: 0.05rem 0.1rem 0.05rem 0.1rem;
border-radius: 0.2rem;
display: inline-block;
align-self: flex-start;
}
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -38,7 +38,7 @@
</head>
<body>
<noscript><div id="noscript-alertbox"><div id="noscript-title">Javascript support is required.</div>
<noscript><div id="noscript-message"><div id="noscript-title">Javascript support is required.</div>
<div id="noscript-content">It appears JavaScript is turned off or is not supported by your browser.
TinodeWeb does not work without JavaScript. Please enable JavaScript by changing your browser options,
then <a href="">try again</a>.
+1 -1
View File
@@ -27,7 +27,7 @@
<script crossorigin="anonymous" src="https://unpkg.com/firebase@6.4.2/firebase-messaging.js"></script>
</head>
<body>
<noscript><div id="noscript-alertbox"><div id="noscript-title">Javascript support is required.</div>
<noscript><div id="noscript-message"><div id="noscript-title">Javascript support is required.</div>
<div id="noscript-content">It appears JavaScript is turned off or is not supported by your browser.
TinodeWeb does not work without JavaScript. Please enable JavaScript by changing your browser options,
then <a href="">try again</a>.</div></div></noscript>
+8 -5
View File
@@ -24,6 +24,14 @@
"granted_permissions": "Granted",
"menu_item_edit_permissions": "Edit permissions",
"label_other_user": "Other",
"action_delete_messages": "Delete Messages",
"delete_messages_warning": "Are you sure you want to delete all mesages? It cannot be undone.",
"action_leave_chat": "Leave Conversation",
"leave_chat_warning": "Are you sure you want to leave this conversation?",
"action_block_contact": "Block Contact",
"block_contact_warning": "Are you sure you want to block this contact?",
"action_report_chat": "Report Conversation",
"report_chat_warning": "Are you sure you want to block and report this conversation?",
"title_info": "Info",
"label_topic_name": "Name",
"label_private": "Private comment",
@@ -34,11 +42,6 @@
"label_permissions": "Permissions:",
"label_you": "You:",
"label_default_access": "Default access mode:",
"action_delete_messages": "Delete Messages",
"action_leave_chat": "Leave Conversation",
"action_report_group": "Report Group",
"action_block_contact": "Block Contact",
"action_report_contact": "Report Contact",
"label_group_members": "Group members:",
"button_add_members": "Add members",
"group_has_no_members": "No members",
+5 -2
View File
@@ -140,6 +140,9 @@
"link_privacy_policy": "Политика конфиденциальности",
"action_delete_messages": "Удалить сообщения",
"action_block_contact": "Заблокировать контакт",
"action_report_contact": "Сообщить о нарушении",
"action_report_group": "Сообщить о нарушении"
"action_report_chat": "Сообщить о нарушении",
"delete_messages_warning": "Вы действительно хотите удалить все сообщения?",
"leave_chat_warning": "Вы действительно хотите покинуть этот чат?",
"block_contact_warning": "Вы действительно заблокировать этот контакт?",
"report_chat_warning": "Вы действительно хотите сообщить о нарушении и заблокировать этот чат?"
}
+5 -2
View File
@@ -140,6 +140,9 @@
"link_privacy_policy": "隐私政策",
"action_delete_messages": "删除所有帖子",
"action_block_contact": "屏蔽联系人",
"action_report_contact": "检举垃圾邮件",
"action_report_group": "检举垃圾邮件"
"delete_messages_warning": ":!![MISSING]!!:Are you sure you want to delete all mesages? It cannot be undone.",
"leave_chat_warning": ":!![MISSING]!!:Are you sure you want to leave this conversation.",
"block_contact_warning": ":!![MISSING]!!:Are you sure you want to block this contact?",
"action_report_chat": "检举垃圾邮件",
"report_chat_warning": ":!![MISSING]!!:Are you sure you want to block and report this conversation?"
}
+14 -9
View File
@@ -25,6 +25,14 @@
"granted_permissions": "Granted",
"menu_item_edit_permissions": "Edit permissions",
"label_other_user": "Other",
"action_delete_messages": "Delete Messages",
"delete_messages_warning": "Are you sure you want to delete all mesages? It cannot be undone.",
"action_leave_chat": "Leave Conversation",
"leave_chat_warning": "Are you sure you want to leave this conversation?",
"action_block_contact": "Block Contact",
"block_contact_warning": "Are you sure you want to block this contact?",
"action_report_chat": "Report Conversation",
"report_chat_warning": "Are you sure you want to block and report this conversation?",
"title_info": "Info",
"label_topic_name": "Name",
"label_private": "Private comment",
@@ -35,11 +43,6 @@
"label_permissions": "Permissions:",
"label_you": "You:",
"label_default_access": "Default access mode:",
"action_delete_messages": "Delete Messages",
"action_leave_chat": "Leave Conversation",
"action_report_group": "Report Group",
"action_block_contact": "Block Contact",
"action_report_contact": "Report Contact",
"label_group_members": "Group members:",
"button_add_members": "Add members",
"group_has_no_members": "No members",
@@ -286,8 +289,11 @@
"link_privacy_policy": "Политика конфиденциальности",
"action_delete_messages": "Удалить сообщения",
"action_block_contact": "Заблокировать контакт",
"action_report_contact": "Сообщить о нарушении",
"action_report_group": "Сообщить о нарушении"
"action_report_chat": "Сообщить о нарушении",
"delete_messages_warning": "Вы действительно хотите удалить все сообщения?",
"leave_chat_warning": "Вы действительно хотите покинуть этот чат?",
"block_contact_warning": "Вы действительно заблокировать этот контакт?",
"report_chat_warning": "Вы действительно хотите сообщить о нарушении и заблокировать этот чат?"
},
"zh": {
"archived_contacts": "已归档联系人 ({count})",
@@ -431,7 +437,6 @@
"link_privacy_policy": "隐私政策",
"action_delete_messages": "删除所有帖子",
"action_block_contact": "屏蔽联系人",
"action_report_contact": "检举垃圾邮件",
"action_report_group": "检举垃圾邮件"
"action_report_chat": "检举垃圾邮件"
}
}
+1 -1
View File
@@ -291,7 +291,7 @@ export default class EditAccountView extends React.Component {
<div className="hr" />
<div className="panel-form-column">
<a href="#" className="red flat-button" onClick={(e) => {e.preventDefault(); this.props.onLogout();}}>
<i className="material-icons">exit_to_app</i> <FormattedMessage id="button_logout"
<i className="material-icons">exit_to_app</i> &nbsp;<FormattedMessage id="button_logout"
defaultMessage="Logout" description="Button [Logout]" />
</a>
</div>
+106 -21
View File
@@ -40,7 +40,47 @@ const messages = defineMessages({
id: 'label_other_user',
defaultMessage: 'Other',
description: 'Label for the other user when the user is unnamed'
}
},
delete_messages: {
id: "action_delete_messages",
defaultMessage: "Delete Messages",
description: "Flat button [Delete Messages]"
},
delete_messages_warning: {
id: "delete_messages_warning",
defaultMessage: "Are you sure you want to delete all mesages? It cannot be undone.",
description: "Alert dialog warning when 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"
},
});
class InfoView extends React.Component {
@@ -91,7 +131,10 @@ class InfoView extends React.Component {
this.handleShowAddMembers = this.handleShowAddMembers.bind(this);
this.handleHideAddMembers = this.handleHideAddMembers.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.handleMoreInfo = this.handleMoreInfo.bind(this);
this.handleTagsUpdated = this.handleTagsUpdated.bind(this);
@@ -354,9 +397,56 @@ class InfoView extends React.Component {
this.setState({showMemberPanel: false});
}
handleDeleteMessages(e) {
e.preventDefault();
const {formatMessage} = this.props.intl;
this.props.onShowAlert(
formatMessage(messages.delete_messages), // title
formatMessage(messages.delete_messages_warning), // content
(() => { this.props.onDeleteMessages(this.props.topic); }), // onConfirm
null, // "OK"
true, // Show Reject button
null // "Cancel"
);
}
handleLeave(e) {
e.preventDefault();
this.props.onLeaveTopic(this.props.topic);
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) {
@@ -591,29 +681,24 @@ class InfoView extends React.Component {
}
<div className="panel-form-column">
<a href="#" className="flat-button" onClick={this.handleDeleteMessages}>
<i className="material-icons">delete_outline</i> &npbs;<FormattedMessage id="action_delete_messages"
defaultMessage="Delete Messages" description="Flat button [Delete Messages]" />
<i className="material-icons">delete_outline</i> &nbsp;{formatMessage(messages.delete_messages)}
</a>
<a href="#" className="red flat-button" onClick={this.handleLeave}>
<i className="material-icons">exit_to_app</i> &npbs;<FormattedMessage id="action_leave_chat"
defaultMessage="Leave Conversation" description="Flat button [Leave Conversation]" />
<i className="material-icons">exit_to_app</i> &nbsp;{formatMessage(messages.leave_chat)}
</a>
{this.state.groupTopic ?
<a href="#" className="red flat-button" onClick={this.handleReport}>
<i className="material-icons">report</i> &npbs;<FormattedMessage id="action_report_group"
defaultMessage="Report Group" description="Flat button [Report Group]" />
{!this.state.groupTopic ?
<a href="#" className="red flat-button" onClick={this.handleBlock}>
<i className="material-icons">block</i> &nbsp;{formatMessage(messages.block_contact)}
</a>
:
<>
<a href="#" className="red flat-button" onClick={this.handleBlock}>
<i className="material-icons">block</i> &npbs;<FormattedMessage id="action_block_contact"
defaultMessage="Block Contact" description="Flat button [Block Contact]" />
</a>
<a href="#" className="red flat-button" onClick={this.handleReport}>
<i className="material-icons">report</i> &npbs;<FormattedMessage id="action_report_contact"
defaultMessage="Report Contact" description="Flat button [Report Contact]" />
</a>
</>
:
null
}
{!this.state.owner ?
<a href="#" className="red flat-button" onClick={this.handleReport}>
<i className="material-icons">report</i> &nbsp;{formatMessage(messages.report_chat)}
</a>
:
null
}
</div>
{this.state.groupTopic ?
+82 -7
View File
@@ -8,6 +8,7 @@ import 'firebase/messaging';
import Tinode from 'tinode-sdk';
import Alert from '../widgets/alert.jsx';
import ContextMenu from '../widgets/context-menu.jsx';
import InfoView from './info-view.jsx';
@@ -98,11 +99,14 @@ class TinodeWeb extends React.Component {
this.handleChangePermissions = this.handleChangePermissions.bind(this);
this.handleTagsUpdated = this.handleTagsUpdated.bind(this);
this.handleLogout = this.handleLogout.bind(this);
this.handleDeleteMessagesRequest = this.handleDeleteMessagesRequest.bind(this);
this.handleLeaveUnsubRequest = this.handleLeaveUnsubRequest.bind(this);
this.handleDialogCancel = this.handleDialogCancel.bind(this);
this.handleBlockTopicRequest = this.handleBlockTopicRequest.bind(this);
this.handleReportTopic = this.handleReportTopic.bind(this);
this.handleShowContextMenu = this.handleShowContextMenu.bind(this);
this.defaultTopicContextMenu = this.defaultTopicContextMenu.bind(this);
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);
@@ -138,8 +142,7 @@ class TinodeWeb extends React.Component {
sidePanelSelected: 'login',
sidePanelTitle: null,
sidePanelAvatar: null,
dialogSelected: null,
contextMenuVisible: false,
login: '',
password: '',
myUserId: null,
@@ -159,6 +162,10 @@ class TinodeWeb extends React.Component {
contextMenuParams: null,
contextMenuItems: [],
// Modal alert dialog.
alertVisible: false,
alertParams: {},
// Chats as shown in the ContactsView
chatList: [],
// Contacts returned by a search query.
@@ -419,7 +426,6 @@ class TinodeWeb extends React.Component {
connected: false,
ready: false,
topicSelectedOnline: false,
dialogSelected: null,
errorText: err && err.message ? err.message : "Disconnected",
errorLevel: err && err.message ? 'err' : 'warn',
loginDisabled: false,
@@ -1080,6 +1086,18 @@ class TinodeWeb extends React.Component {
HashNavigation.navigateTo('');
}
handleDeleteMessagesRequest(topicName) {
const topic = this.tinode.getTopic(topicName);
if (!topic) {
return;
}
// Request hard-delete all messages.
topic.delMessagesAll(true).catch((err) => {
this.handleError(err.message, 'err');
});
}
handleLeaveUnsubRequest(topicName) {
const topic = this.tinode.getTopic(topicName);
if (!topic) {
@@ -1094,8 +1112,39 @@ class TinodeWeb extends React.Component {
});
}
handleDialogCancel() {
this.setState({dialogSelected: null});
handleBlockTopicRequest(topicName) {
const topic = this.tinode.getTopic(topicName);
if (!topic) {
return;
}
topic.updateMode(null, '-JP').then((ctrl) => {
// Hide MessagesView and InfoView panels.
HashNavigation.navigateTo(HashNavigation.setUrlTopic(window.location.hash, ''));
}).catch((err) => {
this.handleError(err.message, 'err');
});
}
handleReportTopic(topicName) {
const topic = this.tinode.getTopic(topicName);
if (!topic) {
return;
}
// Publish spam report.
this.tinode.publish(Tinode.TOPIC_SYS, Tinode.Drafty.attachJSON(null, {
'action': 'report',
'target': topicName
}));
// Remove J and P permissions.
topic.updateMode(null, '-JP').then((ctrl) => {
// Hide MessagesView and InfoView panels.
HashNavigation.navigateTo(HashNavigation.setUrlTopic(window.location.hash, ''));
}).catch((err) => {
this.handleError(err.message, 'err');
});
}
handleShowContextMenu(params, menuItems) {
@@ -1156,6 +1205,20 @@ class TinodeWeb extends React.Component {
}
}
handleShowAlert(title, content, onConfirm, confirm, onReject, reject) {
this.setState({
alertVisible: true,
alertParams: {
title: title,
content: content,
onConfirm: onConfirm,
confirm: confirm,
onReject: onReject,
reject: reject
}
});
}
handleShowInfoView() {
HashNavigation.navigateTo(HashNavigation.addUrlParam(window.location.hash, 'info', true));
this.setState({showInfoPanel: true});
@@ -1258,7 +1321,15 @@ class TinodeWeb extends React.Component {
:
null
}
<Alert
visible={this.state.alertVisible}
title={this.state.alertParams.title}
content={this.state.alertParams.content}
onReject={this.state.alertParams.onReject ? (() => { this.setState({alertVisible: false}); }) : null}
reject={this.state.alertParams.reject}
onConfirm={() => { this.setState({alertVisible: false}); this.state.alertParams.onConfirm(); }}
confirm={this.state.alertParams.confirm}
/>
<SidepanelView
tinode={this.tinode}
connected={this.state.connected}
@@ -1365,9 +1436,13 @@ class TinodeWeb extends React.Component {
onTopicDescUpdate={this.handleTopicUpdateRequest}
onCancel={this.handleHideInfoView}
onShowAlert={this.handleShowAlert}
onChangePermissions={this.handleChangePermissions}
onMemberUpdateRequest={this.handleMemberUpdateRequest}
onDeleteMessages={this.handleDeleteMessagesRequest}
onLeaveTopic={this.handleLeaveUnsubRequest}
onBlockTopic={this.handleBlockTopicRequest}
onReportTopic={this.handleReportTopic}
onAddMember={this.handleManageGroupMembers}
onTopicTagsUpdate={this.handleTagsUpdated}
onInitFind={this.tnInitFind}
+5 -4
View File
@@ -44,7 +44,7 @@ export default class ChipInput extends React.Component {
static indexChips(chips) {
const index = {};
let count = 0;
chips.map(function(item) {
chips.map((item) => {
index[item.user] = count;
count ++;
});
@@ -55,8 +55,8 @@ export default class ChipInput extends React.Component {
static sortChips(chips, keep) {
const required = [];
const normal = [];
chips.map(function(item) {
if (keep.includes(item.user)) {
chips.map((item) => {
if (keep && keep.includes(item.user)) {
required.push(item);
} else {
normal.push(item);
@@ -114,6 +114,7 @@ export default class ChipInput extends React.Component {
render() {
const chips = [];
let count = 0;
const staticMembers = this.props.staticMembers || [];
this.state.sortedChips.map((item) => {
chips.push(
<Chip
@@ -122,7 +123,7 @@ export default class ChipInput extends React.Component {
title={item.public ? item.public.fn : undefined}
noAvatar={this.props.avatarDisabled}
topic={item.user}
required={this.props.staticMembers.includes(item.user)}
required={staticMembers.includes(item.user)}
invalid={item.invalid}
index={count}
key={item.user} />
+2 -14
View File
@@ -277,7 +277,7 @@ class ContextMenu extends React.Component {
return;
}
// Can't cancel. Delete instead.
let promise = all ?
const promise = all ?
topic.delMessagesAll(hard) :
topic.delMessagesList([params.seq], hard);
@@ -296,19 +296,7 @@ class ContextMenu extends React.Component {
return;
}
let am, user;
if (params.user) {
user = topic.subscriber(params.user);
if (!user) {
console.log("Subscriber not found", params.topicName + "[" + params.user + "]");
return;
}
am = user.acs.updateGiven(mode).getGiven();
} else {
am = topic.getAccessMode().updateWant(mode).getWant();
}
let result = topic.setMeta({sub: {user: params.user, mode: am}});
let result = topic.updateMode(params.user, mode);
if (errorHandler) {
result = result.catch((err) => {
errorHandler(err.message, 'err');
+1 -1
View File
@@ -31,7 +31,7 @@ export default class ErrorPanel extends React.PureComponent {
render() {
const icons = {err: 'error', warn: 'warning', info: 'info'}
const level = icons[this.props.level] || '';
const className = 'alert-box ' + level;
const className = 'info-box ' + level;
return (
<div className={className}>
<div className="icon"><i className="material-icons">{level}</i></div>
+3 -3
View File
@@ -150,12 +150,12 @@ class PermissionsEditor extends React.Component {
</tbody></table>
<br />
<div className="dialog-buttons">
<button className="outline" onClick={this.handleCancel}>
<FormattedMessage id="button_cancel" />
</button>
<button className="blue" onClick={this.handleSubmit}>
<FormattedMessage id="button_ok" />
</button>
<button className="white" onClick={this.handleCancel}>
<FormattedMessage id="button_cancel" />
</button>
</div>
</div>
);
+4 -4
View File
@@ -121,13 +121,13 @@ export default class TagManager extends React.Component {
filterFunc={this.handleTagInput} />
}</FormattedMessage>
{this.props.onSubmit || this.props.onCancel ?
<div id="tag-manager-buttons" className="panel-form-row">
<div id="tag-manager-buttons" className="dialog-buttons panel-form-row">
<button className="outline" onClick={this.handleCancel}>
<FormattedMessage id="button_cancel" defautMessage="Cancel" description="Rejection button [Cancel]" />
</button>
<button className="blue" onClick={this.handleSubmit}>
<FormattedMessage id="button_ok" defautMessage="OK" description="Confirmation button [OK]" />
</button>
<button className="white" onClick={this.handleCancel}>
<FormattedMessage id="button_cancel" defautMessage="Cancel" description="Rejection button [Cancel]" />
</button>
</div>
: null}
</div>
+399 -182
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
+2 -2
View File
@@ -39,8 +39,8 @@ module.exports = (env, argv) => {
]
},
performance: {
maxEntrypointSize: 250000,
maxAssetSize: 250000
maxEntrypointSize: 262144,
maxAssetSize: 262144
},
externals: {
'react': 'React',