even more translations and fixes

This commit is contained in:
or-else
2018-10-30 11:44:50 +03:00
parent c8506eb143
commit 954b0079a4
9 changed files with 382 additions and 107 deletions
+30
View File
@@ -13,6 +13,25 @@
"label_push_notifications_disabled": "Notification alerts (requires HTTPS):",
"title_tag_manager": "Tags (user discovery)",
"button_logout": "Logout",
"requested_permissions": "Requested",
"granted_permissions": "Granted",
"menu_item_edit_permissions": "Edit permissions",
"label_other_user": "Other",
"title_info": "Info",
"label_topic_name": "Name",
"label_private": "Private comment",
"private_editing_placeholder": "Visible to you only",
"label_muting_topic": "Muted:",
"action_more": "More",
"label_your_permissions": "Your permissions:",
"label_permissions": "Permissions:",
"label_you": "You:",
"label_default_access": "Default access mode:",
"label_group_members": "Group members:",
"button_add_members": "Add members",
"button_leave": "Leave",
"group_has_no_members": "No members",
"action_leave_chat": "Leave",
"login_prompt": "Login",
"password_prompt": "Password",
"stay_logged_in": "Stay logged in",
@@ -45,6 +64,17 @@
"numeric_confirmation_code_prompt": "Numbers only",
"button_confirm": "Confirm",
"invalid_content": "invalid content",
"menu_item_info": "Info",
"menu_item_clear_messages": "Clear messages",
"menu_item_clear_messages_for_all": "Clear for All",
"menu_item_delete": "Delete",
"menu_item_delete_for_all": "Delete for All",
"menu_item_mute": "Mute",
"menu_item_unmute": "Unmute",
"menu_item_delete_topic": "Delete",
"menu_item_unblock": "Unblock",
"menu_item_block": "Block",
"menu_item_member_delete": "Remove",
"title_group_members": "Group members",
"button_ok": "OK",
"button_cancel": "Cancel",
+35 -5
View File
@@ -62,13 +62,43 @@
"email_dative": "емейлу",
"title_group_members": "Участники",
"download_action": "скачать",
"permission_join": "Присоединяться ({val})",
"permission_join": "Подписываться ({val})",
"permission_read": "Читать ({val})",
"permission_write": "Писать ({val})",
"permission_pres": "Получать уведомления ({val})",
"permission_admin": "Администрировать ({val})",
"permission_pres": "Уведомлять ({val})",
"permission_admin": "Подтверждать ({val})",
"permission_share": "Приглашать ({val})",
"permission_delete": "Удалять ({val})",
"permission_owner": "Владелец ({val})",
"title_permissions": "Права доступа"
}
"title_permissions": "Права доступа",
"requested_permissions": "Требуются",
"granted_permissions": "Получены",
"menu_item_edit_permissions": "Права доступа",
"label_other_user": "Второй",
"label_topic_name": "Название",
"label_private": "Комментарий",
"private_editing_placeholder": "Виден только вам",
"label_muting_topic": "Без уведомлений",
"action_more": "Ещё",
"label_your_permissions": "Ваши права доступа:",
"label_permissions": "Права доступа:",
"label_you": "Вы:",
"label_default_access": "Права по умолчанию:",
"label_group_members": "Участники чата:",
"button_add_members": "Добавить",
"button_leave": "Отписаться",
"group_has_no_members": "Нет участников",
"action_leave_chat": "Уйти из чата",
"menu_item_info": "Информация",
"menu_item_clear_messages": "Удалить сообщения",
"menu_item_clear_messages_for_all": "Удалить для всех",
"menu_item_delete": "Удалить",
"menu_item_delete_for_all": "Удалить для всех",
"menu_item_mute": "Не уведомлять",
"menu_item_unmute": "Уведомлять",
"menu_item_delete_topic": "Удалить",
"menu_item_unblock": "Разблокировать",
"menu_item_block": "Заблокировать",
"menu_item_member_delete": "Отписать",
"title_info": "Подробности"
}
+7 -2
View File
@@ -15,7 +15,12 @@ export default class LocalStorageUtil {
// Partially or wholly update stored object.
static updateObject(key, value) {
let oldVal = localStorage.getObject(key);
localStorage.setObject(key, Object.assign(oldVal || {}, value));
let oldVal = this.getObject(key);
this.setObject(key, Object.assign(oldVal || {}, value));
}
// Just a wrapper.
static removeItem(key) {
localStorage.removeItem(key);
}
}
+63 -3
View File
@@ -14,6 +14,25 @@
"label_push_notifications_disabled": "Notification alerts (requires HTTPS):",
"title_tag_manager": "Tags (user discovery)",
"button_logout": "Logout",
"requested_permissions": "Requested",
"granted_permissions": "Granted",
"menu_item_edit_permissions": "Edit permissions",
"label_other_user": "Other",
"title_info": "Info",
"label_topic_name": "Name",
"label_private": "Private comment",
"private_editing_placeholder": "Visible to you only",
"label_muting_topic": "Muted:",
"action_more": "More",
"label_your_permissions": "Your permissions:",
"label_permissions": "Permissions:",
"label_you": "You:",
"label_default_access": "Default access mode:",
"label_group_members": "Group members:",
"button_add_members": "Add members",
"button_leave": "Leave",
"group_has_no_members": "No members",
"action_leave_chat": "Leave",
"login_prompt": "Login",
"password_prompt": "Password",
"stay_logged_in": "Stay logged in",
@@ -46,6 +65,17 @@
"numeric_confirmation_code_prompt": "Numbers only",
"button_confirm": "Confirm",
"invalid_content": "invalid content",
"menu_item_info": "Info",
"menu_item_clear_messages": "Clear messages",
"menu_item_clear_messages_for_all": "Clear for All",
"menu_item_delete": "Delete",
"menu_item_delete_for_all": "Delete for All",
"menu_item_mute": "Mute",
"menu_item_unmute": "Unmute",
"menu_item_delete_topic": "Delete",
"menu_item_unblock": "Unblock",
"menu_item_block": "Block",
"menu_item_member_delete": "Remove",
"title_group_members": "Group members",
"button_ok": "OK",
"button_cancel": "Cancel",
@@ -140,11 +170,41 @@
"permission_join": "Присоединяться ({val})",
"permission_read": "Читать ({val})",
"permission_write": "Писать ({val})",
"permission_pres": "Получать уведомления ({val})",
"permission_admin": "Администрировать ({val})",
"permission_pres": "Уведомлять ({val})",
"permission_admin": "Подтверждать ({val})",
"permission_share": "Приглашать ({val})",
"permission_delete": "Удалять ({val})",
"permission_owner": "Владелец ({val})",
"title_permissions": "Права доступа"
"title_permissions": "Права доступа",
"requested_permissions": "Требуются",
"granted_permissions": "Получены",
"menu_item_edit_permissions": "Права доступа",
"label_other_user": "Второй",
"label_topic_name": "Название",
"label_private": "Комментарий",
"private_editing_placeholder": "Виден только вам",
"label_muting_topic": "Без уведомлений",
"action_more": "Ещё",
"label_your_permissions": "Ваши права доступа:",
"label_permissions": "Права доступа:",
"label_you": "Вы:",
"label_default_access": "Права по умолчанию:",
"label_group_members": "Участники чата:",
"button_add_members": "Добавить",
"button_leave": "Отписаться",
"group_has_no_members": "Нет участников",
"action_leave_chat": "Уйти из чата",
"menu_item_info": "Информация",
"menu_item_clear_messages": "Удалить сообщения",
"menu_item_clear_messages_for_all": "Удалить для всех",
"menu_item_delete": "Удалить",
"menu_item_delete_for_all": "Удалить для всех",
"menu_item_mute": "Не уведомлять",
"menu_item_unmute": "Уведомлять",
"menu_item_delete_topic": "Удалить",
"menu_item_unblock": "Разблокировать",
"menu_item_block": "Заблокировать",
"menu_item_member_delete": "Отписать",
"title_info": "Подробности"
}
}
+129 -51
View File
@@ -1,5 +1,6 @@
// InfoView: panel with topic/user info.
import React from 'react';
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
import AvatarUpload from '../widgets/avatar-upload.jsx';
import CheckBox from '../widgets/checkbox.jsx';
@@ -13,7 +14,30 @@ import TagManager from '../widgets/tag-manager.jsx';
import { makeImageUrl } from '../lib/blob-helpers.js';
export default class InfoView extends React.Component {
const messages = defineMessages({
requested: {
id: 'requested_permissions',
defaultMessage: 'Requested',
description: 'Title for permissions'
},
granted: {
id: 'granted_permissions',
defaultMessage: 'Granted',
description: 'Title for permissions'
},
edit_permissions: {
id: 'menu_item_edit_permissions',
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'
}
});
class InfoView extends React.Component {
constructor(props) {
super(props);
@@ -241,6 +265,7 @@ export default class InfoView extends React.Component {
}
handleLaunchPermissionsEditor(which, uid) {
const {formatMessage} = this.props.intl;
let toEdit, toCompare, toSkip, titleEdit, titleCompare, userTitle, userAvatar;
switch (which) {
case 'mode':
@@ -250,15 +275,15 @@ export default class InfoView extends React.Component {
toEdit = this.state.modeWant;
toCompare = this.state.modeGiven;
toSkip = this.state.groupTopic ? 'O' : 'ASDO';
titleEdit = "Requested";
titleCompare = "Granted";
titleEdit = formatMessage(messages.requested);
titleCompare = formatMessage(messages.granted);
break;
case 'given':
toEdit = this.state.modeGiven2;
toCompare = this.state.modeWant2;
toSkip = this.state.groupTopic ? (this.state.owner ? '' : 'O') : 'ASDO';
titleEdit = "Granted";
titleCompare = "Requested";
titleEdit = formatMessage(messages.granted);
titleCompare = formatMessage(messages.requested);
break;
case 'auth':
toEdit = this.state.auth;
@@ -280,8 +305,8 @@ export default class InfoView extends React.Component {
toEdit = user.acs.getGiven();
toCompare = user.acs.getWant();
toSkip = this.state.owner ? '' : 'O';
titleEdit = "Granted";
titleCompare = "Requested";
titleEdit = formatMessage(messages.granted);
titleCompare = formatMessage(messages.requested);
if (user.public) {
userTitle = user.public.fn;
userAvatar = user.public.photo;
@@ -342,18 +367,19 @@ export default class InfoView extends React.Component {
}
handleContextMenu(params) {
var instance = this;
var topic = this.props.tinode.getTopic(this.props.topic);
const {formatMessage} = this.props.intl;
const instance = this;
const topic = this.props.tinode.getTopic(this.props.topic);
if (!topic) {
return;
}
var user = topic.subscriber(params.topicName);
const user = topic.subscriber(params.topicName);
if (!user || !user.acs) {
return;
}
var menuItems = [
{title: "Edit permissions", handler: function() {
const menuItems = [
{title: formatMessage(messages.edit_permissions), handler: function() {
instance.handleLaunchPermissionsEditor('user', params.topicName);
}},
'member_delete',
@@ -368,10 +394,14 @@ export default class InfoView extends React.Component {
}
render() {
const {formatMessage} = this.props.intl;
return (
<div id="info-view">
<div className="caption-panel" id="info-caption-panel">
<div className="panel-title" id="info-title">Info</div>
<div className="panel-title" id="info-title">
<FormattedMessage id="title_info" defaultMessage="Info" description="Title for InfoView" />
</div>
<div>
<MenuCancel onCancel={this.props.onCancel} />
</div>
@@ -407,17 +437,31 @@ export default class InfoView extends React.Component {
<div id="info-view-content" className="scrollable-panel">
<div className="panel-form-row">
<div className="panel-form-column">
<div><label className="small">Name</label></div>
<div><label className="small">
<FormattedMessage id="label_topic_name" defaultMessage="Name"
description="Label for editing topic name" />
</label></div>
<div><InPlaceEdit
placeholder={this.state.groupTopic ? "Group name" : <i>Unknown</i>}
readOnly={!this.state.owner}
value={this.state.fullName}
onFinished={this.handleFullNameUpdate} /></div>
<div><label className="small">Private comment</label></div>
<div><InPlaceEdit
placeholder="Visible to you only"
value={this.state.private}
onFinished={this.handlePrivateUpdate} /></div>
<div>
<label className="small">
<FormattedMessage id="label_private" defaultMessage="Private comment"
description="Label for editing 'private'" />
</label>
</div>
<div>
<FormattedMessage id="private_editing_placeholder"
defaultMessage="Visible to you only"
description="Placeholder for editing 'private'">{
(private_placeholder) => <InPlaceEdit
placeholder={private_placeholder}
value={this.state.private}
onFinished={this.handlePrivateUpdate} />
}</FormattedMessage>
</div>
</div>
<AvatarUpload
avatar={this.state.avatar}
@@ -430,23 +474,32 @@ export default class InfoView extends React.Component {
<div className="hr" />
<div className="panel-form-column">
<div className="panel-form-row">
<label>Muted:</label>
<label>
<FormattedMessage id="label_muting_topic" defaultMessage="Muted:"
description="Label for Muting/unmuting the topic" />
</label>
<CheckBox name="P" checked={this.state.muted}
onChange={this.handleMuted} />
</div>
<MoreButton
title="More"
open={this.state.moreInfoExpanded}
onToggle={this.handleMoreInfo} />
<FormattedMessage id="action_more" defaultMessage="More"
description="Action for showing more content">{
(more) => <MoreButton
title={more}
open={this.state.moreInfoExpanded}
onToggle={this.handleMoreInfo} />
}</FormattedMessage>
{this.state.moreInfoExpanded ?
<div className="panel-form-column">
<div className="panel-form-row">
<label>Address:</label>
<label><FormattedMessage id="label_user_id" /></label>
<tt>{this.state.address}</tt>
</div>
{this.state.groupTopic ?
<div className="panel-form-row">
<label>Your permissions:</label>
<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}
@@ -454,13 +507,20 @@ export default class InfoView extends React.Component {
</div>
:
<div>
<div><label className="small">Permissions:</label></div>
<div>
<label className="small">
<FormattedMessage id="label_permissions" defaultMessage="Permissions:"
description="Section title" />
</label>
</div>
<div className="quoted">
<div>Yours: &nbsp;<tt className="clickable"
<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 : "Other"}&prime;s:
<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>
@@ -470,7 +530,12 @@ export default class InfoView extends React.Component {
}
{this.state.sharer && (this.state.auth || this.state.anon) ?
<div>
<div><label className="small">Default access mode:</label></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"
@@ -502,11 +567,13 @@ export default class InfoView extends React.Component {
</div>
<div className="hr" />
{this.state.owner ?
<TagManager
title="Tags"
tags={this.state.tags}
activated={false}
onSubmit={this.handleTagsUpdated} />
<FormattedMessage id="title_tag_manager">{
(tags) => <TagManager
title={tags}
tags={this.state.tags}
activated={false}
onSubmit={this.handleTagsUpdated} />
}</FormattedMessage>
:
null
}
@@ -514,37 +581,46 @@ export default class InfoView extends React.Component {
{this.state.groupTopic ?
<div className="panel-form-column">
<div className="panel-form-row">
<label className="small">Group members:</label>
<label className="small">
<FormattedMessage id="label_group_members" defaultMessage="Group members:"
description="Section title or label" />
</label>
</div>
<div className="panel-form-row">
{this.state.sharer ?
<a href="javascript:;" className="flat-button" onClick={this.handleShowAddMembers}>
<i className="material-icons">person_add</i> Add members
<i className="material-icons">person_add</i> <FormattedMessage id="button_add_members"
defaultMessage="Add members" description="Flat button [Add members] (to topic)" />
</a>
: null}
{!this.state.owner ?
<a href="javascript:;" className="red flat-button" onClick={this.handleLeave}>
<i className="material-icons">exit_to_app</i> Leave
<i className="material-icons">exit_to_app</i> <FormattedMessage id="button_leave"
defaultMessage="Leave" description="Flat button [Leave] (topic)" />
</a>
: null}
</div>
<ContactList
contacts={this.state.contactList}
myUserId={this.props.myUserId}
emptyListMessage="No members"
topicSelected={this.state.selectedContact}
showOnline={false}
showUnread={false}
showMode={true}
noScroll={true}
onTopicSelected={this.handleMemberSelected}
showContextMenu={this.state.admin ? this.handleContextMenu : false}
/>
<FormattedMessage id="group_has_no_members" defaultMessage="No members"
description="Shown in place of group members">{
(no_members) => <ContactList
contacts={this.state.contactList}
myUserId={this.props.myUserId}
emptyListMessage={no_members}
topicSelected={this.state.selectedContact}
showOnline={false}
showUnread={false}
showMode={true}
noScroll={true}
onTopicSelected={this.handleMemberSelected}
showContextMenu={this.state.admin ? this.handleContextMenu : false}
/>
}</FormattedMessage>
</div>
:
<div className="panel-form-row">
<a href="javascript:;" className="red flat-button" onClick={this.handleLeave}>
<i className="material-icons">exit_to_app</i> Leave
<i className="material-icons">exit_to_app</i> <FormattedMessage id="action_leave_chat"
defaultMessage="Leave" description="Action [Leave] chat" />
</a>
</div>
}
@@ -554,3 +630,5 @@ export default class InfoView extends React.Component {
);
}
};
export default injectIntl(InfoView);
+19 -10
View File
@@ -1,8 +1,9 @@
// The top-level class to hold all functionality together.
import React from 'react';
import ReactDOM from 'react-dom';
import { injectIntl } from 'react-intl';
import 'firebase/app';
import * as firebase from 'firebase/app';
import 'firebase/messaging';
import Tinode from 'tinode-sdk';
@@ -23,7 +24,10 @@ import { updateFavicon } from '../lib/utils.js';
// Sound to play on message received.
const POP_SOUND = new Audio('audio/msg.mp3');
export default class TinodeWeb extends React.Component {
console.log("desktop alerts: is secure, is localhost, firebase, navigator, fb_init",
isSecureConnection(), isLocalHost(), (typeof firebase), (typeof navigator), (typeof FIREBASE_INIT));
class TinodeWeb extends React.Component {
constructor(props) {
super(props);
@@ -353,7 +357,7 @@ export default class TinodeWeb extends React.Component {
// Login failed, report error.
this.setState({loginDisabled: false, credMethod: undefined, credCode: undefined});
this.handleError(err.message, 'err');
LocalStorageUtil.removeItem('auth-token');
localStorage.removeItem('auth-token');
HashNavigation.navigateTo('');
});
} else {
@@ -396,7 +400,7 @@ export default class TinodeWeb extends React.Component {
withDesc().
build()
).catch((err) => {
LocalStorageUtil.removeItem('auth-token');
localStorage.removeItem('auth-token');
this.handleError(err.message, 'err');
HashNavigation.navigateTo('');
});
@@ -744,7 +748,7 @@ export default class TinodeWeb extends React.Component {
console.log("Unable to delete token.", err);
}).finally(() => {
LocalStorageUtil.updateObject('settings', {desktopAlerts: false});
LocalStorageUtil.removeItem('firebase-token');
localStorage.removeItem('firebase-token');
this.setState({desktopAlerts: false, firebaseToken: null});
});
} else {
@@ -865,7 +869,7 @@ export default class TinodeWeb extends React.Component {
handleLogout() {
updateFavicon(0);
LocalStorageUtil.removeItem('auth-token');
localStorage.removeItem('auth-token');
if (this.tinode) {
this.tinode.onDisconnect = undefined;
this.tinode.disconnect();
@@ -906,12 +910,15 @@ export default class TinodeWeb extends React.Component {
}
defaultTopicContextMenu(topicName) {
var muted = false, blocked = false, subscribed = false, deleter = false;
var topic = this.tinode.getTopic(topicName);
const topic = this.tinode.getTopic(topicName);
const {formatMessage} = this.props.intl;
let muted = false, blocked = false, subscribed = false, deleter = false;
if (topic) {
if (topic.isSubscribed()) {
subscribed = true;
var acs = topic.getAccessMode();
let acs = topic.getAccessMode();
muted = acs && acs.isMuted();
blocked = acs && !acs.isJoiner();
deleter = acs && acs.isDeleter();
@@ -919,7 +926,7 @@ export default class TinodeWeb extends React.Component {
}
return [
subscribed ? {title: "Info", handler: this.handleShowInfoView} : null,
subscribed ? {title: formatMessage({id: 'menu_item_info'}), handler: this.handleShowInfoView} : null,
subscribed ? 'messages_clear' : null,
subscribed && deleter ? 'messages_clear_hard' : null,
subscribed ? (muted ? 'topic_unmute' : 'topic_mute') : null,
@@ -1128,3 +1135,5 @@ export default class TinodeWeb extends React.Component {
);
}
};
export default injectIntl(TinodeWeb);
+89 -26
View File
@@ -1,38 +1,99 @@
// Context Menu: popup/dropdown menu.
import React from 'react';
import ReactDOM from 'react-dom';
import { injectIntl, defineMessages } from 'react-intl';
import { REM_SIZE } from '../config.js';
export default class ContextMenu extends React.Component {
const messages = defineMessages({
info: {
id: 'menu_item_info',
defaultMessage: 'Info',
description: 'Show extended topic information'
},
clear_messages: {
id: 'menu_item_clear_messages',
defaultMessage: 'Clear messages',
description: 'Delete all messages'
},
clear_for_all: {
id: 'menu_item_clear_messages_for_all',
defaultMessage: 'Clear for All',
description: 'Delete all message(s) for all members'
},
'delete': {
id: 'menu_item_delete',
defaultMessage: 'Delete',
description: 'Delete selected messages'
},
delete_for_all: {
id: 'menu_item_delete_for_all',
defaultMessage: 'Delete for All',
description: 'Delete selected message(s) for all members'
},
mute: {
id: 'menu_item_mute',
defaultMessage: 'Mute',
description: 'Turn off notifications'
},
unmute: {
id: 'menu_item_unmute',
defaultMessage: 'Unmute',
description: 'Turn notifications on'
},
topic_delete: {
id: 'menu_item_delete_topic',
defaultMessage: 'Delete',
description: 'Delete entire topic'
},
unblock: {
id: 'menu_item_unblock',
defaultMessage: 'Unblock',
description: 'Unblock user'
},
block: {
id: 'menu_item_block',
defaultMessage: 'Block',
description: 'Block user'
},
member_delete: {
id: 'menu_item_member_delete',
defaultMessage: 'Remove',
description: 'Remove user from topic'
}
});
class ContextMenu extends React.Component {
constructor(props) {
super(props);
const {formatMessage} = props.intl;
this.handlePageClick = this.handlePageClick.bind(this);
this.handleEscapeKey = this.handleEscapeKey.bind(this);
this.handleClick = this.handleClick.bind(this);
// Preconfigured menu items.
this.MenuItems = {
'topic_info': {title: "Info", handler: null},
'topic_info': {title: formatMessage(messages.info), handler: null},
'messages_clear': {title: "Clear messages", handler: (params, errorHandler) => {
'messages_clear': {title: formatMessage(messages.clear_messages), handler: (params, errorHandler) => {
this.deleteMessages(true, false, params, errorHandler);
}},
'messages_clear_hard': {title: "Clear for All", handler: (params, errorHandler) => {
'messages_clear_hard': {title: formatMessage(messages.clear_for_all), handler: (params, errorHandler) => {
this.deleteMessages(true, true, params, errorHandler);
}},
'message_delete': {title: "Delete", handler: (params, errorHandler) => {
'message_delete': {title: formatMessage(messages.delete), handler: (params, errorHandler) => {
this.deleteMessages(false, false, params, errorHandler);
}},
'message_delete_hard': {title: "Delete for All", handler: (params, errorHandler) => {
'message_delete_hard': {title: formatMessage(messages.delete_for_all), handler: (params, errorHandler) => {
this.deleteMessages(false, true, params, errorHandler);
}},
'topic_unmute': {title: "Unmute", handler: this.topicPermissionSetter.bind(this, '+P')},
'topic_mute': {title: "Mute", handler: this.topicPermissionSetter.bind(this, '-P')},
'topic_unblock': {title: "Unblock", handler: this.topicPermissionSetter.bind(this, '+J')},
'topic_block': {title: "Block", handler: this.topicPermissionSetter.bind(this, '-J')},
'topic_delete': {title: "Delete", handler: (params, errorHandler) => {
'topic_unmute': {title: formatMessage(messages.unmute), handler: this.topicPermissionSetter.bind(this, '+P')},
'topic_mute': {title: formatMessage(messages.mute), handler: this.topicPermissionSetter.bind(this, '-P')},
'topic_unblock': {title: formatMessage(messages.unblock), handler: this.topicPermissionSetter.bind(this, '+J')},
'topic_block': {title: formatMessage(messages.block), handler: this.topicPermissionSetter.bind(this, '-J')},
'topic_delete': {title: formatMessage(messages.topic_delete), handler: (params, errorHandler) => {
let topic = this.props.tinode.getTopic(params.topicName);
if (!topic) {
console.log("Topic not found: ", params.topicName);
@@ -44,9 +105,9 @@ export default class ContextMenu extends React.Component {
}
});
}},
'permissions': {title: "Edit permissions", handler: null},
'member_delete': {title: "Remove", handler: (params, errorHandler) => {
// menu_item_edit_permissions is defined elsewhere.
'permissions': {title: formatMessage({id: 'menu_item_edit_permissions'}), handler: null},
'member_delete': {title: formatMessage(messages.member_delete), handler: (params, errorHandler) => {
let topic = this.props.tinode.getTopic(params.topicName);
if (!topic || !params.user) {
console.log("Topic or user not found: '" + params.topicName + "', '" + params.user + "'");
@@ -58,10 +119,10 @@ export default class ContextMenu extends React.Component {
}
});
}},
'member_mute': {title: "Mute", handler: this.topicPermissionSetter.bind(this, '-P')},
'member_unmute': {title: "Unmute", handler: this.topicPermissionSetter.bind(this, '+P')},
'member_block': {title: "Block", handler: this.topicPermissionSetter.bind(this, '-J')},
'member_unblock': {title: "Unblock", handler: this.topicPermissionSetter.bind(this, '+J')},
'member_mute': {title: formatMessage(messages.mute), handler: this.topicPermissionSetter.bind(this, '-P')},
'member_unmute': {title: formatMessage(messages.unmute), handler: this.topicPermissionSetter.bind(this, '+P')},
'member_block': {title: formatMessage(messages.block), handler: this.topicPermissionSetter.bind(this, '-J')},
'member_unblock': {title: formatMessage(messages.unblock), handler: this.topicPermissionSetter.bind(this, '+J')},
};
}
@@ -104,7 +165,7 @@ export default class ContextMenu extends React.Component {
// Menu Actions
deleteMessages(all, hard, params, errorHandler) {
var topic = this.props.tinode.getTopic(params.topicName);
const topic = this.props.tinode.getTopic(params.topicName);
if (!topic) {
console.log("Topic not found: ", params.topicName);
return;
@@ -127,13 +188,13 @@ export default class ContextMenu extends React.Component {
// Function is used by context menu to set permissions.
topicPermissionSetter(mode, params, errorHandler) {
var topic = this.props.tinode.getTopic(params.topicName);
const topic = this.props.tinode.getTopic(params.topicName);
if (!topic) {
console.log("Topic not found", params.topicName);
return;
}
var am, user;
let am, user;
if (params.user) {
user = topic.subscriber(params.user);
if (!user) {
@@ -171,16 +232,16 @@ export default class ContextMenu extends React.Component {
});
// Ensure that menu is inside the app-container.
var hSize = 12 * REM_SIZE;
var vSize = REM_SIZE * (0.7 + menu.length * 2.5);
var left = (this.props.bounds.right - this.props.clickAt.x < hSize) ?
const hSize = 12 * REM_SIZE;
const vSize = REM_SIZE * (0.7 + menu.length * 2.5);
const left = (this.props.bounds.right - this.props.clickAt.x < hSize) ?
(this.props.clickAt.x - this.props.bounds.left - hSize) :
(this.props.clickAt.x - this.props.bounds.left);
var top = (this.props.bounds.bottom - this.props.clickAt.y < vSize) ?
const top = (this.props.bounds.bottom - this.props.clickAt.y < vSize) ?
(this.props.clickAt.y - this.props.bounds.top - vSize) :
(this.props.clickAt.y - this.props.bounds.top);
var position = {
const position = {
left: left + 'px',
top: top + 'px'
};
@@ -192,3 +253,5 @@ export default class ContextMenu extends React.Component {
);
}
}
export default injectIntl(ContextMenu);
+5 -5
View File
File diff suppressed because one or more lines are too long
+5 -5
View File
File diff suppressed because one or more lines are too long