trusted badges work as expected
This commit is contained in:
+26
-7
@@ -368,25 +368,44 @@ div.alert .content {
|
|||||||
}
|
}
|
||||||
/* END Alert */
|
/* END Alert */
|
||||||
|
|
||||||
|
/* BEGIN trusted badges with legend */
|
||||||
|
div.trusted-badge {
|
||||||
|
margin: 0.25rem 0;
|
||||||
|
}
|
||||||
|
/* END trusted badges */
|
||||||
|
|
||||||
/* Generic text colors */
|
/* Generic text colors */
|
||||||
.blue {
|
.blue {
|
||||||
color: #2196f3; /* blue 500 */
|
color: #2196f3!important; /* blue 500 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.verified-color {
|
||||||
|
color: #03A9F4!important; /* lt-blue 500 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.staff-color {
|
||||||
|
color: #689f38!important; /* light green 700 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.danger-color {
|
||||||
|
color: #FFC107!important; /* amber 500 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.red {
|
.red {
|
||||||
color: #D32F2F; /* red 700 */
|
color: #D32F2F!important; /* red 700 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.amber {
|
/* Color of an inverted icon badges */
|
||||||
color: #FFC107; /* amber 500 */
|
.badge-inv {
|
||||||
|
color: #fffd!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.gray {
|
.gray {
|
||||||
color: #757575;
|
color: #757575!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.light-gray {
|
.light-gray {
|
||||||
color: #bbb;
|
color: #bbb!important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.large {
|
.large {
|
||||||
@@ -565,7 +584,7 @@ div.alert .content {
|
|||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
height: 2.5rem;
|
height: 2.5rem;
|
||||||
line-height: 2.25;
|
line-height: 2.25;
|
||||||
margin: 0.25rem 0.125rem;
|
margin: 0.25rem 0.125rem 0 0.125rem;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
vertical-align: baseline;
|
vertical-align: baseline;
|
||||||
border-bottom: 1px dashed #ddd;
|
border-bottom: 1px dashed #ddd;
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+4
-1
@@ -176,5 +176,8 @@
|
|||||||
"drafty_attachment": "Dateianhang",
|
"drafty_attachment": "Dateianhang",
|
||||||
"drafty_form": "Formular:",
|
"drafty_form": "Formular:",
|
||||||
"drafty_image": "Bild",
|
"drafty_image": "Bild",
|
||||||
"menu_item_restore_topic": ":!![MISSING]!!:[object Object]"
|
"menu_item_restore_topic": "Wiederherstellen",
|
||||||
|
"badge_danger": "Verdächtig",
|
||||||
|
"badge_staff": "Verwaltung",
|
||||||
|
"badge_verified": "Verifiziert"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,10 @@
|
|||||||
"action_more": "More",
|
"action_more": "More",
|
||||||
"action_report_chat": "Report Conversation",
|
"action_report_chat": "Report Conversation",
|
||||||
"archived_contacts": "Archived contacts ({count})",
|
"archived_contacts": "Archived contacts ({count})",
|
||||||
|
"badge_danger": "Untrustworthy",
|
||||||
"badge_owner": "owner",
|
"badge_owner": "owner",
|
||||||
|
"badge_staff": "Staff-managed",
|
||||||
|
"badge_verified": "Verified/official",
|
||||||
"badge_you": "you",
|
"badge_you": "you",
|
||||||
"block_contact_warning": "Are you sure you want to block this contact?",
|
"block_contact_warning": "Are you sure you want to block this contact?",
|
||||||
"blocked_contacts_link": "Blocked contacts ({count})",
|
"blocked_contacts_link": "Blocked contacts ({count})",
|
||||||
|
|||||||
+4
-1
@@ -176,5 +176,8 @@
|
|||||||
"drafty_attachment": "Archivo",
|
"drafty_attachment": "Archivo",
|
||||||
"drafty_form": "Formulario:",
|
"drafty_form": "Formulario:",
|
||||||
"drafty_image": "Imagen",
|
"drafty_image": "Imagen",
|
||||||
"menu_item_restore_topic": ":!![MISSING]!!:[object Object]"
|
"menu_item_restore_topic": "Restaurar",
|
||||||
|
"badge_danger": "Suspicaz",
|
||||||
|
"badge_staff": "Administración",
|
||||||
|
"badge_verified": "Verificado"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,10 +31,22 @@
|
|||||||
"defaultMessage": "Archived contacts ({count})",
|
"defaultMessage": "Archived contacts ({count})",
|
||||||
"description": "Label for archived chats"
|
"description": "Label for archived chats"
|
||||||
},
|
},
|
||||||
|
"badge_danger": {
|
||||||
|
"defaultMessage": "Untrustworthy",
|
||||||
|
"description": "Suspicious or untrustworthy account or topic badge"
|
||||||
|
},
|
||||||
"badge_owner": {
|
"badge_owner": {
|
||||||
"defaultMessage": "owner",
|
"defaultMessage": "owner",
|
||||||
"description": "Badge for indicating the owner"
|
"description": "Badge for indicating the owner"
|
||||||
},
|
},
|
||||||
|
"badge_staff": {
|
||||||
|
"defaultMessage": "Staff-managed",
|
||||||
|
"description": "Explanation of a staff-managed account or topic badge"
|
||||||
|
},
|
||||||
|
"badge_verified": {
|
||||||
|
"defaultMessage": "Verified/official",
|
||||||
|
"description": "Explanation of a verified account or topic badge"
|
||||||
|
},
|
||||||
"badge_you": {
|
"badge_you": {
|
||||||
"defaultMessage": "you",
|
"defaultMessage": "you",
|
||||||
"description": "Badge for indicating the current user"
|
"description": "Badge for indicating the current user"
|
||||||
|
|||||||
+4
-2
@@ -109,7 +109,6 @@
|
|||||||
"numeric_confirmation_code_prompt": "숫자만",
|
"numeric_confirmation_code_prompt": "숫자만",
|
||||||
"button_confirm": "확인",
|
"button_confirm": "확인",
|
||||||
"save_attachment": "저장",
|
"save_attachment": "저장",
|
||||||
"delete_content": ":!![OBSOLETE]!!:컨텐츠삭제",
|
|
||||||
"invalid_content": "잘못된내용",
|
"invalid_content": "잘못된내용",
|
||||||
"user_not_found": "찾을수없음",
|
"user_not_found": "찾을수없음",
|
||||||
"badge_you": "당신",
|
"badge_you": "당신",
|
||||||
@@ -179,5 +178,8 @@
|
|||||||
"drafty_attachment": "부착",
|
"drafty_attachment": "부착",
|
||||||
"drafty_form": "형태:",
|
"drafty_form": "형태:",
|
||||||
"drafty_image": "이미지",
|
"drafty_image": "이미지",
|
||||||
"menu_item_restore_topic": ":!![MISSING]!!:[object Object]"
|
"menu_item_restore_topic": "복원",
|
||||||
|
"badge_danger": "의심 많은",
|
||||||
|
"badge_staff": "직원 관리하에",
|
||||||
|
"badge_verified": ":!![MISSING]!!:[object Object]"
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -176,5 +176,8 @@
|
|||||||
"drafty_attachment": "Atasament",
|
"drafty_attachment": "Atasament",
|
||||||
"drafty_form": "Formă:",
|
"drafty_form": "Formă:",
|
||||||
"drafty_image": "Imagine",
|
"drafty_image": "Imagine",
|
||||||
"menu_item_restore_topic": ":!![MISSING]!!:[object Object]"
|
"menu_item_restore_topic": "Restabili",
|
||||||
|
"badge_danger": "Suspicios",
|
||||||
|
"badge_staff": "Administrare",
|
||||||
|
"badge_verified": "Verificat"
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -176,5 +176,8 @@
|
|||||||
"drafty_attachment": "Аттачмент",
|
"drafty_attachment": "Аттачмент",
|
||||||
"drafty_form": "Форма:",
|
"drafty_form": "Форма:",
|
||||||
"drafty_image": "Картинка",
|
"drafty_image": "Картинка",
|
||||||
"menu_item_restore_topic": ":!![MISSING]!!:[object Object]"
|
"menu_item_restore_topic": "Разархивировать",
|
||||||
|
"badge_danger": "Подозрительный",
|
||||||
|
"badge_staff": "Администрация",
|
||||||
|
"badge_verified": "Верифицированный"
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-1
@@ -176,5 +176,8 @@
|
|||||||
"drafty_attachment": "附件",
|
"drafty_attachment": "附件",
|
||||||
"drafty_form": "形式:",
|
"drafty_form": "形式:",
|
||||||
"drafty_image": "图像",
|
"drafty_image": "图像",
|
||||||
"menu_item_restore_topic": ":!![MISSING]!!:[object Object]"
|
"menu_item_restore_topic": "从存档中恢复",
|
||||||
|
"badge_danger": "可疑的",
|
||||||
|
"badge_staff": "在员工管理下",
|
||||||
|
"badge_verified": "值得信赖"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -165,7 +165,7 @@ export function deliveryMarker(received) {
|
|||||||
case Tinode.MESSAGE_STATUS_SENDING:
|
case Tinode.MESSAGE_STATUS_SENDING:
|
||||||
return { name: 'access_time' }; // watch face
|
return { name: 'access_time' }; // watch face
|
||||||
case Tinode.MESSAGE_STATUS_FAILED:
|
case Tinode.MESSAGE_STATUS_FAILED:
|
||||||
return { name: 'warning', color: 'amber' }; // yellow icon /!\
|
return { name: 'warning', color: 'danger-color' }; // yellow icon /!\
|
||||||
case Tinode.MESSAGE_STATUS_SENT:
|
case Tinode.MESSAGE_STATUS_SENT:
|
||||||
return { name: 'done' }; // checkmark
|
return { name: 'done' }; // checkmark
|
||||||
case Tinode.MESSAGE_STATUS_RECEIVED:
|
case Tinode.MESSAGE_STATUS_RECEIVED:
|
||||||
|
|||||||
+32
-6
@@ -176,7 +176,11 @@
|
|||||||
"channel": "Sender",
|
"channel": "Sender",
|
||||||
"drafty_attachment": "Dateianhang",
|
"drafty_attachment": "Dateianhang",
|
||||||
"drafty_form": "Formular:",
|
"drafty_form": "Formular:",
|
||||||
"drafty_image": "Bild"
|
"drafty_image": "Bild",
|
||||||
|
"menu_item_restore_topic": "Wiederherstellen",
|
||||||
|
"badge_danger": "Verdächtig",
|
||||||
|
"badge_staff": "Verwaltung",
|
||||||
|
"badge_verified": "Verifiziert"
|
||||||
},
|
},
|
||||||
"en": {
|
"en": {
|
||||||
"action_block_contact": "Block Contact",
|
"action_block_contact": "Block Contact",
|
||||||
@@ -187,7 +191,10 @@
|
|||||||
"action_more": "More",
|
"action_more": "More",
|
||||||
"action_report_chat": "Report Conversation",
|
"action_report_chat": "Report Conversation",
|
||||||
"archived_contacts": "Archived contacts ({count})",
|
"archived_contacts": "Archived contacts ({count})",
|
||||||
|
"badge_danger": "Untrustworthy",
|
||||||
"badge_owner": "owner",
|
"badge_owner": "owner",
|
||||||
|
"badge_staff": "Staff-managed",
|
||||||
|
"badge_verified": "Verified/official",
|
||||||
"badge_you": "you",
|
"badge_you": "you",
|
||||||
"block_contact_warning": "Are you sure you want to block this contact?",
|
"block_contact_warning": "Are you sure you want to block this contact?",
|
||||||
"blocked_contacts_link": "Blocked contacts ({count})",
|
"blocked_contacts_link": "Blocked contacts ({count})",
|
||||||
@@ -535,7 +542,11 @@
|
|||||||
"channel": "canal",
|
"channel": "canal",
|
||||||
"drafty_attachment": "Archivo",
|
"drafty_attachment": "Archivo",
|
||||||
"drafty_form": "Formulario:",
|
"drafty_form": "Formulario:",
|
||||||
"drafty_image": "Imagen"
|
"drafty_image": "Imagen",
|
||||||
|
"menu_item_restore_topic": "Restaurar",
|
||||||
|
"badge_danger": "Suspicaz",
|
||||||
|
"badge_staff": "Administración",
|
||||||
|
"badge_verified": "Verificado"
|
||||||
},
|
},
|
||||||
"ko": {
|
"ko": {
|
||||||
"validate_credential_action": "확인",
|
"validate_credential_action": "확인",
|
||||||
@@ -714,7 +725,10 @@
|
|||||||
"channel": "채널",
|
"channel": "채널",
|
||||||
"drafty_attachment": "부착",
|
"drafty_attachment": "부착",
|
||||||
"drafty_form": "형태:",
|
"drafty_form": "형태:",
|
||||||
"drafty_image": "이미지"
|
"drafty_image": "이미지",
|
||||||
|
"menu_item_restore_topic": "복원",
|
||||||
|
"badge_danger": "의심 많은",
|
||||||
|
"badge_staff": "직원 관리하에"
|
||||||
},
|
},
|
||||||
"ro": {
|
"ro": {
|
||||||
"validate_credential_action": "confirmă",
|
"validate_credential_action": "confirmă",
|
||||||
@@ -893,7 +907,11 @@
|
|||||||
"title_manage_tags": "Administrează",
|
"title_manage_tags": "Administrează",
|
||||||
"drafty_attachment": "Atasament",
|
"drafty_attachment": "Atasament",
|
||||||
"drafty_form": "Formă:",
|
"drafty_form": "Formă:",
|
||||||
"drafty_image": "Imagine"
|
"drafty_image": "Imagine",
|
||||||
|
"menu_item_restore_topic": "Restabili",
|
||||||
|
"badge_danger": "Suspicios",
|
||||||
|
"badge_staff": "Administrare",
|
||||||
|
"badge_verified": "Verificat"
|
||||||
},
|
},
|
||||||
"ru": {
|
"ru": {
|
||||||
"contacts_not_found": "Чатов нет<br />¯∖_(ツ)_/¯",
|
"contacts_not_found": "Чатов нет<br />¯∖_(ツ)_/¯",
|
||||||
@@ -1072,7 +1090,11 @@
|
|||||||
"channel": "канал",
|
"channel": "канал",
|
||||||
"drafty_attachment": "Аттачмент",
|
"drafty_attachment": "Аттачмент",
|
||||||
"drafty_form": "Форма:",
|
"drafty_form": "Форма:",
|
||||||
"drafty_image": "Картинка"
|
"drafty_image": "Картинка",
|
||||||
|
"menu_item_restore_topic": "Разархивировать",
|
||||||
|
"badge_danger": "Подозрительный",
|
||||||
|
"badge_staff": "Администрация",
|
||||||
|
"badge_verified": "Верифицированный"
|
||||||
},
|
},
|
||||||
"zh": {
|
"zh": {
|
||||||
"archived_contacts": "已归档联系人 ({count})",
|
"archived_contacts": "已归档联系人 ({count})",
|
||||||
@@ -1251,6 +1273,10 @@
|
|||||||
"channel": "频道",
|
"channel": "频道",
|
||||||
"drafty_attachment": "附件",
|
"drafty_attachment": "附件",
|
||||||
"drafty_form": "形式:",
|
"drafty_form": "形式:",
|
||||||
"drafty_image": "图像"
|
"drafty_image": "图像",
|
||||||
|
"menu_item_restore_topic": "从存档中恢复",
|
||||||
|
"badge_danger": "可疑的",
|
||||||
|
"badge_staff": "在员工管理下",
|
||||||
|
"badge_verified": "值得信赖"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import React from 'react';
|
|||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import AvatarUpload from '../widgets/avatar-upload.jsx';
|
import AvatarUpload from '../widgets/avatar-upload.jsx';
|
||||||
|
import BadgeList from '../widgets/badge-list.jsx';
|
||||||
|
|
||||||
import { makeImageDataUrl } from '../lib/blob-helpers.js';
|
import { makeImageDataUrl } from '../lib/blob-helpers.js';
|
||||||
|
|
||||||
@@ -32,6 +33,7 @@ export default class EditAccountView extends React.Component {
|
|||||||
description="Label for user address (ID)" /></label>
|
description="Label for user address (ID)" /></label>
|
||||||
<tt>{this.props.myUserId}</tt>
|
<tt>{this.props.myUserId}</tt>
|
||||||
</div>
|
</div>
|
||||||
|
<BadgeList trustedBadges={this.props.trustedBadges} />
|
||||||
</div>
|
</div>
|
||||||
<AvatarUpload
|
<AvatarUpload
|
||||||
avatar={this.state.avatar}
|
avatar={this.state.avatar}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
|||||||
import Tinode from 'tinode-sdk';
|
import Tinode from 'tinode-sdk';
|
||||||
|
|
||||||
import AvatarUpload from '../widgets/avatar-upload.jsx';
|
import AvatarUpload from '../widgets/avatar-upload.jsx';
|
||||||
|
import BadgeList from '../widgets/badge-list.jsx';
|
||||||
import CheckBox from '../widgets/checkbox.jsx';
|
import CheckBox from '../widgets/checkbox.jsx';
|
||||||
import ContactList from '../widgets/contact-list.jsx';
|
import ContactList from '../widgets/contact-list.jsx';
|
||||||
import ErrorPanel from '../widgets/error-panel.jsx';
|
import ErrorPanel from '../widgets/error-panel.jsx';
|
||||||
@@ -120,6 +121,7 @@ class InfoView extends React.Component {
|
|||||||
anon: null,
|
anon: null,
|
||||||
contactList: [],
|
contactList: [],
|
||||||
tags: [],
|
tags: [],
|
||||||
|
trustedBadges: [],
|
||||||
showMemberPanel: false,
|
showMemberPanel: false,
|
||||||
showPermissionEditorFor: undefined,
|
showPermissionEditorFor: undefined,
|
||||||
moreInfoExpanded: false,
|
moreInfoExpanded: false,
|
||||||
@@ -219,6 +221,14 @@ class InfoView extends React.Component {
|
|||||||
const defacs = topic.getDefaultAccess() || {};
|
const defacs = topic.getDefaultAccess() || {};
|
||||||
const acs = topic.getAccessMode();
|
const acs = topic.getAccessMode();
|
||||||
|
|
||||||
|
const badges = [];
|
||||||
|
if (topic.trusted) {
|
||||||
|
for (const [key, val] of Object.entries(topic.trusted)) {
|
||||||
|
if (val) {
|
||||||
|
badges.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
owner: acs && acs.isOwner(),
|
owner: acs && acs.isOwner(),
|
||||||
admin: acs && acs.isAdmin(),
|
admin: acs && acs.isAdmin(),
|
||||||
@@ -228,6 +238,7 @@ class InfoView extends React.Component {
|
|||||||
|
|
||||||
fullName: topic.public ? topic.public.fn : undefined,
|
fullName: topic.public ? topic.public.fn : undefined,
|
||||||
avatar: makeImageDataUrl(topic.public ? topic.public.photo : null),
|
avatar: makeImageDataUrl(topic.public ? topic.public.photo : null),
|
||||||
|
trustedBadges: badges,
|
||||||
private: topic.private ? topic.private.comment : null,
|
private: topic.private ? topic.private.comment : null,
|
||||||
address: topic.name,
|
address: topic.name,
|
||||||
groupTopic: topic.isGroupType(),
|
groupTopic: topic.isGroupType(),
|
||||||
@@ -586,6 +597,7 @@ class InfoView extends React.Component {
|
|||||||
onFinished={this.handlePrivateUpdate} />
|
onFinished={this.handlePrivateUpdate} />
|
||||||
}</FormattedMessage>
|
}</FormattedMessage>
|
||||||
</div>
|
</div>
|
||||||
|
<BadgeList trustedBadges={this.state.trustedBadges} />
|
||||||
</div>
|
</div>
|
||||||
<AvatarUpload
|
<AvatarUpload
|
||||||
avatar={this.state.avatar}
|
avatar={this.state.avatar}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import Tinode from 'tinode-sdk';
|
|||||||
const Drafty = Tinode.Drafty;
|
const Drafty = Tinode.Drafty;
|
||||||
|
|
||||||
import ChatMessage from '../widgets/chat-message.jsx';
|
import ChatMessage from '../widgets/chat-message.jsx';
|
||||||
|
import ContactBadges from '../widgets/contact-badges.jsx';
|
||||||
import DocPreview from '../widgets/doc-preview.jsx';
|
import DocPreview from '../widgets/doc-preview.jsx';
|
||||||
import ErrorPanel from '../widgets/error-panel.jsx';
|
import ErrorPanel from '../widgets/error-panel.jsx';
|
||||||
import GroupSubs from '../widgets/group-subs.jsx';
|
import GroupSubs from '../widgets/group-subs.jsx';
|
||||||
@@ -213,6 +214,9 @@ class MessagesView extends React.Component {
|
|||||||
topic: null,
|
topic: null,
|
||||||
title: '',
|
title: '',
|
||||||
avatar: null,
|
avatar: null,
|
||||||
|
isVerified: false,
|
||||||
|
isStaff: false,
|
||||||
|
isDangerous: false,
|
||||||
docPreview: null,
|
docPreview: null,
|
||||||
imagePreview: null,
|
imagePreview: null,
|
||||||
imagePostview: null,
|
imagePostview: null,
|
||||||
@@ -825,6 +829,18 @@ class MessagesView extends React.Component {
|
|||||||
const topic = this.props.tinode.getTopic(this.state.topic);
|
const topic = this.props.tinode.getTopic(this.state.topic);
|
||||||
const isChannel = topic.isChannelType();
|
const isChannel = topic.isChannelType();
|
||||||
const groupTopic = topic.isGroupType() && !isChannel;
|
const groupTopic = topic.isGroupType() && !isChannel;
|
||||||
|
const icon_badges = [];
|
||||||
|
if (topic.trusted) {
|
||||||
|
if (topic.trusted.verified) {
|
||||||
|
icon_badges.push({icon: 'verified', color: 'badge-inv'});
|
||||||
|
}
|
||||||
|
if (topic.trusted.staff) {
|
||||||
|
icon_badges.push({icon: 'staff', color: 'badge-inv'});
|
||||||
|
}
|
||||||
|
if (topic.trusted.danger) {
|
||||||
|
icon_badges.push({icon: 'dangerous', color: 'badge-inv'});
|
||||||
|
}
|
||||||
|
}
|
||||||
let messageNodes = [];
|
let messageNodes = [];
|
||||||
let previousFrom = null;
|
let previousFrom = null;
|
||||||
let chatBoxClass = null;
|
let chatBoxClass = null;
|
||||||
@@ -929,7 +945,7 @@ class MessagesView extends React.Component {
|
|||||||
this.state.title ||
|
this.state.title ||
|
||||||
<i><FormattedMessage id="unnamed_topic" defaultMessage="Unnamed"
|
<i><FormattedMessage id="unnamed_topic" defaultMessage="Unnamed"
|
||||||
description="Title shown when the topic has no name" /></i>
|
description="Title shown when the topic has no name" /></i>
|
||||||
}</div>
|
}<ContactBadges badges={icon_badges} /></div>
|
||||||
<div id="topic-last-seen">{lastSeen}</div>
|
<div id="topic-last-seen">{lastSeen}</div>
|
||||||
</div>
|
</div>
|
||||||
{groupTopic ?
|
{groupTopic ?
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ class SidepanelView extends React.Component {
|
|||||||
state={view}
|
state={view}
|
||||||
title={title}
|
title={title}
|
||||||
avatar={avatar}
|
avatar={avatar}
|
||||||
|
trustedBadges={this.props.trustedBadges}
|
||||||
myUserId={this.props.myUserId}
|
myUserId={this.props.myUserId}
|
||||||
onSignUp={this.props.onSignUp}
|
onSignUp={this.props.onSignUp}
|
||||||
onSettings={this.props.onSettings}
|
onSettings={this.props.onSettings}
|
||||||
@@ -162,6 +163,7 @@ class SidepanelView extends React.Component {
|
|||||||
<EditAccountView
|
<EditAccountView
|
||||||
tinode={this.props.tinode}
|
tinode={this.props.tinode}
|
||||||
myUserId={this.props.myUserId}
|
myUserId={this.props.myUserId}
|
||||||
|
trustedBadges={this.props.trustedBadges}
|
||||||
onBasicNavigate={this.props.onBasicNavigate} /> :
|
onBasicNavigate={this.props.onBasicNavigate} /> :
|
||||||
|
|
||||||
view === 'general' ?
|
view === 'general' ?
|
||||||
|
|||||||
@@ -172,6 +172,7 @@ class TinodeWeb extends React.Component {
|
|||||||
sidePanelSelected: 'login',
|
sidePanelSelected: 'login',
|
||||||
sidePanelTitle: null,
|
sidePanelTitle: null,
|
||||||
sidePanelAvatar: null,
|
sidePanelAvatar: null,
|
||||||
|
myTrustedBadges: [],
|
||||||
loadSpinnerVisible: false,
|
loadSpinnerVisible: false,
|
||||||
|
|
||||||
login: '',
|
login: '',
|
||||||
@@ -655,6 +656,17 @@ class TinodeWeb extends React.Component {
|
|||||||
sidePanelAvatar: makeImageDataUrl(desc.public.photo)
|
sidePanelAvatar: makeImageDataUrl(desc.public.photo)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (desc.trusted) {
|
||||||
|
const badges = [];
|
||||||
|
for (const [key, val] of Object.entries(desc.trusted)) {
|
||||||
|
if (val) {
|
||||||
|
badges.push(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
myTrustedBadges: badges,
|
||||||
|
});
|
||||||
|
}
|
||||||
if (desc.acs) {
|
if (desc.acs) {
|
||||||
this.setState({
|
this.setState({
|
||||||
incognitoMode: !desc.acs.isPresencer()
|
incognitoMode: !desc.acs.isPresencer()
|
||||||
@@ -1532,6 +1544,7 @@ class TinodeWeb extends React.Component {
|
|||||||
state={this.state.sidePanelSelected}
|
state={this.state.sidePanelSelected}
|
||||||
title={this.state.sidePanelTitle}
|
title={this.state.sidePanelTitle}
|
||||||
avatar={this.state.sidePanelAvatar}
|
avatar={this.state.sidePanelAvatar}
|
||||||
|
trustedBadges={this.state.myTrustedBadges}
|
||||||
login={this.state.login}
|
login={this.state.login}
|
||||||
persist={this.state.persist}
|
persist={this.state.persist}
|
||||||
myUserId={this.state.myUserId}
|
myUserId={this.state.myUserId}
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
|
||||||
|
const icon_mapping = {'staff': 'verified_user'};
|
||||||
|
|
||||||
|
const messages = defineMessages({
|
||||||
|
badge_verified: {
|
||||||
|
id: 'badge_verified',
|
||||||
|
defaultMessage: 'Verified/official',
|
||||||
|
description: 'Explanation of a verified account or topic badge'
|
||||||
|
},
|
||||||
|
badge_staff: {
|
||||||
|
id: 'badge_staff',
|
||||||
|
defaultMessage: 'Staff-managed',
|
||||||
|
description: 'Explanation of a staff-managed account or topic badge'
|
||||||
|
},
|
||||||
|
badge_danger: {
|
||||||
|
id: 'badge_danger',
|
||||||
|
defaultMessage: 'Untrustworthy',
|
||||||
|
description: 'Suspicious or untrustworthy account or topic badge'
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/* Trusted badges with labels: verified, staff, danger */
|
||||||
|
class BadgeList extends React.PureComponent {
|
||||||
|
render() {
|
||||||
|
const {formatMessage} = this.props.intl;
|
||||||
|
let badges = null;
|
||||||
|
if (this.props.trustedBadges && this.props.trustedBadges.length > 0) {
|
||||||
|
badges = [];
|
||||||
|
this.props.trustedBadges.map((b) => {
|
||||||
|
const comment = formatMessage(messages['badge_' + b]);
|
||||||
|
const style = 'material-icons ' + b + '-color';
|
||||||
|
badges.push(<div className="trusted-badge" key={b}><i className={style}>{icon_mapping[b] || b}</i> {comment}</div>);
|
||||||
|
});
|
||||||
|
return <>{badges}</>;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default injectIntl(BadgeList);
|
||||||
@@ -1,24 +1,23 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const icon_mapping = {'muted': 'notifications_off', 'banned': 'block',
|
const icon_mapping = {'muted': 'notifications_off', 'banned': 'block', 'staff': 'verified_user'};
|
||||||
'verified': 'verified', 'staff': 'verified_user', 'dangerous': 'dangerous'};
|
|
||||||
|
|
||||||
/* Contact's labels: [you], or icons [muted], [blocked] */
|
/* Contact's labels: [you], or icons [muted], [blocked] */
|
||||||
export default class ContactBadges extends React.PureComponent {
|
export default class ContactBadges extends React.PureComponent {
|
||||||
render() {
|
render() {
|
||||||
let badges = null;
|
let badges = null;
|
||||||
if (this.props.badges && this.props.badges.length > 0) {
|
if (this.props.badges && this.props.badges.length > 0) {
|
||||||
badges = [];
|
badges = [];
|
||||||
this.props.badges.map(function(b) {
|
this.props.badges.map((b) => {
|
||||||
if (b.icon) {
|
const color = (b.color ? ' ' + b.color : '');
|
||||||
badges.push(<i className="material-icons as-badge" key={b.key || b.icon}>{icon_mapping[b.icon] || b.icon}</i>);
|
if (b.icon) {
|
||||||
} else {
|
badges.push(<i className={'material-icons as-badge' + color} key={b.key || b.icon}>{icon_mapping[b.icon] || b.icon}</i>);
|
||||||
const style = 'badge' + (b.color ? ' ' + b.color : '');
|
} else {
|
||||||
badges.push(<span className={style} key={b.key || b.name}>{b.name}</span>);
|
badges.push(<span className={'badge' + color} key={b.key || b.name}>{b.name}</span>);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return <>{badges}</>;
|
return <>{badges}</>;
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -105,9 +105,9 @@ class ContactList extends React.Component {
|
|||||||
isChannel={isChannel}
|
isChannel={isChannel}
|
||||||
onSelected={this.props.onTopicSelected}
|
onSelected={this.props.onTopicSelected}
|
||||||
showContextMenu={this.props.showContextMenu}
|
showContextMenu={this.props.showContextMenu}
|
||||||
isVerified={c.isVerified()}
|
isVerified={c.trusted && c.trusted.verified}
|
||||||
isStaff={c.isStaff()}
|
isStaff={c.trusted && c.trusted.staff}
|
||||||
isDangerous={c.isDangerous()}
|
isDangerous={c.trusted && c.trusted.danger}
|
||||||
item={key}
|
item={key}
|
||||||
index={contactNodes.length}
|
index={contactNodes.length}
|
||||||
key={key} />
|
key={key} />
|
||||||
|
|||||||
@@ -66,13 +66,13 @@ class Contact extends React.Component {
|
|||||||
const badges = this.props.badges ? this.props.badges.slice() : [];
|
const badges = this.props.badges ? this.props.badges.slice() : [];
|
||||||
const icon_badges = [];
|
const icon_badges = [];
|
||||||
if (this.props.isVerified) {
|
if (this.props.isVerified) {
|
||||||
icon_badges.push({icon: 'verified'});
|
icon_badges.push({icon: 'verified', color: 'verified-color'});
|
||||||
}
|
}
|
||||||
if (this.props.isStaff) {
|
if (this.props.isStaff) {
|
||||||
icon_badges.push({icon: 'staff'});
|
icon_badges.push({icon: 'staff', color: 'staff-color'});
|
||||||
}
|
}
|
||||||
if (this.props.isDangerous) {
|
if (this.props.isDangerous) {
|
||||||
icon_badges.push({icon: 'dangerous'});
|
icon_badges.push({icon: 'dangerous', color: 'danger-color'});
|
||||||
}
|
}
|
||||||
if (this.props.acs) {
|
if (this.props.acs) {
|
||||||
if (this.props.showMode) {
|
if (this.props.showMode) {
|
||||||
|
|||||||
@@ -1,12 +1,18 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
|
||||||
import LetterTile from './letter-tile.jsx';
|
import LetterTile from './letter-tile.jsx';
|
||||||
import ButtonBack from './button-back.jsx';
|
import ButtonBack from './button-back.jsx';
|
||||||
|
import ContactBadges from './contact-badges.jsx';
|
||||||
import MenuContacts from './menu-contacts.jsx';
|
import MenuContacts from './menu-contacts.jsx';
|
||||||
import MenuStart from './menu-start.jsx';
|
import MenuStart from './menu-start.jsx';
|
||||||
|
|
||||||
export default class SideNavbar extends React.PureComponent {
|
export default class SideNavbar extends React.PureComponent {
|
||||||
render() {
|
render() {
|
||||||
|
const icon_badges = [];
|
||||||
|
this.props.trustedBadges.map((b) => {
|
||||||
|
icon_badges.push({icon: b, color: 'badge-inv'});
|
||||||
|
});
|
||||||
return (
|
return (
|
||||||
<div id="side-caption-panel" className="caption-panel">
|
<div id="side-caption-panel" className="caption-panel">
|
||||||
{this.props.onCancel ? <ButtonBack onBack={this.props.onCancel} /> : null}
|
{this.props.onCancel ? <ButtonBack onBack={this.props.onCancel} /> : null}
|
||||||
@@ -19,7 +25,7 @@ export default class SideNavbar extends React.PureComponent {
|
|||||||
</div>
|
</div>
|
||||||
:
|
:
|
||||||
null}
|
null}
|
||||||
<div id="sidepanel-title" className="panel-title">{this.props.title}</div>
|
<div id="sidepanel-title" className="panel-title">{this.props.title}<ContactBadges badges={icon_badges}/></div>
|
||||||
{this.props.state === 'login' ?
|
{this.props.state === 'login' ?
|
||||||
<MenuStart onSignUp={this.props.onSignUp} onSettings={this.props.onSettings} /> :
|
<MenuStart onSignUp={this.props.onSignUp} onSettings={this.props.onSettings} /> :
|
||||||
this.props.state === 'contacts' ?
|
this.props.state === 'contacts' ?
|
||||||
|
|||||||
+256
-98
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
+34
-4
File diff suppressed because one or more lines are too long
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user