修复全页面走查发现的 P0 前端问题(第一批)
八个 agent 对 11 章逐页对照设计稿+后端源码后,先修其中"功能不可用/崩溃/谎报成功"级别的:
崩溃与数据错误
- content-library-view: Highlight 按 [start,len] 数组解构后端返回的 {start,end} 对象,
对象不可迭代会直接抛 TypeError,任何文本搜索命中都让整个结果区渲染崩掉。服务端偏移还叠加
两个问题(Go 字节下标 vs JS UTF-16;偏移基准是全文但 snippet 会被开窗截断),改为在展示
文本上本地匹配关键词。
- content-library-view: firstAttachment 用 Drafty.attachments,SDK 里硬过滤 tp=='EX'
只认文件附件,图片(IM)/视频(VD)/语音(AU) 一个都取不到——收藏缩略图、语音播放源、聊天记录
图片视频宫格全部拿不到资源。改用 Drafty.entities 按类型分派(chat-message.jsx 已有先例)。
- message-center-view: 系统通知的机器码兜底会把真实数据吞掉(日报提醒的 summary 就是日期
字符串 "2026-08-20",会议通知的 summary 是标题),改为查表命中才替换。
- message-center-view: 会话列表漏了 avatar 字段,每行都只能落到兜底图标;同文件
frequentContacts() 本来就是对的,照它补上。
功能不可用
- auth-onboarding-view: 首次开启青少年模式是死路——设完密码丢弃了服务端返回的
enable_action_token,从不调 enableYouthMode,用户走完短信验证+设密码后模式仍是关的。
现在拿着这个 token 把最后一步做完。
- group-management-view: "投诉/举报"是个 onToast('暂未开放') 死桩,而 target_type='group'
这条链路早就通了。接上真实举报页。
- tinode-web: 刷新/深链会被弹回首页。两个原因叠加:初始化白名单还是上游 Tinode 的
['cred','reset','register'];handleLoginSuccessful 无条件把 hash 改写成 workbench,
刷新触发的自动登录也走这条。抽出 SIDE_PANEL_VIEWS 常量复用,并区分登录流程与自动登录。
- widgets/meta-message: deleted 分支从未实现,撤回一条消息后时间线上什么都不剩。
谎报成功 / 判定错误
- tinode-web + personal-settings-view: 改密码不返回 Promise,服务端拒绝时照样弹"密码已更新"。
- group-management-view: 禁言批量读 result.succeeded,但该接口返回的是 {topic, items},
succeeded 恒为 undefined,不管成没成都弹"设置成功"。两个接口结构不同,分开判定。
- workplace-collaboration-view: 会议取消状态写成 'cancelled',后端是 'canceled' 单 l,
会议取消后"取消会议"按钮还挂着。
样式与显示
- base.css: 删掉旧版 .organization-department 的 padding-left !important,它压过按层级算出的
内联缩进,导致部门行全平、只有人员行缩进。
- base.css: 补 .youth-password-gate(原来 0 条规则),PIN 框缺 position:relative 和居中。
- security-support-view: shield_lock 不在经典 Material Icons 里(只有 Symbols),会显示成
字面文本;.risk-info-page 也是 0 条规则,整页渲染成裸项目符号列表。改用 verified_user 并
补上 .risk-dialog。
- contact-management-view: 好友资料页性别直接输出后端枚举,显示成 "male"。
- workplace-collaboration-view: 层级标注两条路径两种格式(树形深三层变"3级"、搜索硬传"三"),
统一成一个 helper。
已记录不在前端修的后端缺口:recallMessage 的 version 只能传 1,因为所有消息读取接口
(messagePayload/messageSearchPayload/mediaMessagePayload/favoriteSnapshot)都不下发 version,
冲突错误里也不回传真实值,被编辑过的消息撤回必然失败。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
c4189646f4
commit
5a07bb4e3b
+97
-37
@@ -6638,11 +6638,26 @@ function IndependentPassword({
|
||||
}
|
||||
setBusy(true);
|
||||
try {
|
||||
await (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_2__.setIndependentPassword)(pin, 'youth_mode', actionToken);
|
||||
const result = await (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_2__.setIndependentPassword)(pin, 'youth_mode', actionToken);
|
||||
sessionStorage.removeItem('im-action-token:' + IDENTITY_CHECK_SCENE);
|
||||
setPin('');
|
||||
const enableToken = result && result.enable_action_token;
|
||||
if (enableToken) {
|
||||
try {
|
||||
const current = await (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_2__.getYouthMode)();
|
||||
await (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_2__.enableYouthMode)(current.policy_version, enableToken);
|
||||
setError('');
|
||||
setToast('青少年模式已开启');
|
||||
window.setTimeout(() => navigate('youth-mode-on'), 600);
|
||||
return;
|
||||
} catch (enableErr) {
|
||||
setError('独立密码已设置,但自动开启未成功:' + (enableErr.message || '请返回重试'));
|
||||
window.setTimeout(() => navigate('youth-mode-off'), 1200);
|
||||
return;
|
||||
}
|
||||
}
|
||||
setError('');
|
||||
setToast('独立密码设置成功');
|
||||
setPin('');
|
||||
} catch (err) {
|
||||
setError(err.message || '设置失败,请返回重新验证身份');
|
||||
} finally {
|
||||
@@ -7690,6 +7705,11 @@ function FriendRequests({
|
||||
}, void 0, true)]
|
||||
}, void 0, true);
|
||||
}
|
||||
const GENDER_LABELS = {
|
||||
male: '男',
|
||||
female: '女',
|
||||
other: '其他'
|
||||
};
|
||||
function seedProfile(item) {
|
||||
if (!item || !item.user_id) return;
|
||||
(0,_lib_use_cached_data_js__WEBPACK_IMPORTED_MODULE_5__.writeCachedData)('profile-seed:' + item.user_id, {
|
||||
@@ -8035,7 +8055,7 @@ function Profile({
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("dt", {
|
||||
children: "性别"
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("dd", {
|
||||
children: profile.gender
|
||||
children: GENDER_LABELS[profile.gender] || profile.gender
|
||||
}, void 0, false)]
|
||||
}, void 0, true) : null, (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("div", {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("dt", {
|
||||
@@ -8684,12 +8704,17 @@ function Search({
|
||||
function draftyContentOf(content) {
|
||||
return tinode_sdk__WEBPACK_IMPORTED_MODULE_1__.Drafty.isValid(content) ? content : null;
|
||||
}
|
||||
const MEDIA_ENTITY_TYPES = ['IM', 'VD', 'AU', 'EX'];
|
||||
function firstAttachment(content) {
|
||||
const drafty = draftyContentOf(content);
|
||||
if (!drafty) return null;
|
||||
let found = null;
|
||||
tinode_sdk__WEBPACK_IMPORTED_MODULE_1__.Drafty.attachments(drafty, att => {
|
||||
if (!found) found = att;
|
||||
tinode_sdk__WEBPACK_IMPORTED_MODULE_1__.Drafty.entities(drafty, (data, _index, tp) => {
|
||||
if (!found && data && MEDIA_ENTITY_TYPES.includes(tp)) {
|
||||
found = data;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
return found;
|
||||
}
|
||||
@@ -9306,18 +9331,23 @@ function DownloadPage({
|
||||
}
|
||||
function Highlight({
|
||||
text,
|
||||
ranges
|
||||
query
|
||||
}) {
|
||||
if (!ranges || !ranges.length) return text;
|
||||
const needle = (query || '').trim();
|
||||
if (!needle || !text) return text;
|
||||
const parts = [];
|
||||
const haystack = text.toLowerCase();
|
||||
const lowered = needle.toLowerCase();
|
||||
let last = 0;
|
||||
ranges.forEach(([start, len], i) => {
|
||||
parts.push(text.slice(last, start), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_8__.jsxDEV)("mark", {
|
||||
children: text.slice(start, start + len)
|
||||
}, i, false));
|
||||
last = start + len;
|
||||
});
|
||||
parts.push(text.slice(last));
|
||||
for (let at = haystack.indexOf(lowered); at !== -1; at = haystack.indexOf(lowered, at + lowered.length)) {
|
||||
if (at > last) parts.push(text.slice(last, at));
|
||||
parts.push((0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_8__.jsxDEV)("mark", {
|
||||
children: text.slice(at, at + needle.length)
|
||||
}, at, false));
|
||||
last = at + needle.length;
|
||||
}
|
||||
if (!parts.length) return text;
|
||||
if (last < text.length) parts.push(text.slice(last));
|
||||
return parts;
|
||||
}
|
||||
function HistoryNav({
|
||||
@@ -9468,7 +9498,7 @@ function History({
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_8__.jsxDEV)("p", {
|
||||
children: item.type === 'text' ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_8__.jsxDEV)(Highlight, {
|
||||
text: item.snippet || '',
|
||||
ranges: item.matches
|
||||
query: query
|
||||
}, void 0, false) : TYPE_LABEL[item.type] || item.snippet || ''
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_8__.jsxDEV)("small", {
|
||||
children: (0,_lib_strformat_js__WEBPACK_IMPORTED_MODULE_4__.shortDateFormat)(new Date(item.ts))
|
||||
@@ -11148,7 +11178,13 @@ function GroupSettings({
|
||||
}, void 0, false)]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("button", {
|
||||
type: "button",
|
||||
onClick: () => onToast('举报入口暂未开放'),
|
||||
onClick: () => {
|
||||
let hash = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_3__["default"].setUrlSidePanel('', 'abuse-report-reasons');
|
||||
hash = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_3__["default"].addUrlParam(hash, 'target_type', 'group');
|
||||
hash = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_3__["default"].addUrlParam(hash, 'target_id', topic);
|
||||
hash = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_3__["default"].addUrlParam(hash, 'target_name', group && group.name || topic);
|
||||
_lib_navigation_js__WEBPACK_IMPORTED_MODULE_3__["default"].navigateTo(hash);
|
||||
},
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("span", {
|
||||
children: "投诉/举报"
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)(Icon, {
|
||||
@@ -11696,8 +11732,14 @@ function MemberPicker({
|
||||
user_id
|
||||
}))) : (0,_lib_im_api_js__WEBPACK_IMPORTED_MODULE_4__.addGroupAdmins)(topic, selected);
|
||||
call.then(result => {
|
||||
const failed = result && result.succeeded ? result.succeeded.filter(s => !s.ok) : [];
|
||||
setToast(failed.length ? `成功设置 ${selected.length - failed.length} 人,${failed.length} 人设置失败` : '设置成功');
|
||||
let failedCount;
|
||||
if (mute) {
|
||||
const done = result && Array.isArray(result.items) ? result.items.length : selected.length;
|
||||
failedCount = Math.max(selected.length - done, 0);
|
||||
} else {
|
||||
failedCount = result && Array.isArray(result.succeeded) ? result.succeeded.filter(s => !s.ok).length : 0;
|
||||
}
|
||||
setToast(failedCount ? `成功设置 ${selected.length - failedCount} 人,${failedCount} 人设置失败` : '设置成功');
|
||||
window.setTimeout(() => navigate(back, topic), 900);
|
||||
}).catch(err => onToast(err.message || '设置失败')).finally(() => setBusy(false));
|
||||
};
|
||||
@@ -12176,11 +12218,11 @@ function GroupDescriptionEditor({
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("textarea", {
|
||||
autoFocus: true,
|
||||
value: value,
|
||||
maxLength: 225,
|
||||
maxLength: 200,
|
||||
placeholder: "请输入群简介内容",
|
||||
onChange: e => setValue(e.target.value)
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_6__.jsxDEV)("small", {
|
||||
children: [value.length, "/225"]
|
||||
children: [value.length, "/200"]
|
||||
}, void 0, true)]
|
||||
}, void 0, true)]
|
||||
}, void 0, true);
|
||||
@@ -12660,6 +12702,7 @@ function normalizeConversations(chatList, myUserId) {
|
||||
summary,
|
||||
time: formatConversationTime(item.touched),
|
||||
unread: Math.max(Number(item.unread) || 0, 0),
|
||||
avatar: (0,_lib_blob_helpers_js__WEBPACK_IMPORTED_MODULE_4__.makeImageUrl)(item.public && item.public.photo),
|
||||
icon: isGroup ? 'group' : 'person',
|
||||
online: isGroup ? undefined : !!item.online,
|
||||
muted: !!(item.acs && item.acs.isMuted && item.acs.isMuted()),
|
||||
@@ -12983,11 +13026,11 @@ const NOTIFICATION_TEXT = {
|
||||
accepted: '对方已通过你的好友申请',
|
||||
rejected: '对方拒绝了你的好友申请'
|
||||
};
|
||||
const MACHINE_CODE = /^[a-z0-9._-]+$/;
|
||||
function systemNotificationText(item) {
|
||||
const summary = (item.summary || '').trim();
|
||||
if (summary && !MACHINE_CODE.test(summary)) return summary;
|
||||
return NOTIFICATION_TEXT[summary] || NOTIFICATION_TEXT[item.event_type] || '您有一条新的系统通知。';
|
||||
const mapped = NOTIFICATION_TEXT[summary] || NOTIFICATION_TEXT[item.event_type];
|
||||
if (mapped) return mapped;
|
||||
return summary || '您有一条新的系统通知。';
|
||||
}
|
||||
function SystemMessages({
|
||||
authenticated
|
||||
@@ -15009,6 +15052,7 @@ function ChangePassword({
|
||||
const [oldPwd, setOldPwd] = react__WEBPACK_IMPORTED_MODULE_0___default().useState('');
|
||||
const [newPwd, setNewPwd] = react__WEBPACK_IMPORTED_MODULE_0___default().useState('');
|
||||
const [confirmPwd, setConfirmPwd] = react__WEBPACK_IMPORTED_MODULE_0___default().useState('');
|
||||
const [busy, setBusy] = react__WEBPACK_IMPORTED_MODULE_0___default().useState(false);
|
||||
const submit = () => {
|
||||
if (!oldPwd || newPwd.length < 6) {
|
||||
onToast('请输入原密码,新密码至少6位');
|
||||
@@ -15022,9 +15066,15 @@ function ChangePassword({
|
||||
onToast('当前环境不支持修改密码');
|
||||
return;
|
||||
}
|
||||
onUpdatePassword(newPwd);
|
||||
onToast('密码已更新');
|
||||
window.setTimeout(() => navigate('android-settings'), 500);
|
||||
if (busy) return;
|
||||
setBusy(true);
|
||||
Promise.resolve(onUpdatePassword(newPwd)).then(() => {
|
||||
onToast('密码已更新');
|
||||
window.setTimeout(() => navigate('android-settings'), 500);
|
||||
}).catch(err => {
|
||||
onToast(err && err.message || '修改失败,请重试');
|
||||
setBusy(false);
|
||||
});
|
||||
};
|
||||
return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("div", {
|
||||
className: "personal-page profile-editor-page",
|
||||
@@ -15717,11 +15767,11 @@ function FraudAwareness({
|
||||
title: "安全提醒",
|
||||
back: secondary ? 'fraud-risk-warning' : 'personal-center'
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("main", {
|
||||
className: "risk-info-page",
|
||||
className: "risk-info-page risk-dialog",
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("span", {
|
||||
className: "risk-symbol",
|
||||
children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)(Icon, {
|
||||
children: secondary ? 'warning_amber' : 'shield_lock'
|
||||
children: secondary ? 'warning_amber' : 'verified_user'
|
||||
}, void 0, false)
|
||||
}, void 0, false), secondary ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)(react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.Fragment, {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("p", {
|
||||
@@ -17035,6 +17085,8 @@ const messages = (0,react_intl__WEBPACK_IMPORTED_MODULE_1__.defineMessages)({
|
||||
description: 'Placeholder for the country selector'
|
||||
}
|
||||
});
|
||||
const SIDE_PANEL_VIEWS = ['acc_general', 'archive', 'blocked', 'contacts', 'cred', 'crop', 'edit', 'general', 'newtpk', 'notif', 'register', 'reset', 'security', 'settings', 'support', 'wallpapers', 'tenant', 'login', 'enterprise-register', 'enterprise-feedback', 'identity-check', 'realname', 'realname-verified', 'realname-reminder', 'independent-password', 'messages-home', 'messages-offline', 'messages-menu', 'message-actions', 'system-messages', 'chat-inbound-request', 'chat-inbound-message', 'chat-outbound-request', 'chat-status', 'chat-friend', 'chat-media', 'chat-blocked', 'chat-deleted', 'chat-standard', 'chat-attachments', 'chat-mixed', 'chat-contact-card', 'compose-keyboard', 'mentions-select', 'mentions-complete', 'mentions-message', 'emoji-panel', 'emoji-message', 'voice-ready', 'voice-hold', 'voice-recording', 'media-uploading', 'media-gallery', 'media-retry', 'upload-file', 'file-message', 'message-multiselect', 'favorite-success', 'forward-select', 'forward-multiple', 'forward-individual', 'forward-bundle', 'address-book', 'friend-requests', 'add-friend', 'my-friend-qr', 'friend-search-result', 'friend-verification', 'friend-profile', 'group-member-profile', 'friend-settings', 'friend-settings-blocked', 'friend-delete-confirm', 'block-list', 'block-confirm', 'clear-chat-confirm', 'group-list', 'group-empty', 'group-invite', 'group-events', 'group-join-requests', 'group-new-request', 'group-announcement', 'group-summary', 'group-announcement-detail', 'group-settings', 'group-profile', 'group-avatar', 'group-nickname', 'group-description', 'group-my-nickname', 'group-role-message', 'group-qr', 'group-governance', 'group-admins', 'group-admin-add', 'group-admin-success', 'group-admin-partial', 'group-admin-removed', 'group-mute-add', 'group-muted', 'group-owner-select', 'group-owner-confirm', 'group-files', 'group-file-upload', 'favorites', 'favorites-mixed', 'favorites-files', 'favorites-text', 'favorites-voice', 'favorites-links', 'favorites-select', 'favorite-share', 'file-download', 'file-downloading', 'file-downloaded', 'history-search', 'history-files', 'history-links', 'history-images', 'history-videos', 'call-history', 'call-incoming', 'audio-call-ringing', 'audio-call-active', 'audio-call-muted', 'audio-call-speaker', 'video-call-ringing', 'video-call-camera-off', 'video-call-active', 'video-call-peer-camera-off', 'call-minimized', 'workbench', 'organization-directory', 'meeting-organizer', 'meeting-attendee', 'meeting-create', 'meeting-detail', 'daily-report-editor', 'daily-report-mine', 'daily-report-team', 'daily-report-detail', 'monthly-report-editor', 'monthly-report-list', 'monthly-report-detail', 'executive-mailbox', 'executive-mailbox-notice', 'personal-center', 'personal-profile', 'profile-nickname', 'profile-birth-date', 'profile-signature', 'profile-gender', 'profile-region', 'personal-qrcode', 'android-settings', 'cache-clear-confirm', 'clear-history-confirm', 'change-password', 'delete-account-confirm', 'app-version', 'privacy-settings', 'friend-discovery-settings', 'youth-mode-off', 'youth-mode-on', 'youth-mode-verify', 'notification-permission', 'permission-settings-reminder', 'camera-permission-info', 'microphone-permission-info', 'fraud-risk-warning', 'fraud-risk-confirmation', 'abuse-report-reasons', 'abuse-report-details', 'user-feedback', ''];
|
||||
const AUTH_FLOW_VIEWS = ['tenant', 'login', 'register', 'reset', 'cred', 'enterprise-register', 'enterprise-feedback'];
|
||||
class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component) {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
@@ -17283,7 +17335,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
});
|
||||
}
|
||||
const parsedNav = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].parseUrlHash(window.location.hash);
|
||||
if (!['cred', 'reset', 'register'].includes(parsedNav.path[0])) {
|
||||
if (!SIDE_PANEL_VIEWS.includes(parsedNav.path[0]) || !parsedNav.path[0]) {
|
||||
this.setState({
|
||||
requestedTopic: parsedNav.path[1]
|
||||
});
|
||||
@@ -17494,7 +17546,7 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
newTopicTabSelected: hash.params.tab
|
||||
};
|
||||
if (hash.path && hash.path.length > 0) {
|
||||
if (['acc_general', 'archive', 'blocked', 'contacts', 'cred', 'crop', 'edit', 'general', 'newtpk', 'notif', 'register', 'reset', 'security', 'settings', 'support', 'wallpapers', 'tenant', 'login', 'enterprise-register', 'enterprise-feedback', 'identity-check', 'realname', 'realname-verified', 'realname-reminder', 'independent-password', 'messages-home', 'messages-offline', 'messages-menu', 'message-actions', 'system-messages', 'chat-inbound-request', 'chat-inbound-message', 'chat-outbound-request', 'chat-status', 'chat-friend', 'chat-media', 'chat-blocked', 'chat-deleted', 'chat-standard', 'chat-attachments', 'chat-mixed', 'chat-contact-card', 'compose-keyboard', 'mentions-select', 'mentions-complete', 'mentions-message', 'emoji-panel', 'emoji-message', 'voice-ready', 'voice-hold', 'voice-recording', 'media-uploading', 'media-gallery', 'media-retry', 'upload-file', 'file-message', 'message-multiselect', 'favorite-success', 'forward-select', 'forward-multiple', 'forward-individual', 'forward-bundle', 'address-book', 'friend-requests', 'add-friend', 'my-friend-qr', 'friend-search-result', 'friend-verification', 'friend-profile', 'group-member-profile', 'friend-settings', 'friend-settings-blocked', 'friend-delete-confirm', 'block-list', 'block-confirm', 'clear-chat-confirm', 'group-list', 'group-empty', 'group-invite', 'group-events', 'group-join-requests', 'group-new-request', 'group-announcement', 'group-summary', 'group-announcement-detail', 'group-settings', 'group-profile', 'group-avatar', 'group-nickname', 'group-description', 'group-my-nickname', 'group-role-message', 'group-qr', 'group-governance', 'group-admins', 'group-admin-add', 'group-admin-success', 'group-admin-partial', 'group-admin-removed', 'group-mute-add', 'group-muted', 'group-owner-select', 'group-owner-confirm', 'group-files', 'group-file-upload', 'favorites', 'favorites-mixed', 'favorites-files', 'favorites-text', 'favorites-voice', 'favorites-links', 'favorites-select', 'favorite-share', 'file-download', 'file-downloading', 'file-downloaded', 'history-search', 'history-files', 'history-links', 'history-images', 'history-videos', 'call-history', 'call-incoming', 'audio-call-ringing', 'audio-call-active', 'audio-call-muted', 'audio-call-speaker', 'video-call-ringing', 'video-call-camera-off', 'video-call-active', 'video-call-peer-camera-off', 'call-minimized', 'workbench', 'organization-directory', 'meeting-organizer', 'meeting-attendee', 'meeting-create', 'meeting-detail', 'daily-report-editor', 'daily-report-mine', 'daily-report-team', 'daily-report-detail', 'monthly-report-editor', 'monthly-report-list', 'monthly-report-detail', 'executive-mailbox', 'executive-mailbox-notice', 'personal-center', 'personal-profile', 'profile-nickname', 'profile-birth-date', 'profile-signature', 'profile-gender', 'profile-region', 'personal-qrcode', 'android-settings', 'cache-clear-confirm', 'clear-history-confirm', 'change-password', 'delete-account-confirm', 'app-version', 'privacy-settings', 'friend-discovery-settings', 'youth-mode-off', 'youth-mode-on', 'youth-mode-verify', 'notification-permission', 'permission-settings-reminder', 'camera-permission-info', 'microphone-permission-info', 'fraud-risk-warning', 'fraud-risk-confirmation', 'abuse-report-reasons', 'abuse-report-details', 'user-feedback', ''].includes(hash.path[0])) {
|
||||
if (SIDE_PANEL_VIEWS.includes(hash.path[0])) {
|
||||
newState.sidePanelSelected = hash.path[0];
|
||||
newState.sidePanelParams = hash.params;
|
||||
} else {
|
||||
@@ -17766,7 +17818,9 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
loadSpinnerVisible: false
|
||||
});
|
||||
});
|
||||
let urlHash = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].setUrlSidePanel(window.location.hash, 'workbench');
|
||||
const currentView = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].parseUrlHash(window.location.hash).path[0];
|
||||
const cameFromAuthFlow = !currentView || AUTH_FLOW_VIEWS.includes(currentView) || !SIDE_PANEL_VIEWS.includes(currentView);
|
||||
let urlHash = cameFromAuthFlow ? _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].setUrlSidePanel(window.location.hash, 'workbench') : window.location.hash;
|
||||
if (goToTopic) {
|
||||
urlHash = _lib_navigation_js__WEBPACK_IMPORTED_MODULE_20__["default"].setUrlTopic(urlHash, goToTopic);
|
||||
}
|
||||
@@ -18413,9 +18467,13 @@ class TinodeWeb extends (react__WEBPACK_IMPORTED_MODULE_0___default().Component)
|
||||
}
|
||||
handleUpdatePasswordRequest(password) {
|
||||
this.handleError();
|
||||
if (password) {
|
||||
this.tinode.updateAccountBasic(null, this.tinode.getCurrentLogin(), password).catch(err => this.handleError(err.message, 'err'));
|
||||
if (!password) {
|
||||
return Promise.reject(new Error('密码不能为空'));
|
||||
}
|
||||
return this.tinode.updateAccountBasic(null, this.tinode.getCurrentLogin(), password).catch(err => {
|
||||
this.handleError(err.message, 'err');
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
handleChangePermissions(topicName, mode, uid) {
|
||||
const topic = this.tinode.getTopic(topicName);
|
||||
@@ -19855,6 +19913,8 @@ function ImgFromFile({
|
||||
className: className
|
||||
}, void 0, false);
|
||||
}
|
||||
const LEVEL_NUMERALS = ['一', '二', '三', '四', '五', '六', '七', '八', '九', '十'];
|
||||
const levelLabel = n => LEVEL_NUMERALS[n - 1] || String(n);
|
||||
function DeptRow({
|
||||
dept,
|
||||
depth,
|
||||
@@ -19873,7 +19933,7 @@ function DeptRow({
|
||||
children: icon
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("span", {
|
||||
children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("strong", {
|
||||
children: [dept.name, typeof dept.member_count === 'number' ? `${dept.member_count}人` : '', "(", depth === 0 ? '一级' : depth === 1 ? '二级' : `${depth + 1}级`, ")"]
|
||||
children: [dept.name, typeof dept.member_count === 'number' ? `${dept.member_count}人` : '', "(", levelLabel(depth + 1), "级)"]
|
||||
}, void 0, true)
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)(Icon, {
|
||||
children: expanded ? 'expand_more' : 'chevron_right'
|
||||
@@ -19916,7 +19976,7 @@ function PersonRow({
|
||||
children: "radio_button_unchecked"
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("span", {
|
||||
children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("strong", {
|
||||
children: [person.display_name, "(", level, "级)"]
|
||||
children: [person.display_name, "(", levelLabel(level), "级)"]
|
||||
}, void 0, true)
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)(Icon, {
|
||||
children: "chevron_right"
|
||||
@@ -20280,7 +20340,7 @@ function MeetingDetail({
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)(Icon, {
|
||||
children: "notifications"
|
||||
}, void 0, false), "提醒未响应"]
|
||||
}, void 0, true) : null, meeting.permissions && meeting.permissions.can_cancel && meeting.state !== 'cancelled' ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("button", {
|
||||
}, void 0, true) : null, meeting.permissions && meeting.permissions.can_cancel && meeting.state !== 'canceled' ? (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("button", {
|
||||
type: "button",
|
||||
className: "danger",
|
||||
disabled: busy,
|
||||
@@ -20511,7 +20571,7 @@ function OrganizationDirectory({
|
||||
}, 'd' + (item.department && item.department.department_id || idx), false) : (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)(PersonRow, {
|
||||
person: item.user,
|
||||
depth: 0,
|
||||
level: "三",
|
||||
level: 3,
|
||||
isMe: item.user && (item.user.user_id === myUserId || 'usr' + item.user.user_id === myUserId)
|
||||
}, 'u' + (item.user && item.user.user_id || idx), false))
|
||||
}, void 0, false) : (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_5__.jsxDEV)("section", {
|
||||
|
||||
Reference in New Issue
Block a user