修复用户实测反馈的4处问题:品牌名泄露、修改密码页注释泄露、安全提醒页未居中、群相关行间距
- 品牌名:BASE_APP_NAME 从 "TinodeWeb" 改为 "MeetingIM"(关于页/青少年模式文案不再暴露 Tinode 字样);
logo-view.jsx(未选中会话时的空状态)去掉开源模板遗留的 Tinode 主页/GitHub 链接/原始版本号,
换成品牌图标+"选择一个会话开始聊天"
- personal-settings-view.jsx:删除 ChangePassword 页面里被误当正文渲染的开发注释(提及 Tinode 协议),
改回真正的代码注释
- base.css:.risk-info-page(安全提醒整页)补 margin:0 auto——原来复用模态弹窗的 .risk-dialog 样式,
宽屏下整块内容贴左显示,没有居中
- base.css:.group-member-picker/.group-settings-header/.group-member-section-title 的 strong/small
漏加入既有的 line-height:1.3 覆盖名单,继承通用 button{line-height:2.2rem},导致群成员列表/群聊设置
头部的姓名与角色/简介文字行间距异常大、贴底部分割线过近
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
bede45fd7f
commit
f2218a822e
+42
-12
@@ -3955,12 +3955,29 @@ img.channel {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: var(--clr-cyan-50);
|
||||
}
|
||||
#dummy-view a {
|
||||
text-decoration: none;
|
||||
display: block;
|
||||
text-align: center;
|
||||
}
|
||||
#dummy-view-icon {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 6.5rem;
|
||||
height: 6.5rem;
|
||||
margin: 0 auto 0.8rem;
|
||||
border-radius: 1.2rem;
|
||||
color: #fff;
|
||||
background: #2878d6;
|
||||
}
|
||||
#dummy-view-icon .material-icons {
|
||||
font-size: 4.2rem;
|
||||
}
|
||||
#dummy-view h2 {
|
||||
margin: 0;
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
#dummy-view p {
|
||||
margin: 0.25rem 0 0;
|
||||
color: #777f89;
|
||||
}
|
||||
|
||||
#image-preview {
|
||||
position: absolute;
|
||||
@@ -9164,7 +9181,8 @@ div.toast.show {
|
||||
.group-list strong,
|
||||
.group-request-list strong,
|
||||
.group-admin-page strong,
|
||||
.group-muted-list strong {
|
||||
.group-muted-list strong,
|
||||
.group-member-picker strong {
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
@@ -9176,7 +9194,8 @@ div.toast.show {
|
||||
.group-list small,
|
||||
.group-request-list small,
|
||||
.group-admin-page small,
|
||||
.group-muted-list small {
|
||||
.group-muted-list small,
|
||||
.group-member-picker small {
|
||||
margin-top: 0.2rem;
|
||||
color: #9299a2;
|
||||
font-size: 0.75rem;
|
||||
@@ -9882,7 +9901,11 @@ div.toast.show {
|
||||
自己的 place-items:center 就只剩交叉轴(水平)生效,主轴(垂直)退回 flex-start,
|
||||
里面的图标会贴着方块顶部而不是居中。 */
|
||||
.group-settings-header > span:not(.group-avatar) { display: flex; flex-direction: column; gap: 0.15rem; min-width: 0; }
|
||||
.group-settings-header small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #9299a2; }
|
||||
/* Same generic `button { line-height: 2.2rem }` leak as .group-member-picker's rows (see its
|
||||
comment) -- name and description each sat in a ~29px box instead of hugging their own text,
|
||||
reading as far more gap between the two lines than the .15rem `gap` above actually specifies. */
|
||||
.group-settings-header strong { line-height: 1.3; }
|
||||
.group-settings-header small { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: #9299a2; line-height: 1.3; }
|
||||
|
||||
.group-list > button {
|
||||
display: grid;
|
||||
@@ -10223,11 +10246,13 @@ div.toast.show {
|
||||
.group-member-section-title > strong {
|
||||
color: #30353c;
|
||||
font-size: 1rem;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.group-member-section-title > small {
|
||||
margin-left: auto;
|
||||
color: #949ba4;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.group-settings section > .group-member-grid {
|
||||
@@ -10540,11 +10565,6 @@ div.toast.show {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.group-member-picker small {
|
||||
margin-top: 0.2rem;
|
||||
color: #9299a2;
|
||||
}
|
||||
|
||||
.group-check {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
@@ -13808,6 +13828,16 @@ div.toast.show {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* .risk-dialog was designed as a modal card, centered by .risk-overlay's place-items:center wrapper
|
||||
(RiskConfirmDialog). FraudAwareness reuses the same class directly as .support-page's <main> (no
|
||||
overlay wrapper, no explicit height on the page unlike a modal) to pick up its ul/li/aside/button
|
||||
styling -- but .support-page is a plain flex column with no centering of its own, so the capped
|
||||
width left the whole page pinned to the left edge on anything wider than ~25rem instead of centered
|
||||
like every other support-page/group-page/people-page in the app. */
|
||||
.risk-info-page {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.risk-symbol {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+3
-2
@@ -1,7 +1,8 @@
|
||||
import { PACKAGE_VERSION } from './version.js';
|
||||
|
||||
// Version-independent name of this application, used for Firebase app name.
|
||||
export const BASE_APP_NAME = 'TinodeWeb';
|
||||
// Version-independent name of this application, used for Firebase app name and shown to users
|
||||
// (about page, youth-mode copy).
|
||||
export const BASE_APP_NAME = 'MeetingIM';
|
||||
// Name of this application, used in the User-Agent.
|
||||
export const APP_NAME = BASE_APP_NAME + '/' + (PACKAGE_VERSION || '0.25');
|
||||
|
||||
|
||||
+6
-13
@@ -1,25 +1,18 @@
|
||||
/* This is just a static page to display when no conversation is selected. */
|
||||
/* Static placeholder shown in the message pane when no conversation is selected. */
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Tinode } from 'tinode-sdk';
|
||||
import { BASE_APP_NAME } from '../config.js';
|
||||
|
||||
import { APP_NAME } from '../config.js';
|
||||
function Icon({children}) { return <i className="material-icons" aria-hidden="true">{children}</i>; }
|
||||
|
||||
export default class LogoView extends React.PureComponent {
|
||||
render() {
|
||||
const version = APP_NAME + ' (' + Tinode.getLibrary() + ')';
|
||||
return (
|
||||
<div id="dummy-view">
|
||||
<div>
|
||||
<a href="https://github.com/tinode/chat/">
|
||||
<img id="logo" alt="logo" src="img/logo.svg" />
|
||||
<h2>Tinode Web</h2>
|
||||
</a>
|
||||
<p><FormattedMessage id="label_client" defaultMessage="Client:"
|
||||
description="Label for a client version" /> {version}</p>
|
||||
<p><FormattedMessage id="label_server" defaultMessage="Server:"
|
||||
description="Label for a server version" /> {this.props.serverVersion} ({this.props.serverAddress})</p>
|
||||
<span id="dummy-view-icon"><Icon>forum</Icon></span>
|
||||
<h2>{BASE_APP_NAME}</h2>
|
||||
<p>选择一个会话开始聊天</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -2127,9 +2127,7 @@ class MessagesView extends React.Component {
|
||||
|
||||
let component;
|
||||
if (!this.state.topic) {
|
||||
component = <LogoView
|
||||
serverVersion={this.props.serverVersion}
|
||||
serverAddress={this.props.serverAddress} />;
|
||||
component = <LogoView />;
|
||||
|
||||
} else {
|
||||
let component2;
|
||||
|
||||
@@ -395,6 +395,8 @@ function ClearHistoryConfirm({tinode, chatList, onToast}) {
|
||||
// (Tinode.updateAccountBasic), already wired end-to-end via tinode-web.jsx's
|
||||
// handleUpdatePasswordRequest/onUpdatePassword prop (used today by the old acc-security-view.jsx).
|
||||
// Reusing that verified callback here instead of reimplementing the WS call.
|
||||
// The server-side account-update call never checks the caller's current password -- "原密码" below
|
||||
// is a frontend-only speed bump against fat-fingering this field, not a real credential check.
|
||||
function ChangePassword({onUpdatePassword, onToast}) {
|
||||
const [oldPwd, setOldPwd] = React.useState('');
|
||||
const [newPwd, setNewPwd] = React.useState('');
|
||||
@@ -421,7 +423,6 @@ function ChangePassword({onUpdatePassword, onToast}) {
|
||||
<label><span>原密码</span><input type="password" value={oldPwd} onChange={e => setOldPwd(e.target.value)} placeholder="请输入当前密码" /></label>
|
||||
<label><span>新密码</span><input type="password" value={newPwd} onChange={e => setNewPwd(e.target.value)} placeholder="至少6位" /></label>
|
||||
<label><span>确认新密码</span><input type="password" value={confirmPwd} onChange={e => setConfirmPwd(e.target.value)} placeholder="再次输入新密码" /></label>
|
||||
<p>Tinode 协议本身不会在服务端校验"原密码",这里的原密码输入是前端自己加的一道二次确认,防止误触。</p>
|
||||
</main></div>;
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -2358,7 +2358,7 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var _version_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./version.js */ "./src/version.js");
|
||||
|
||||
const BASE_APP_NAME = 'TinodeWeb';
|
||||
const BASE_APP_NAME = 'MeetingIM';
|
||||
const APP_NAME = BASE_APP_NAME + '/' + (_version_js__WEBPACK_IMPORTED_MODULE_0__.PACKAGE_VERSION || '0.25');
|
||||
const API_KEY = "AQAAAAABAAAoeOI7tA3HsYvdzDhYhZJy" || 0;
|
||||
const KNOWN_HOSTS = {
|
||||
@@ -15741,9 +15741,7 @@ function ChangePassword({
|
||||
onChange: e => setConfirmPwd(e.target.value),
|
||||
placeholder: "再次输入新密码"
|
||||
}, void 0, false)]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_7__.jsxDEV)("p", {
|
||||
children: "Tinode 协议本身不会在服务端校验\"原密码\",这里的原密码输入是前端自己加的一道二次确认,防止误触。"
|
||||
}, void 0, false)]
|
||||
}, void 0, true)]
|
||||
}, void 0, true)]
|
||||
}, void 0, true);
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -13,45 +13,35 @@ __webpack_require__.r(__webpack_exports__);
|
||||
/* harmony export */ });
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "react");
|
||||
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
|
||||
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react-intl */ "react-intl");
|
||||
/* harmony import */ var react_intl__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react_intl__WEBPACK_IMPORTED_MODULE_1__);
|
||||
/* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! tinode-sdk */ "tinode-sdk");
|
||||
/* harmony import */ var tinode_sdk__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(tinode_sdk__WEBPACK_IMPORTED_MODULE_2__);
|
||||
/* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../config.js */ "./src/config.js");
|
||||
/* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js");
|
||||
|
||||
|
||||
/* harmony import */ var _config_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../config.js */ "./src/config.js");
|
||||
/* harmony import */ var react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react/jsx-dev-runtime */ "./node_modules/react/jsx-dev-runtime.js");
|
||||
|
||||
|
||||
|
||||
function Icon({
|
||||
children
|
||||
}) {
|
||||
return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("i", {
|
||||
className: "material-icons",
|
||||
"aria-hidden": "true",
|
||||
children: children
|
||||
}, void 0, false);
|
||||
}
|
||||
class LogoView extends (react__WEBPACK_IMPORTED_MODULE_0___default().PureComponent) {
|
||||
render() {
|
||||
const version = _config_js__WEBPACK_IMPORTED_MODULE_3__.APP_NAME + ' (' + tinode_sdk__WEBPACK_IMPORTED_MODULE_2__.Tinode.getLibrary() + ')';
|
||||
return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("div", {
|
||||
return (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("div", {
|
||||
id: "dummy-view",
|
||||
children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("div", {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("a", {
|
||||
href: "https://github.com/tinode/chat/",
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("img", {
|
||||
id: "logo",
|
||||
alt: "logo",
|
||||
src: "img/logo.svg"
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("h2", {
|
||||
children: "Tinode Web"
|
||||
}, void 0, false)]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("p", {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, {
|
||||
id: "label_client",
|
||||
defaultMessage: "Client:",
|
||||
description: "Label for a client version"
|
||||
}, void 0, false), " ", version]
|
||||
}, void 0, true), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)("p", {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_4__.jsxDEV)(react_intl__WEBPACK_IMPORTED_MODULE_1__.FormattedMessage, {
|
||||
id: "label_server",
|
||||
defaultMessage: "Server:",
|
||||
description: "Label for a server version"
|
||||
}, void 0, false), " ", this.props.serverVersion, " (", this.props.serverAddress, ")"]
|
||||
}, void 0, true)]
|
||||
children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("div", {
|
||||
children: [(0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("span", {
|
||||
id: "dummy-view-icon",
|
||||
children: (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)(Icon, {
|
||||
children: "forum"
|
||||
}, void 0, false)
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("h2", {
|
||||
children: _config_js__WEBPACK_IMPORTED_MODULE_1__.BASE_APP_NAME
|
||||
}, void 0, false), (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_2__.jsxDEV)("p", {
|
||||
children: "选择一个会话开始聊天"
|
||||
}, void 0, false)]
|
||||
}, void 0, true)
|
||||
}, void 0, false);
|
||||
}
|
||||
@@ -1841,10 +1831,7 @@ class MessagesView extends (react__WEBPACK_IMPORTED_MODULE_0___default().Compone
|
||||
}, void 0, false);
|
||||
let component;
|
||||
if (!this.state.topic) {
|
||||
component = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_logo_view_jsx__WEBPACK_IMPORTED_MODULE_10__["default"], {
|
||||
serverVersion: this.props.serverVersion,
|
||||
serverAddress: this.props.serverAddress
|
||||
}, void 0, false);
|
||||
component = (0,react_jsx_dev_runtime__WEBPACK_IMPORTED_MODULE_22__.jsxDEV)(_logo_view_jsx__WEBPACK_IMPORTED_MODULE_10__["default"], {}, void 0, false);
|
||||
} else {
|
||||
let component2;
|
||||
if (this.state.imagePreview) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user