even more translations and fixes
This commit is contained in:
@@ -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",
|
||||
|
||||
+34
-4
@@ -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": "Подробности"
|
||||
}
|
||||
@@ -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
@@ -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": "Подробности"
|
||||
}
|
||||
}
|
||||
+113
-35
@@ -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"
|
||||
<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} /></div>
|
||||
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"
|
||||
<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: <tt className="clickable"
|
||||
<div>
|
||||
<FormattedMessage id="label_you" defaultMessage="You:"
|
||||
description="Label for the current user" /> <tt className="clickable"
|
||||
onClick={this.handleLaunchPermissionsEditor.bind(this, 'want')}>
|
||||
{this.state.access}
|
||||
</tt></div>
|
||||
<div>{this.state.fullName ? this.state.fullName : "Other"}′s:
|
||||
<div>{this.state.fullName ? this.state.fullName : formatMessage(messages.other_user)}:
|
||||
<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"
|
||||
<FormattedMessage id="title_tag_manager">{
|
||||
(tags) => <TagManager
|
||||
title={tags}
|
||||
tags={this.state.tags}
|
||||
activated={false}
|
||||
onSubmit={this.handleTagsUpdated} />
|
||||
}</FormattedMessage>
|
||||
:
|
||||
null
|
||||
}
|
||||
@@ -514,24 +581,31 @@ 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
|
||||
<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"
|
||||
emptyListMessage={no_members}
|
||||
topicSelected={this.state.selectedContact}
|
||||
showOnline={false}
|
||||
showUnread={false}
|
||||
@@ -540,11 +614,13 @@ export default class InfoView extends React.Component {
|
||||
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
@@ -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);
|
||||
|
||||
@@ -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
File diff suppressed because one or more lines are too long
+5
-5
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user